Skip to content

Commit 4c2eb72

Browse files
Form: refix close popup on label click (T1258881) (#28609)
1 parent 90626e0 commit 4c2eb72

File tree

2 files changed

+109
-31
lines changed

2 files changed

+109
-31
lines changed

packages/devextreme/js/__internal/ui/form/m_form.layout_manager.utils.ts

+20-27
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import $ from '@js/core/renderer';
33
import { extend } from '@js/core/utils/extend';
44
import { captionize } from '@js/core/utils/inflector';
55
import { each } from '@js/core/utils/iterator';
6-
import { isBoolean, isDefined, isFunction } from '@js/core/utils/type';
6+
import { isDefined, isFunction } from '@js/core/utils/type';
77
import type { dxDropDownEditorOptions } from '@js/ui/drop_down_editor/ui.drop_down_editor';
88
import type { FormItemComponent } from '@js/ui/form';
9-
import type { dxOverlayOptions } from '@js/ui/overlay';
9+
import type { Properties as PopupProperties } from '@js/ui/popup';
1010
import type dxTextBox from '@js/ui/text_box';
1111

1212
import { SIMPLE_ITEM_TYPE } from './constants';
@@ -167,12 +167,10 @@ export function convertToLabelMarkOptions(
167167
};
168168
}
169169

