Skip to content

Commit 92f441b

Browse files
authored
DropDownEditor: popup repaint should only use initial dropDownOptions (T1279637) (#30444)
1 parent 1ba4912 commit 92f441b

File tree

5 files changed

+111
-11
lines changed

5 files changed

+111
-11
lines changed

packages/devextreme/js/__internal/ui/drop_down_editor/m_drop_down_editor.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class DropDownEditor<
188188
buttonsLocation: 'default',
189189
useHiddenSubmitElement: false,
190190
validationMessagePosition: 'auto',
191+
_userDropDownOptions: {},
191192
};
192193
}
193194

@@ -237,8 +238,7 @@ class DropDownEditor<
237238
const { rtlEnabled, dropDownOptions } = this.option();
238239

239240
this._updatePopupPosition(rtlEnabled);
240-
// @ts-expect-error ts-error
241-
this._options.cache('dropDownOptions', dropDownOptions);
241+
this._cacheUserDropDownOptions(dropDownOptions);
242242
}
243243

244244
_updatePopupPosition(isRtlEnabled?: boolean): void {
@@ -633,7 +633,7 @@ class DropDownEditor<
633633
_renderPopupContent(): void {}
634634

635635
_renderPopup(): void {
636-
const popupConfig = extend(this._popupConfig(), this._options.cache('dropDownOptions'));
636+
const popupConfig = extend(this._popupConfig(), this.option('_userDropDownOptions'));
637637

638638
// @ts-expect-error ts-error
639639
this._popup = this._createComponent(this._$popup, Popup, popupConfig);
@@ -959,6 +959,12 @@ class DropDownEditor<
959959
}
960960
}
961961

962+
_cacheUserDropDownOptions(value, name = 'dropDownOptions'): void {
963+
const optionName = name.replace('dropDownOptions', '_userDropDownOptions');
964+
965+
this.option(optionName, value);
966+
}
967+
962968
_renderSubmitElement(): void {
963969
if (this.option('useHiddenSubmitElement')) {
964970
this._$submitElement = $('<input>')
@@ -987,7 +993,7 @@ class DropDownEditor<
987993
}
988994

989995
_optionChanged(args: OptionChanged<TProperties>): void {
990-
const { name, value } = args;
996+
const { name, fullName, value } = args;
991997

992998
switch (name) {
993999
case 'width':
@@ -1016,11 +1022,11 @@ class DropDownEditor<
10161022
break;
10171023
case 'dropDownOptions': {
10181024
this._popupOptionChanged(args);
1019-
const { dropDownOptions } = this.option();
1020-
// @ts-expect-error ts-error
1021-
this._options.cache('dropDownOptions', dropDownOptions);
1025+
this._cacheUserDropDownOptions(value, fullName);
10221026
break;
10231027
}
1028+
case '_userDropDownOptions':
1029+
break;
10241030
case 'popupPosition':
10251031
break;
10261032
case 'deferRendering':

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ class Lookup extends DropDownList<LookupProperties> {
617617

618618
const options = extend(
619619
popupConfig,
620-
this._options.cache('dropDownOptions'),
620+
this.option('_userDropDownOptions'),
621621
{
622622
showEvent: null,
623623
hideEvent: null,
@@ -1154,9 +1154,7 @@ class Lookup extends DropDownList<LookupProperties> {
11541154
fullName,
11551155
value: value === 'auto' ? this.initialOption('dropDownOptions')[getFieldName(fullName)] : value,
11561156
});
1157-
const { dropDownOptions } = this.option();
1158-
// @ts-expect-error ts-error
1159-
this._options.cache('dropDownOptions', dropDownOptions);
1157+
this._cacheUserDropDownOptions(value, fullName);
11601158
break;
11611159
}
11621160
default:

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,64 @@ QUnit.module('popup integration', () => {
19131913

19141914
assert.strictEqual($overlayContent.outerWidth(), $container.outerWidth(), 'width is correct');
19151915
});
1916+
1917+
QUnit.test('dropDownOptions should get options from Popup after render', function(assert) {
1918+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1919+
opened: true,
1920+
}).dxDropDownEditor('instance');
1921+
1922+
const { dropDownOptions } = dropDownEditor.option();
1923+
1924+
1925+
assert.strictEqual(dropDownOptions.visible, true, 'dropDownOptions includes visible option from Popup');
1926+
assert.strictEqual(dropDownOptions.disabled, false, 'dropDownOptions includes disabled option from Popup');
1927+
});
1928+
1929+
QUnit.test('Should cache dropDownOptions from user in _userDropDownOptions on init', function(assert) {
1930+
const dropDownOptions = { showTitle: true };
1931+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1932+
opened: true,
1933+
dropDownOptions,
1934+
}).dxDropDownEditor('instance');
1935+
1936+
const { _userDropDownOptions } = dropDownEditor.option();
1937+
1938+
assert.deepEqual(_userDropDownOptions, dropDownOptions, 'initial dropDownOptions are cached in _userDropDownOptions');
1939+
});
1940+
1941+
QUnit.test('Should cache updated dropDownOptions from user in _userDropDownOptions on runtime change', function(assert) {
1942+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1943+
opened: true,
1944+
}).dxDropDownEditor('instance');
1945+
1946+
dropDownEditor.option('dropDownOptions', { width: 123 });
1947+
1948+
const { _userDropDownOptions } = dropDownEditor.option();
1949+
1950+
assert.deepEqual(_userDropDownOptions, { width: 123, showTitle: false }, 'updated dropDownOptions are cached in _userDropDownOptions');
1951+
});
1952+
1953+
QUnit.test('_userDropDownOptions cache should be updated correctly after partial dropDownOptions update', function(assert) {
1954+
const dropDownOptions = {
1955+
showTitle: false,
1956+
position: {
1957+
my: 'left',
1958+
at: 'right',
1959+
of: '#dropDownEditorLazy',
1960+
}
1961+
};
1962+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1963+
opened: true,
1964+
dropDownOptions,
1965+
}).dxDropDownEditor('instance');
1966+
1967+
dropDownEditor.option('dropDownOptions.position.my', 'top');
1968+
1969+
const { _userDropDownOptions } = dropDownEditor.option();
1970+
dropDownOptions.position.my = 'top';
1971+
1972+
assert.deepEqual(_userDropDownOptions, dropDownOptions, 'updated part of dropDownOptions is cached in _userDropDownOptions');
1973+
});
19161974
});
19171975

