Skip to content

Commit

Permalink
DropDownBox: items in the value should be sorted by selection order o…
Browse files Browse the repository at this point in the history
…n async load (T1181665) (#25642)
  • Loading branch information
AlexanderMoiseev authored Sep 27, 2023
1 parent cf4dc9f commit 3ddbe14
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
17 changes: 13 additions & 4 deletions packages/devextreme/js/ui/drop_down_box.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ const DropDownBox = DropDownEditor.inherit({
});
},

_sortValuesByKeysOrder(orderedKeys, values) {
const sortedValues = values.sort((a, b) => {
return orderedKeys.indexOf(a.itemKey) - orderedKeys.indexOf(b.itemKey);
});

return sortedValues.map(x => x.itemDisplayValue);
},

_renderInputValue: function() {
this._rejectValueLoading();
const values = [];
Expand All @@ -157,9 +165,9 @@ const DropDownBox = DropDownEditor.inherit({
.always(item => {
const displayValue = this._displayGetter(item);
if(isDefined(displayValue)) {
values.push(displayValue);
values.push({ itemKey: key, itemDisplayValue: displayValue });
} else if(this.option('acceptCustomValue')) {
values.push(key);
values.push({ itemKey: key, itemDisplayValue: key });
}
deferred.resolve();
});
Expand All @@ -170,8 +178,9 @@ const DropDownBox = DropDownEditor.inherit({
return when
.apply(this, itemLoadDeferreds)
.always(() => {
this.option('displayValue', values);
callBase(values.length && values);
const orderedValues = this._sortValuesByKeysOrder(keys, values);
this.option('displayValue', orderedValues);
callBase(values.length && orderedValues);
});
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,64 @@ const moduleConfig = {
}
};

QUnit.module('items order', moduleConfig, () => {
function getStore(items) {
return {
load: () => {
$.Deferred().resolve(items).promise();
},
byKey: (key) => {
const d = $.Deferred();
if(key === 10250) {
setTimeout(() => {
d.resolve(items[0]);
}, 300);
} else if(key === 10252) {
setTimeout(() => {
d.resolve(items[1]);
}, 500);
} else {
d.resolve(items[2]);
}

return d.promise();
}
};
}

QUnit.test('should be correct when items loaded asynchronously and display value is set', function(assert) {
const items = [{ id: 10250, name: 'HANAR' }, { id: 10252, name: 'SUPRD' }, { id: 10249, name: 'Tomps' }];

const instance = this.$element.dxDropDownBox({
dataSource: getStore(items),
valueExpr: 'id',
displayExpr: 'name',
value: [10250, 10252, 10249]
}).dxDropDownBox('instance');

this.clock.tick(500);

assert.deepEqual(instance.option('value'), [10250, 10252, 10249], 'value is correct');
assert.strictEqual(instance.option('text'), 'HANAR, SUPRD, Tomps', 'text is correct');
assert.strictEqual($(`.${TEXTEDITOR_INPUT_CLASS}`).val(), 'HANAR, SUPRD, Tomps', 'input value is correct');
});

QUnit.test('should be correct when items loaded asynchronously (T1181665)', function(assert) {
const items = [10250, 10252, 10249];

const instance = this.$element.dxDropDownBox({
dataSource: getStore(items),
value: items
}).dxDropDownBox('instance');

this.clock.tick(500);

assert.deepEqual(instance.option('value'), [10250, 10252, 10249], 'value is correct');
assert.strictEqual(instance.option('text'), '10250, 10252, 10249', 'text is correct');
assert.strictEqual($(`.${TEXTEDITOR_INPUT_CLASS}`).val(), '10250, 10252, 10249', 'input value is correct');
});
});

QUnit.module('common', moduleConfig, () => {
QUnit.test('the widget should display custom value without the dataSource', function(assert) {
this.$element.dxDropDownBox({ value: 1, acceptCustomValue: true });
Expand Down

0 comments on commit 3ddbe14

Please sign in to comment.