Skip to content

Commit edca2a9

Browse files
authored
TagBox: previously rendered tags should not rerender on value change (T1246066)
1 parent 4f891e4 commit edca2a9

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ function xor(a: boolean, b: boolean): boolean {
3131
}
3232

3333
const TAGBOX_TAG_DATA_KEY = 'dxTagData';
34+
const TAGBOX_TAG_DISPLAY_VALUE = 'dxTagDisplayValue';
3435

3536
const TAGBOX_CLASS = 'dx-tagbox';
3637
const TAGBOX_TAG_CONTAINER_CLASS = 'dx-tag-container';
3738
const TAGBOX_TAG_CLASS = 'dx-tag';
3839
const TAGBOX_MULTI_TAG_CLASS = 'dx-tagbox-multi-tag';
39-
const TAGBOX_CUSTOM_TAG_CLASS = 'dx-tag-custom';
4040
const TAGBOX_TAG_REMOVE_BUTTON_CLASS = 'dx-tag-remove-button';
4141
const TAGBOX_ONLY_SELECT_CLASS = 'dx-tagbox-only-select';
4242
const TAGBOX_SINGLE_LINE_CLASS = 'dx-tagbox-single-line';
@@ -1143,24 +1143,23 @@ const TagBox = (SelectBox as any).inherit({
11431143
const itemModel = this._getItemModel(item, displayValue);
11441144

11451145
if ($tag) {
1146-
if (isDefined(displayValue)) {
1146+
const tagDisplayValue = $tag.data(TAGBOX_TAG_DISPLAY_VALUE);
1147+
1148+
if (isDefined(displayValue) && !equalByValue(tagDisplayValue, displayValue)) {
11471149
$tag.empty();
11481150
this._applyTagTemplate(itemModel, $tag);
11491151
}
1150-
1151-
$tag.removeClass(TAGBOX_CUSTOM_TAG_CLASS);
11521152
this._updateElementAria($tag.attr('id'));
11531153
} else {
11541154
const tagId = `dx-${new Guid()}`;
11551155

1156-
$tag = this._createTag(value, $input, tagId);
1156+
$tag = this._createTag(value, $input, tagId, displayValue);
11571157

11581158
this._setTagAria($tag, isDefined(displayValue) ? displayValue : value);
11591159

11601160
if (isDefined(item)) {
11611161
this._applyTagTemplate(itemModel, $tag);
11621162
} else {
1163-
$tag.addClass(TAGBOX_CUSTOM_TAG_CLASS);
11641163
this._applyTagTemplate(value, $tag);
11651164
}
11661165

@@ -1203,11 +1202,12 @@ const TagBox = (SelectBox as any).inherit({
12031202
return result;
12041203
},
12051204

1206-
_createTag(value, $input, tagId) {
1205+
_createTag(value, $input, tagId, displayValue): dxElementWrapper {
12071206
return $('<div>')
12081207
.attr('id', tagId)
12091208
.addClass(TAGBOX_TAG_CLASS)
12101209
.data(TAGBOX_TAG_DATA_KEY, value)
1210+
.data(TAGBOX_TAG_DISPLAY_VALUE, displayValue)
12111211
.insertBefore($input);
12121212
},
12131213

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,63 @@ QUnit.module('tags', moduleSetup, () => {
834834
});
835835
});
836836
});
837+
838+
QUnit.test('Should not rerender previously rendered tags on value change (T1246066)', function(assert) {
839+
let tagRenderCount = 0;
840+
const tagBox = $('#tagBox').dxTagBox({
841+
items: [{ name: 'one', value: 1 }, { name: 'two', value: 2 }],
842+
displayExpr: 'name',
843+
valueExpr: 'value',
844+
value: [1],
845+
tagTemplate(item) {
846+
tagRenderCount += 1;
847+
848+
return $('<div>').text(item);
849+
},
850+
}).dxTagBox('instance');
851+
852+
tagBox.option('value', [1]);
853+
854+
assert.strictEqual(tagRenderCount, 1, 'tag was only rendred once');
855+
});
856+
857+
QUnit.test('Should not rerender previously rendered tags on items change (T1246066)', function(assert) {
858+
let tagRenderCount = 0;
859+
const tagBox = $('#tagBox').dxTagBox({
860+
items: [{ name: 'one', value: 1 }, { name: 'two', value: 2 }],
861+
displayExpr: 'name',
862+
valueExpr: 'value',
863+
value: [1],
864+
tagTemplate(item) {
865+
tagRenderCount += 1;
866+
867+
return $('<div>').text(item);
868+
},
869+
}).dxTagBox('instance');
870+
871+
tagBox.option('items', [{ name: 'one', value: 1 }]);
872+
873+
assert.strictEqual(tagRenderCount, 1, 'tag was only rendred once');
874+
});
875+
876+
QUnit.test('Should rerender tag on update item field that is used as displayExpr', function(assert) {
877+
const $tagBox = $('#tagBox').dxTagBox({
878+
items: [{ name: 'one', value: 1 }, { name: 'two', value: 2 }],
879+
displayExpr: 'name',
880+
valueExpr: 'value',
881+
value: [1],
882+
});
883+
const tagBox = $tagBox.dxTagBox('instance');
884+
885+
let tagText = $tagBox.find(`.${TAGBOX_TAG_CLASS}`).text();
886+
887+
assert.equal(tagText, 'one', 'tag is correct on init');
888+
889+
tagBox.option('items[0].name', 'zero');
890+
891+
tagText = $tagBox.find(`.${TAGBOX_TAG_CLASS}`).text();
892+
assert.equal(tagText, 'zero', 'tag text is updated');
893+
});
837894
});
838895

839896
QUnit.module('multi tag support', {

0 commit comments

Comments
 (0)