Skip to content

Commit 72ed6af

Browse files
authored
DropDownEditor: popup repaint should only use initial dropDownOptions (T1279637) (#30445)
1 parent e8e1da1 commit 72ed6af

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
delete popupConfig.closeOnOutsideClick;
639639
// @ts-expect-error ts-error
@@ -956,6 +956,12 @@ class DropDownEditor<
956956
}
957957
}
958958

959+
_cacheUserDropDownOptions(value, name = 'dropDownOptions'): void {
960+
const optionName = name.replace('dropDownOptions', '_userDropDownOptions');
961+
962+
this.option(optionName, value);
963+
}
964+
959965
_renderSubmitElement(): void {
960966
if (this.option('useHiddenSubmitElement')) {
961967
this._$submitElement = $('<input>')
@@ -984,7 +990,7 @@ class DropDownEditor<
984990
}
985991

986992
_optionChanged(args: OptionChanged<TProperties>): void {
987-
const { name, value } = args;
993+
const { name, fullName, value } = args;
988994

989995
switch (name) {
990996
case 'width':
@@ -1013,11 +1019,11 @@ class DropDownEditor<
10131019
break;
10141020
case 'dropDownOptions': {
10151021
this._popupOptionChanged(args);
1016-
const { dropDownOptions } = this.option();
1017-
// @ts-expect-error ts-error
1018-
this._options.cache('dropDownOptions', dropDownOptions);
1022+
this._cacheUserDropDownOptions(value, fullName);
10191023
break;
10201024
}
1025+
case '_userDropDownOptions':
1026+
break;
10211027
case 'popupPosition':
10221028
break;
10231029
case 'deferRendering':

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

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

623623
const options = extend(
624624
popupConfig,
625-
this._options.cache('dropDownOptions'),
625+
this.option('_userDropDownOptions'),
626626
{
627627
showEvent: null,
628628
hideEvent: null,
@@ -1160,9 +1160,7 @@ class Lookup extends DropDownList<LookupProperties> {
11601160
fullName,
11611161
value: value === 'auto' ? this.initialOption('dropDownOptions')[getFieldName(fullName)] : value,
11621162
});
1163-
const { dropDownOptions } = this.option();
1164-
// @ts-expect-error ts-error
1165-
this._options.cache('dropDownOptions', dropDownOptions);
1163+
this._cacheUserDropDownOptions(value, fullName);
11661164
break;
11671165
}
11681166
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
@@ -1940,6 +1940,64 @@ QUnit.module('popup integration', () => {
19401940

19411941
assert.strictEqual($overlayContent.outerWidth(), $container.outerWidth(), 'width is correct');
19421942
});
1943+
1944+
QUnit.test('dropDownOptions should get options from Popup after render', function(assert) {
1945+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1946+
opened: true,
1947+
}).dxDropDownEditor('instance');
1948+
1949+
const { dropDownOptions } = dropDownEditor.option();
1950+
1951+
1952+
assert.strictEqual(dropDownOptions.visible, true, 'dropDownOptions includes visible option from Popup');
1953+
assert.strictEqual(dropDownOptions.disabled, false, 'dropDownOptions includes disabled option from Popup');
1954+
});
1955+
1956+
QUnit.test('Should cache dropDownOptions from user in _userDropDownOptions on init', function(assert) {
1957+
const dropDownOptions = { showTitle: true };
1958+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1959+
opened: true,
1960+
dropDownOptions,
1961+
}).dxDropDownEditor('instance');
1962+
1963+
const { _userDropDownOptions } = dropDownEditor.option();
1964+
1965+
assert.deepEqual(_userDropDownOptions, dropDownOptions, 'initial dropDownOptions are cached in _userDropDownOptions');
1966+
});
1967+
1968+
QUnit.test('Should cache updated dropDownOptions from user in _userDropDownOptions on runtime change', function(assert) {
1969+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1970+
opened: true,
1971+
}).dxDropDownEditor('instance');
1972+
1973+
dropDownEditor.option('dropDownOptions', { width: 123 });
1974+
1975+
const { _userDropDownOptions } = dropDownEditor.option();
1976+
1977+
assert.deepEqual(_userDropDownOptions, { width: 123, showTitle: false }, 'updated dropDownOptions are cached in _userDropDownOptions');
1978+
});
1979+
1980+
QUnit.test('_userDropDownOptions cache should be updated correctly after partial dropDownOptions update', function(assert) {
1981+
const dropDownOptions = {
1982+
showTitle: false,
1983+
position: {
1984+
my: 'left',
1985+
at: 'right',
1986+
of: '#dropDownEditorLazy',
1987+
}
1988+
};
1989+
const dropDownEditor = $('#dropDownEditorLazy').dxDropDownEditor({
1990+
opened: true,
1991+
dropDownOptions,
1992+
}).dxDropDownEditor('instance');
1993+
1994+
dropDownEditor.option('dropDownOptions.position.my', 'top');
1995+
1996+
const { _userDropDownOptions } = dropDownEditor.option();
1997+
dropDownOptions.position.my = 'top';
1998+
1999+
assert.deepEqual(_userDropDownOptions, dropDownOptions, 'updated part of dropDownOptions is cached in _userDropDownOptions');
2000+
});
19432001
});
19442002

19452003
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
@@ -1471,6 +1471,32 @@ QUnit.module('popup', moduleConfig, () => {
14711471

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

14761502
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
@@ -2533,6 +2533,18 @@ QUnit.module('popup options', {
25332533
assert.roughEqual(getOuterHeight($overlayContent), getOuterHeight($container) / 2, 0.1, 'popup height is correct');
25342534
});
25352535

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

0 commit comments

Comments
 (0)