Skip to content

Commit 4ed64e8

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

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
@@ -34,12 +34,12 @@ function xor(a: boolean, b: boolean): boolean {
3434
}
3535

3636
const TAGBOX_TAG_DATA_KEY = 'dxTagData';
37+
const TAGBOX_TAG_DISPLAY_VALUE = 'dxTagDisplayValue';
3738

3839
const TAGBOX_CLASS = 'dx-tagbox';
3940
const TAGBOX_TAG_CONTAINER_CLASS = 'dx-tag-container';
4041
const TAGBOX_TAG_CLASS = 'dx-tag';
4142
const TAGBOX_MULTI_TAG_CLASS = 'dx-tagbox-multi-tag';
42-
const TAGBOX_CUSTOM_TAG_CLASS = 'dx-tag-custom';
4343
const TAGBOX_TAG_REMOVE_BUTTON_CLASS = 'dx-tag-remove-button';
4444
const TAGBOX_ONLY_SELECT_CLASS = 'dx-tagbox-only-select';
4545
const TAGBOX_SINGLE_LINE_CLASS = 'dx-tagbox-single-line';
@@ -1243,24 +1243,23 @@ class TagBox<
12431243
const itemModel = this._getItemModel(item, displayValue);
12441244

12451245
if ($tag) {
1246-
if (isDefined(displayValue)) {
1246+
const tagDisplayValue = $tag.data(TAGBOX_TAG_DISPLAY_VALUE);
1247+
1248+
if (isDefined(displayValue) && !equalByValue(tagDisplayValue, displayValue)) {
12471249
$tag.empty();
12481250
this._applyTagTemplate(itemModel, $tag);
12491251
}
1250-
1251-
$tag.removeClass(TAGBOX_CUSTOM_TAG_CLASS);
12521252
this._updateElementAria($tag.attr('id'));
12531253
} else {
12541254
const tagId = `dx-${new Guid()}`;
12551255

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

12581258
this._setTagAria($tag, isDefined(displayValue) ? displayValue : value);
12591259

12601260
if (isDefined(item)) {
12611261
this._applyTagTemplate(itemModel, $tag);
12621262
} else {
1263-
$tag.addClass(TAGBOX_CUSTOM_TAG_CLASS);
12641263
this._applyTagTemplate(value, $tag);
12651264
}
12661265

@@ -1303,11 +1302,12 @@ class TagBox<
13031302
return result;
13041303
}
13051304

1306-
_createTag(value, $input, tagId): dxElementWrapper {
1305+
_createTag(value, $input, tagId, displayValue): dxElementWrapper {
13071306
return $('<div>')
13081307
.attr('id', tagId)
13091308
.addClass(TAGBOX_TAG_CLASS)
13101309
.data(TAGBOX_TAG_DATA_KEY, value)
1310+
.data(TAGBOX_TAG_DISPLAY_VALUE, displayValue)
13111311
.insertBefore($input);
13121312
}
13131313

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)