170-
// eslint-disable-next-line @typescript-eslint/naming-convention
171-
function _getDropDownEditorOptions(
170+
function getDropDownEditorOptions(
172171
$parent,
173172
editorType: FormItemComponent,
174173
editorInputId: string,
175-
onContentReadyExternal?: DropDownOptions['onContentReady'],
176174
): DropDownOptions {
177175
const isDropDownEditor = DROP_DOWN_EDITORS.includes(editorType);
178176

@@ -181,33 +179,28 @@ function _getDropDownEditorOptions(
181179
}
182180

183181
return {
184-
onContentReady: (e) => {
185-
const { component } = e;
182+
// @ts-expect-error // unpublished option
183+
onPopupInitialized: ({ component, popup }): void => {
186184
const openOnFieldClick = component.option('openOnFieldClick') as DropDownOptions['openOnFieldClick'];
187-
const initialHideOnOutsideClick = component.option('dropDownOptions.hideOnOutsideClick') as dxOverlayOptions<dxTextBox>['hideOnOutsideClick'];
188-
189-
if (openOnFieldClick) {
190-
component.option('dropDownOptions', {
191-
hideOnOutsideClick: (e) => {
192-
if (isBoolean(initialHideOnOutsideClick)) {
193-
return initialHideOnOutsideClick;
194-
}
185+
const initialHideOnOutsideClick = popup.option('hideOnOutsideClick') as PopupProperties['hideOnOutsideClick'];
195186

196-
const $target = $(e.target);
197-
const $label = $parent.find(`label[for="${editorInputId}"]`);
198-
const isLabelClicked = !!$target.closest($label).length;
187+
// Do not overwrite boolean hideOnOutsideClick
188+
if (openOnFieldClick && isFunction(initialHideOnOutsideClick)) {
189+
const hideOnOutsideClick: PopupProperties['hideOnOutsideClick'] = (e) => {
190+
const $target = $(e.target);
191+
const $label = $parent.find(`label[for="${editorInputId}"]`);
192+
const isLabelClicked = !!$target.closest($label).length;
199193

200-
if (!isFunction(initialHideOnOutsideClick)) {
201-
return !isLabelClicked;
202-
}
194+
return !isLabelClicked && initialHideOnOutsideClick(e);
195+
};
203196

204-
return !isLabelClicked && initialHideOnOutsideClick(e);
205-
},
197+
component.option('dropDownOptions', {
198+
hideOnOutsideClick,
206199
});
207-
}
208200

209-
if (isFunction(onContentReadyExternal)) {
210-
onContentReadyExternal(e);
201+
popup.option({
202+
hideOnOutsideClick,
203+
});
211204
}
212205
},
213206
};
@@ -245,7 +238,7 @@ function _convertToEditorOptions({
245238
const stylingMode = externalEditorOptions?.stylingMode || editorStylingMode;
246239
const useSpecificLabelOptions = EDITORS_WITH_SPECIFIC_LABELS.includes(editorType);
247240

248-
const dropDownEditorOptions = _getDropDownEditorOptions($parent, editorType, editorInputId, externalEditorOptions?.onContentReady);
241+
const dropDownEditorOptions = getDropDownEditorOptions($parent, editorType, editorInputId);
249242

250243
const result = extend(
251244
true,

packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.tests.js

+89-4
Original file line numberDiff line numberDiff line change
@@ -4579,15 +4579,100 @@ QUnit.test('form should be dirty when some editors are dirty', function(assert)
45794579
// NOTE: In the real environment, clicking the label triggers a click on the editor,
45804580
// toggling the popup visibility if openOnFieldClick=true.
45814581
// This assertion only takes hideOnOutsideClick into account
4582-
if(hideOnOutsideClick === false) {
4583-
assert.true(editorInstance.option('opened'), `drop down list ${openOnFieldClick ? 'is hidden by triggered input click' : 'is visible'}`);
4584-
} else {
4585-
assert.strictEqual(editorInstance.option('opened'), openOnFieldClick, `drop down list is hidden by ${openOnFieldClick ? 'triggered input click' : 'outside click'}`);
4582+
switch(hideOnOutsideClick) {
4583+
case true:
4584+
assert.false(editorInstance.option('opened'), 'drop down list is hidden by outside click');
4585+
break;
4586+
case false:
4587+
assert.true(editorInstance.option('opened'), `drop down list ${openOnFieldClick ? 'is hidden by triggered input click' : 'is visible'}`);
4588+
break;
4589+
default:
4590+
assert.strictEqual(editorInstance.option('opened'), openOnFieldClick, `drop down list is hidden by ${openOnFieldClick ? 'triggered input click' : 'outside click'}`);
45864591
}
45874592
});
45884593
});
45894594
});
45904595

4596+
QUnit.test('DropDownEditor popup must toggle on input or dropDownButton click if openOnFieldClick = true', function(assert) {
4597+
const $form = $('#form').dxForm({
4598+
formData: { CustomerID: 'VINET' },
4599+
items: [{
4600+
itemType: 'group',
4601+
colCount: 2,
4602+
items: [{
4603+
dataField: 'CustomerID',
4604+
editorType: 'dxSelectBox',
4605+
editorOptions: {
4606+
items: ['VINET', 'VALUE', 'VINS'],
4607+
value: '',
4608+
openOnFieldClick: true,
4609+
},
4610+
}],
4611+
}],
4612+
});
4613+
4614+
const $dropDownEditorInput = $form.find(`.${EDITOR_INPUT_CLASS}`);
4615+
const $dropDownButton = $form.find(`.${DROP_DOWN_EDITOR_BUTTON_CLASS}`);
4616+
4617+
pointerMock($dropDownEditorInput).click();
4618+
4619+
const editorInstance = $form.dxForm('instance').getEditor('CustomerID');
4620+
4621+
assert.true(editorInstance.option('opened'), 'drop down list is visible');
4622+
4623+
pointerMock($dropDownEditorInput).click();
4624+
4625+
assert.false(editorInstance.option('opened'), 'drop down list is hidden');
4626+
4627+
pointerMock($dropDownButton).click();
4628+
4629+
assert.true(editorInstance.option('opened'), 'drop down list is visible');
4630+
4631+
pointerMock($dropDownButton).click();
4632+
4633+
assert.false(editorInstance.option('opened'), 'drop down list is hidden');
4634+
});
4635+
4636+
QUnit.test('DropDownEditor popup must toggle on dropDownButton click if openOnFieldClick = false', function(assert) {
4637+
const $form = $('#form').dxForm({
4638+
formData: { CustomerID: 'VINET' },
4639+
items: [{
4640+
itemType: 'group',
4641+
colCount: 2,
4642+
items: [{
4643+
dataField: 'CustomerID',
4644+
editorType: 'dxSelectBox',
4645+
editorOptions: {
4646+
items: ['VINET', 'VALUE', 'VINS'],
4647+
value: '',
4648+
openOnFieldClick: false,
4649+
},
4650+
}],
4651+
}],
4652+
});
4653+
4654+
const $dropDownEditorInput = $form.find(`.${EDITOR_INPUT_CLASS}`);
4655+
const $dropDownButton = $form.find(`.${DROP_DOWN_EDITOR_BUTTON_CLASS}`);
4656+
4657+
pointerMock($dropDownEditorInput).click();
4658+
4659+
const editorInstance = $form.dxForm('instance').getEditor('CustomerID');
4660+
4661+
assert.false(editorInstance.option('opened'), 'drop down list is hidden');
4662+
4663+
pointerMock($dropDownButton).click();
4664+
4665+
assert.true(editorInstance.option('opened'), 'drop down list is visible');
4666+
4667+
pointerMock($dropDownEditorInput).click();
4668+
4669+
assert.true(editorInstance.option('opened'), 'drop down list is visible');
4670+
4671+
pointerMock($dropDownButton).click();
4672+
4673+
assert.false(editorInstance.option('opened'), 'drop down list is hidden');
4674+
});
4675+
45914676
QUnit.module('reset', () => {
45924677
[
45934678
['dxCalendar', new Date(2019, 1, 2), { dxCalendar: new Date(2019, 1, 3) } ],

0 commit comments

Comments
 (0)