Skip to content

Commit 851e8d2

Browse files
Form: DropDownBox loses its value after the Form is resized (T1196835) (#28709) (#28718)
1 parent 5e993e7 commit 851e8d2

File tree

6 files changed

+167
-45
lines changed

6 files changed

+167
-45
lines changed

packages/devextreme/js/__internal/core/widget/widget.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import DOMComponent from './dom_component';
2323
import type { OptionChanged } from './types';
2424

2525
const DISABLED_STATE_CLASS = 'dx-state-disabled';
26-
const FOCUSED_STATE_CLASS = 'dx-state-focused';
26+
export const FOCUSED_STATE_CLASS = 'dx-state-focused';
2727
const INVISIBLE_STATE_CLASS = 'dx-state-invisible';
2828

2929
function setAttribute(name, value, target): void {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import Widget from '@js/ui/widget/ui.widget';
2929
import DropDownButton from './m_drop_down_button';
3030
import { getElementWidth, getSizeValue } from './m_utils';
3131

32-
const DROP_DOWN_EDITOR_CLASS = 'dx-dropdowneditor';
32+
export const DROP_DOWN_EDITOR_CLASS = 'dx-dropdowneditor';
3333
const DROP_DOWN_EDITOR_INPUT_WRAPPER = 'dx-dropdowneditor-input-wrapper';
3434
const DROP_DOWN_EDITOR_BUTTON_ICON = 'dx-dropdowneditor-icon';
3535
const DROP_DOWN_EDITOR_OVERLAY = 'dx-dropdowneditor-overlay';

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ import TabPanel from '@js/ui/tab_panel';
2626
import { isMaterial, isMaterialBased } from '@js/ui/themes';
2727
import ValidationEngine from '@js/ui/validation_engine';
2828
import Widget from '@js/ui/widget/ui.widget';
29+
import { FOCUSED_STATE_CLASS } from '@ts/core/widget/widget';
30+
import { DROP_DOWN_EDITOR_CLASS } from '@ts/ui/drop_down_editor/m_drop_down_editor';
2931
import { TOOLBAR_CLASS } from '@ts/ui/toolbar/m_constants';
3032

33+
import { TEXTEDITOR_CLASS, TEXTEDITOR_INPUT_CLASS } from '../text_box/m_text_editor.base';
3134
import {
3235
setLabelWidthByMaxLabelWidth,
3336
} from './components/m_label';
@@ -66,8 +69,6 @@ import {
6669
tryGetTabPath,
6770
} from './m_form.utils';
6871

69-
const FOCUSED_STATE_CLASS = 'dx-state-focused';
70-
7172
const ITEM_OPTIONS_FOR_VALIDATION_UPDATING = ['items', 'isRequired', 'validationRules', 'visible'];
7273

7374
// @ts-expect-error
@@ -1201,9 +1202,7 @@ const Form = Widget.inherit({
12011202
},
12021203

12031204
_refresh() {
1204-
const editorSelector = `.${FOCUSED_STATE_CLASS} > :not(.dx-dropdowneditor-input-wrapper) input,`
1205-
+ ` .${FOCUSED_STATE_CLASS} textarea`;
1206-
1205+
const editorSelector = `.${TEXTEDITOR_CLASS}.${FOCUSED_STATE_CLASS}:not(.${DROP_DOWN_EDITOR_CLASS}) .${TEXTEDITOR_INPUT_CLASS}`;
12071206
// @ts-expect-error
12081207
eventsEngine.trigger(this.$element().find(editorSelector), 'change');
12091208

packages/devextreme/js/__internal/ui/tab_panel/m_tab_panel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import supportUtils from '@ts/core/utils/m_support';
1515
// eslint-disable-next-line import/no-named-default
1616
import { default as TabPanelItem } from './m_item';
1717

18-
const TABPANEL_CLASS = 'dx-tabpanel';
18+
export const TABPANEL_CLASS = 'dx-tabpanel';
1919
const TABPANEL_TABS_CLASS = 'dx-tabpanel-tabs';
2020
const TABPANEL_TABS_ITEM_CLASS = 'dx-tabpanel-tab';
2121
const TABPANEL_CONTAINER_CLASS = 'dx-tabpanel-container';

packages/devextreme/js/__internal/ui/text_box/m_text_editor.base.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import ClearButton from './m_text_editor.clear';
2222
import { TextEditorLabel } from './m_text_editor.label';
2323
import TextEditorButtonCollection from './texteditor_button_collection/m_index';
2424

25-
const TEXTEDITOR_CLASS = 'dx-texteditor';
25+
export const TEXTEDITOR_CLASS = 'dx-texteditor';
2626
const TEXTEDITOR_INPUT_CONTAINER_CLASS = 'dx-texteditor-input-container';
27-
const TEXTEDITOR_INPUT_CLASS = 'dx-texteditor-input';
27+
export const TEXTEDITOR_INPUT_CLASS = 'dx-texteditor-input';
2828
const TEXTEDITOR_INPUT_SELECTOR = `.${TEXTEDITOR_INPUT_CLASS}`;
2929
const TEXTEDITOR_CONTAINER_CLASS = 'dx-texteditor-container';
3030
const TEXTEDITOR_BUTTONS_CONTAINER_CLASS = 'dx-texteditor-buttons-container';

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

Lines changed: 158 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import resizeCallbacks from '__internal/core/utils/m_resize_callbacks';
66
import typeUtils from 'core/utils/type';
77
import { extend } from 'core/utils/extend';
88
import visibilityEventsModule from 'common/core/events/visibility_change';
9-
import { EDITORS_WITHOUT_LABELS } from '__internal/ui/form/m_form.layout_manager.utils';
9+
import {
10+
EDITORS_WITHOUT_LABELS,
11+
} from '__internal/ui/form/m_form.layout_manager.utils';
1012
import 'generic_light.css!';
1113
import $ from 'jquery';
1214
import 'ui/autocomplete';
@@ -20,6 +22,10 @@ import 'ui/range_slider';
2022
import windowModule from '__internal/core/utils/m_window';
2123
import Form from 'ui/form';
2224
import TextEditorBase from 'ui/text_box/ui.text_editor.base.js';
25+
import {
26+
TEXTEDITOR_INPUT_CLASS
27+
} from '__internal/ui/text_box/m_text_editor.base';
28+
2329

2430
import {
2531
FIELD_ITEM_CLASS,
@@ -57,6 +63,7 @@ import themes from 'ui/themes';
5763
import registerKeyHandlerTestHelper from '../../helpers/registerKeyHandlerTestHelper.js';
5864
import responsiveBoxScreenMock from '../../helpers/responsiveBoxScreenMock.js';
5965
import { isDefined } from 'core/utils/type.js';
66+
import { TABPANEL_CLASS } from '__internal/ui/tab_panel/m_tab_panel';
6067

6168
const INVALID_CLASS = 'dx-invalid';
6269
const FORM_GROUP_CONTENT_CLASS = 'dx-form-group-content';
@@ -95,9 +102,9 @@ if(device.current().deviceType === 'desktop') {
95102
});
96103
}
97104

98-
QUnit.testInActiveWindow('Form\'s inputs saves value on refresh', function(assert) {
105+
QUnit.testInActiveWindow('Form\'s textbox input saves value on refresh (T404958)', function(assert) {
99106
let screen = 'md';
100-
const $formContainer = $('#form').dxForm({
107+
const $form = $('#form').dxForm({
101108
screenByWidth: function() {
102109
return screen;
103110
},
@@ -113,17 +120,48 @@ QUnit.testInActiveWindow('Form\'s inputs saves value on refresh', function(asser
113120
]
114121
});
115122

116-
$('#form input')
123+
$form.find(`.${TEXTEDITOR_INPUT_CLASS}`)
124+
.first()
125+
.focus()
126+
.val('test');
127+
128+
screen = 'sm';
129+
resizeCallbacks.fire();
130+
131+
const formData = $form.dxForm('instance').option('formData');
132+
133+
assert.deepEqual(formData, { name: 'test' }, 'textbox value updates');
134+
});
135+
136+
QUnit.testInActiveWindow('Form\'s textarea input saves value on refresh (T404958)', function(assert) {
137+
let screen = 'md';
138+
const $form = $('#form').dxForm({
139+
screenByWidth: function() {
140+
return screen;
141+
},
142+
colCountByScreen: {
143+
sm: 1,
144+
md: 2
145+
},
146+
items: [
147+
{
148+
dataField: 'name',
149+
editorType: 'dxTextArea'
150+
}
151+
]
152+
});
153+
154+
$form.find(`.${TEXTEDITOR_INPUT_CLASS}`)
117155
.first()
118156
.focus()
119157
.val('test');
120158

121159
screen = 'sm';
122160
resizeCallbacks.fire();
123161

124-
const formData = $formContainer.dxForm('instance').option('formData');
162+
const formData = $form.dxForm('instance').option('formData');
125163

126-
assert.deepEqual(formData, { name: 'test' }, 'value updates');
164+
assert.deepEqual(formData, { name: 'test' }, 'textarea value updates');
127165
});
128166

129167
QUnit.test('Check field width on render form with colspan', function(assert) {
@@ -4916,39 +4954,124 @@ QUnit.module('reset', () => {
49164954
assert.strictEqual(summaryItemsAfterValidate.length, 2, 'form has validation summary after validation');
49174955
});
49184956

4919-
QUnit.test('DropDownBox should not lose its value if form resized (T1196835)', function(assert) {
4920-
let screen = 'lg';
4921-
4922-
const value = 'VINET';
4923-
const text = 'Vins et alcools Chevalier (France)';
4924-
const $form = $('#form').dxForm({
4925-
formData: { CustomerID: value },
4926-
screenByWidth: function() { return screen; },
4927-
colCountByScreen: {
4928-
sm: 1,
4929-
lg: 2
4930-
},
4931-
items: [
4932-
{
4933-
itemType: 'simple',
4934-
cssClass: 'test-ddbox',
4935-
dataField: 'CustomerID',
4936-
editorOptions: {
4937-
displayExpr: 'Text',
4938-
valueExpr: 'Value',
4939-
showClearButton: true,
4940-
dataSource: [{ Value: value, Text: text }],
4957+
[
4958+
'dxSelectBox',
4959+
'dxDropDownBox'
4960+
].forEach((editorType) => {
4961+
QUnit.test(`Focused ${editorType} should not lose its value when the form is resized (T1196835)`, function(assert) {
4962+
let screen = 'lg';
4963+
4964+
const name = 'VINET';
4965+
const value = 'Vins et alcools Chevalier (France)';
4966+
const form = $('#form').dxForm({
4967+
formData: { name: name },
4968+
screenByWidth: function() { return screen; },
4969+
colCountByScreen: {
4970+
sm: 1,
4971+
lg: 2
4972+
},
4973+
items: [
4974+
{
4975+
itemType: 'simple',
4976+
dataField: 'name',
4977+
editorOptions: {
4978+
displayExpr: 'Text',
4979+
valueExpr: 'Value',
4980+
showClearButton: true,
4981+
dataSource: [{ Value: name, Text: value }],
4982+
},
4983+
editorType,
49414984
},
4942-
editorType: 'dxDropDownBox',
4985+
]
4986+
}).dxForm('instance');
4987+
4988+
const dropDownEditor = form.getEditor('name');
4989+
4990+
screen = 'sm';
4991+
dropDownEditor.focus();
4992+
resizeCallbacks.fire();
4993+
4994+
assert.strictEqual($(form.getEditor('name').field()).val(), value, `${editorType} contains expected value`);
4995+
});
4996+
4997+
QUnit.test(`Focused ${editorType} inside a tabbed item should not lose its value when the form is resized (T1196835)`, function(assert) {
4998+
let screen = 'lg';
4999+
5000+
const name = 'VINET';
5001+
const value = 'Vins et alcools Chevalier (France)';
5002+
const form = $('#form').dxForm({
5003+
formData: { name: name },
5004+
screenByWidth: function() { return screen; },
5005+
colCountByScreen: {
5006+
sm: 1,
5007+
lg: 2
49435008
},
4944-
]
5009+
items: [{
5010+
itemType: 'tabbed',
5011+
tabs: [{
5012+
title: 'Phone',
5013+
colCount: 1,
5014+
items: [{
5015+
itemType: 'simple',
5016+
dataField: 'name',
5017+
editorOptions: {
5018+
displayExpr: 'Text',
5019+
valueExpr: 'Value',
5020+
showClearButton: true,
5021+
dataSource: [{ Value: name, Text: value }],
5022+
},
5023+
editorType,
5024+
}],
5025+
}],
5026+
}],
5027+
}).dxForm('instance');
5028+
5029+
const dropDownEditor = form.getEditor('name');
5030+
5031+
screen = 'sm';
5032+
dropDownEditor.focus();
5033+
resizeCallbacks.fire();
5034+
5035+
assert.strictEqual($(form.getEditor('name').field()).val(), value, `${editorType} contains expected value`);
49455036
});
4946-
const $input = $form.find(`.test-ddbox .${EDITOR_INPUT_CLASS}`);
49475037

4948-
screen = 'sm';
4949-
$input.focus();
4950-
resizeCallbacks.fire();
5038+
QUnit.test(`${editorType} inside a tabbed item and focused tab should not lose its value when the form is resized (T1196835)`, function(assert) {
5039+
let screen = 'lg';
49515040

4952-
assert.strictEqual($input.val(), text, 'ddBox contain correct value');
5041+
const name = 'VINET';
5042+
const value = 'Vins et alcools Chevalier (France)';
5043+
const form = $('#form').dxForm({
5044+
formData: { name: name },
5045+
screenByWidth: function() { return screen; },
5046+
colCountByScreen: {
5047+
sm: 1,
5048+
lg: 2
5049+
},
5050+
items: [{
5051+
itemType: 'tabbed',
5052+
tabs: [{
5053+
title: 'Phone',
5054+
colCount: 1,
5055+
items: [{
5056+
itemType: 'simple',
5057+
dataField: 'name',
5058+
editorOptions: {
5059+
displayExpr: 'Text',
5060+
valueExpr: 'Value',
5061+
showClearButton: true,
5062+
dataSource: [{ Value: name, Text: value }],
5063+
},
5064+
editorType,
5065+
}],
5066+
}],
5067+
}],
5068+
}).dxForm('instance');
5069+
5070+
screen = 'sm';
5071+
$(form.element()).find(`.${TABPANEL_CLASS}`).focus();
5072+
resizeCallbacks.fire();
5073+
5074+
assert.strictEqual($(form.getEditor('name').field()).val(), value, `${editorType} contains expected value`);
5075+
});
49535076
});
49545077
});

0 commit comments

Comments
 (0)