19181976
QUnit.module('overlay content height', () => {

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,32 @@ QUnit.module('popup', moduleConfig, () => {
14701470

14711471
assert.ok(wheelEvent.originalEvent.isDefaultPrevented());
14721472
});
1473+
1474+
QUnit.test('Popup should not be disabled after runtime change of disabled, dropDownOptions and option that triggers invalidate (T1279637)', function(assert) {
1475+
const dropDownList = $('#dropDownList').dxDropDownList({
1476+
items: [1, 2, 3],
1477+
opened: true,
1478+
disabled: false,
1479+
searchEnabled: true,
1480+
}).dxDropDownList('instance');
1481+
1482+
dropDownList.option({
1483+
disabled: true,
1484+
dropDownOptions: { width: 200 },
1485+
searchEnabled: false,
1486+
});
1487+
let popupDisabled = $('.dx-dropdowneditor-overlay.dx-popup').dxPopup('instance').option('disabled');
1488+
1489+
assert.strictEqual(popupDisabled, true, 'popup is disabled');
1490+
1491+
dropDownList.option({
1492+
disabled: false,
1493+
searchEnabled: true,
1494+
});
1495+
popupDisabled = $('.dx-dropdowneditor-overlay.dx-popup').dxPopup('instance').option('disabled');
1496+
1497+
assert.strictEqual(popupDisabled, false, 'popup is not disabled');
1498+
});
14731499
});
14741500

14751501
QUnit.module('dataSource integration', moduleConfig, function() {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,6 +2535,18 @@ QUnit.module('popup options', {
25352535
assert.roughEqual(getOuterHeight($overlayContent), getOuterHeight($container) / 2, 0.1, 'popup height is correct');
25362536
});
25372537

2538+
QUnit.test('_userDropDownOptions cache should be updated correctly after partial dropDownOptions update', function(assert) {
2539+
const lookup = $('#lookup').dxLookup({ }).dxLookup('instance');
2540+
const dropDownOptionsAfterInit = { ... lookup.option('dropDownOptions') };
2541+
2542+
lookup.open();
2543+
lookup.option('dropDownOptions.width', 123);
2544+
2545+
const { _userDropDownOptions } = lookup.option();
2546+
2547+
assert.deepEqual(_userDropDownOptions, { ...dropDownOptionsAfterInit, width: 123 }, 'updated part of dropDownOptions is cached in _userDropDownOptions');
2548+
});
2549+
25382550
[
25392551
{
25402552
component: PopupFull,

0 commit comments

Comments
 (0)