Skip to content

Commit 224702b

Browse files
TagBox: fix tag rendering when valueExpr is a function (T1234032) (#28825)
1 parent bb10f63 commit 224702b

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

packages/devextreme/js/__internal/ui/m_tag_box.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ const TagBox = (SelectBox as any).inherit({
978978

979979
_getSelectedItemsFromList(values) {
980980
const listSelectedItems = this._list?.option('selectedItems');
981+
981982
let selectedItems = [];
982983
if (values.length === listSelectedItems?.length) {
983984
selectedItems = this._filterSelectedItems(listSelectedItems, values);

packages/devextreme/js/core/utils/selection_filter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getKeyHash, equalByValue } from './common';
2-
import { isString, isObject } from './type';
2+
import { isFunction, isString, isObject } from './type';
33
import { compileGetter } from './data';
44

55
export const SelectionFilterCreator = function(selectedItemKeys, isSelectAll) {
@@ -25,7 +25,7 @@ export const SelectionFilterCreator = function(selectedItemKeys, isSelectAll) {
2525
filterExpr.push(isSelectAll ? 'and' : 'or');
2626
}
2727

28-
if(isString(keyExpr)) {
28+
if(isString(keyExpr) || isFunction(keyExpr)) {
2929
filterExprPart = getFilterForPlainKey(keyExpr, key);
3030
} else {
3131
filterExprPart = getFilterForCompositeKey(keyExpr, key);

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/tagBox.tests.js

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6659,6 +6659,94 @@ QUnit.module('dataSource integration', moduleSetup, () => {
66596659
assert.ok(true, 'TagBox rendered');
66606660
});
66616661

6662+
QUnit.test('Tagbox should render tag correctly when hideSelectedItems = true and valueExpr is a function (T1234032)', function(assert) {
6663+
const data = [
6664+
{ id: 1, scheme: 'schema1', name: 'name1' },
6665+
{ id: 2, scheme: 'schema1', name: 'name2' }
6666+
];
6667+
const $tagBox = $('#tagBox').dxTagBox({
6668+
dataSource: data,
6669+
valueExpr(x) {
6670+
return x && x.name + ' ' + x.scheme;
6671+
},
6672+
displayExpr: 'name',
6673+
hideSelectedItems: true,
6674+
opened: true
6675+
});
6676+
const instance = $tagBox.dxTagBox('instance');
6677+
const $listItem = getListItems($tagBox);
6678+
$listItem.trigger('dxclick');
6679+
6680+
const $tags = instance.$element().find(`.${TAGBOX_TAG_CLASS}`);
6681+
assert.strictEqual($tags.length, 1, 'One tag is rendered after click');
6682+
assert.strictEqual($tags.eq(0).text().trim(), 'name1', 'Correct tag text is rendered');
6683+
assert.strictEqual(instance.option('value')[0], 'name1 schema1', 'Correct value is stored');
6684+
6685+
const $secondItem = getListItems($tagBox);
6686+
$secondItem.trigger('dxclick');
6687+
6688+
const $updatedTags = instance.$element().find(`.${TAGBOX_TAG_CLASS}`);
6689+
assert.strictEqual($updatedTags.length, 2, 'Two tags are rendered after selecting the second item');
6690+
assert.strictEqual($updatedTags.eq(1).text().trim(), 'name2', 'Second tag is rendered correctly');
6691+
assert.strictEqual(instance.option('value')[1], 'name2 schema1', 'Correct value is stored');
6692+
});
6693+
6694+
QUnit.test('TagBox should render initial tags correctly even if items are not loaded yet and valueExpr is a function', function(assert) {
6695+
const data = [
6696+
{ name: 'name1', scheme: 'schema1', value: 1 },
6697+
{ name: 'name2', scheme: 'schema2', value: 2 },
6698+
];
6699+
6700+
const dataSource = new DataSource({
6701+
store: new ArrayStore(data),
6702+
paginate: true,
6703+
pageSize: 1,
6704+
});
6705+
6706+
const $tagBox = $('#tagBox').dxTagBox({
6707+
dataSource,
6708+
displayExpr: 'name',
6709+
hideSelectedItems: true,
6710+
valueExpr(x) {
6711+
return x && `${x.name} ${x.scheme}`;
6712+
},
6713+
value: ['name1 schema1', 'name2 schema2'],
6714+
opened: true
6715+
});
6716+
6717+
const instance = $tagBox.dxTagBox('instance');
6718+
const $tags = instance.$element().find(`.${TAGBOX_TAG_CLASS}`);
6719+
6720+
assert.strictEqual($tags.length, 2, 'Two tag is rendered after init');
6721+
assert.strictEqual($tags.eq(0).text().trim(), 'name1', 'Correct first tag text is rendered');
6722+
assert.strictEqual($tags.eq(1).text().trim(), 'name2', 'Correct second tag text is rendered');
6723+
assert.strictEqual(instance.option('value')[0], 'name1 schema1', 'Correct first value is stored');
6724+
assert.strictEqual(instance.option('value')[1], 'name2 schema2', 'Correct second value is stored');
6725+
});
6726+
6727+
QUnit.test('Tagbox should render initial value correctly with function valueExpr', function(assert) {
6728+
const data = [
6729+
{ id: 1, scheme: 'schema1', name: 'name1' },
6730+
{ id: 2, scheme: 'schema1', name: 'name2' }
6731+
];
6732+
6733+
const instance = $('#tagBox').dxTagBox({
6734+
dataSource: data,
6735+
valueExpr(x) {
6736+
return x && `${x.name} ${x.scheme}`;
6737+
},
6738+
displayExpr: 'name',
6739+
hideSelectedItems: true,
6740+
value: ['name1 schema1'],
6741+
opened: true
6742+
}).dxTagBox('instance');
6743+
6744+
const $tags = instance.$element().find(`.${TAGBOX_TAG_CLASS}`);
6745+
assert.strictEqual($tags.length, 1, 'One tag is rendered initially');
6746+
assert.strictEqual($tags.eq(0).text().trim(), 'name1', 'Correct tag text is rendered');
6747+
assert.strictEqual(instance.option('value')[0], 'name1 schema1', 'Initial value is correct');
6748+
});
6749+
66626750
QUnit.test('TagBox should correctly handle disposing on data loading', function(assert) {
66636751
assert.expect(1);
66646752

@@ -6817,9 +6905,8 @@ QUnit.module('performance', () => {
68176905
const $item = $(getList(tagBox).find('.dx-list-item').eq(0));
68186906

68196907
$item.trigger('dxclick');
6820-
68216908
const filter = load.lastCall.args[0].filter;
6822-
assert.ok($.isFunction(filter), 'filter is function');
6909+
assert.ok($.isFunction(filter[0]), 'filter is function');
68236910
});
68246911

68256912
QUnit.test('loadOptions.filter should be correct when user filter is also used', function(assert) {

0 commit comments

Comments
 (0)