Skip to content

Commit 9172b79

Browse files
Form: fix get item by path (T1311534) (#31544)
1 parent cc65639 commit 9172b79

File tree

6 files changed

+1248
-1093
lines changed

6 files changed

+1248
-1093
lines changed

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,11 +1373,11 @@ class Form extends Widget<FormProperties> {
13731373
_getItemByField(field: string | {
13741374
fieldName: string;
13751375
fieldPath: string[];
1376-
}, items: PreparedItem[]): PreparedItem | false {
1376+
}, items: PreparedItem[]): PreparedItem | null {
13771377
const fieldParts = isObject(field) ? field : this._getFieldParts(field);
13781378
const { fieldName } = fieldParts;
13791379
const { fieldPath } = fieldParts;
1380-
let resultItem: PreparedItem | false = false;
1380+
let resultItem: PreparedItem | null = null;
13811381

13821382
if (items.length) {
13831383
each(items, (_index: number, item: PreparedItem): boolean => {
@@ -1416,34 +1416,24 @@ class Form extends Widget<FormProperties> {
14161416
fieldName: string;
14171417
fieldPath: string[];
14181418
} {
1419-
const fieldSeparator = '.';
1420-
let fieldName = field;
1421-
let separatorIndex = fieldName.indexOf(fieldSeparator);
1422-
const resultPath = [];
1423-
1424-
while (separatorIndex !== -1) {
1425-
// @ts-expect-error ts-error
1426-
resultPath.push(fieldName.substr(0, separatorIndex));
1427-
fieldName = fieldName.substr(separatorIndex + 1);
1428-
separatorIndex = fieldName.indexOf(fieldSeparator);
1429-
}
1419+
const [fieldName, ...fieldPath] = field.split('.').reverse();
14301420

14311421
return {
14321422
fieldName,
1433-
fieldPath: resultPath.reverse(),
1423+
fieldPath,
14341424
};
14351425
}
14361426

14371427
_getItemByFieldPath(
14381428
path: string[],
14391429
fieldName: string,
14401430
item: Item,
1441-
): Item | false {
1431+
): Item | null {
14421432
const { itemType } = item;
14431433
const subItemsField = this._getSubItemField(itemType);
14441434

14451435
const isItemWithSubItems = itemType === 'group' || itemType === 'tabbed' || (item as TabItem).title;
1446-
let result: Item | false = false;
1436+
let result: Item | null = null;
14471437

14481438
do {
14491439
if (isItemWithSubItems) {
@@ -1459,7 +1449,7 @@ class Form extends Widget<FormProperties> {
14591449
pathNode = path.pop();
14601450
}
14611451

1462-
if (!path.length) {
1452+
if (!path.length && nameWithoutSpaces === pathNode) {
14631453
result = this._getItemByField(fieldName, item[subItemsField]);
14641454

14651455
// eslint-disable-next-line max-depth
@@ -1468,10 +1458,15 @@ class Form extends Widget<FormProperties> {
14681458
}
14691459
}
14701460

1471-
if (!isGroupWithName || (isGroupWithName && nameWithoutSpaces === pathNode)) {
1461+
const isGroupPathNodeOrUnnamed = !isGroupWithName
1462+
|| (isGroupWithName && nameWithoutSpaces === pathNode);
1463+
1464+
if (isGroupPathNodeOrUnnamed && path.length) {
1465+
result = this._searchItemInEverySubItem(path, fieldName, item[subItemsField]);
1466+
14721467
// eslint-disable-next-line max-depth
1473-
if (path.length) {
1474-
result = this._searchItemInEverySubItem(path, fieldName, item[subItemsField]);
1468+
if (!result) {
1469+
break;
14751470
}
14761471
}
14771472
} else {
@@ -1490,20 +1485,17 @@ class Form extends Widget<FormProperties> {
14901485
path: string[],
14911486
fieldName: string,
14921487
items: Item[],
1493-
): Item | false {
1494-
let result: Item | false = false;
1488+
): Item | null {
1489+
let result: Item | null = null;
14951490
each(items, (_index: number, groupItem: GroupItem): boolean => {
14961491
result = this._getItemByFieldPath(path.slice(), fieldName, groupItem);
1492+
14971493
if (result) {
14981494
return false;
14991495
}
15001496
return true;
15011497
});
15021498

1503-
if (!result) {
1504-
return false;
1505-
}
1506-
15071499
return result;
15081500
}
15091501

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const tryGetTabPath = (fullPath: string): string => {
6262

6363
export const getItemPath = (
6464
items: PreparedItem[],
65-
item: PreparedItem | false,
65+
item: PreparedItem | null,
6666
isTabs?: boolean,
6767
): string => {
6868
if (!item) {

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import $ from 'jquery';
2+
import device from 'core/devices';
23

34
import 'ui/form';
5+
import registerKeyHandlerTestHelper from '../../helpers/registerKeyHandlerTestHelper.js';
6+
7+
const EDITOR_INPUT_CLASS = 'dx-texteditor-input';
48

59
QUnit.testStart(function() {
610
const markup = '<div id="form"></div>';
@@ -32,3 +36,19 @@ QUnit.test('Set { items: [{dataField}] }, call registerKeyHandler', function(ass
3236
form.registerKeyHandler('tab', handler);
3337
assert.ok(true, 'no exceptions');
3438
});
39+
40+
if(device.current().deviceType === 'desktop') {
41+
const items = [
42+
{ dataField: 'name', editorType: 'dxTextBox' },
43+
{ dataField: 'age', editorType: 'dxNumberBox' }
44+
];
45+
46+
items.forEach((item) => {
47+
registerKeyHandlerTestHelper.runTests({
48+
createWidget: ($element) => $element.dxForm({ items: items }).dxForm('instance'),
49+
keyPressTargetElement: (widget) => widget.getEditor(item.dataField).$element().find(`.${EDITOR_INPUT_CLASS}`),
50+
checkInitialize: false,
51+
testNamePrefix: `Form -> ${item.editorType}:`
52+
});
53+
});
54+
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,19 +2055,19 @@ module('Align labels', () => {
20552055
}]
20562056
});
20572057

2058-
testWrapper.setItemOption('title1.group1.description', 'visible', false);
2058+
testWrapper.setItemOption('title1.group2.description', 'visible', false);
20592059
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 0, etalonLabelText: 'Home Address' });
20602060
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 1, etalonLabelText: 'Last Name' });
20612061

2062-
testWrapper.setItemOption('title1.group1.homeAddress', 'visible', false);
2062+
testWrapper.setItemOption('title1.group2.homeAddress', 'visible', false);
20632063
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 0, etalonLabelText: 'Name' });
20642064
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 1, etalonLabelText: 'Last Name' });
20652065

2066-
testWrapper.setItemOption('title1.group1.description', 'visible', true);
2066+
testWrapper.setItemOption('title1.group2.description', 'visible', true);
20672067
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 0, etalonLabelText: 'Description' });
20682068
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 1, etalonLabelText: 'Last Name' });
20692069

2070-
testWrapper.setItemOption('title1.group1.homeAddress', 'visible', true);
2070+
testWrapper.setItemOption('title1.group2.homeAddress', 'visible', true);
20712071
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 0, etalonLabelText: 'Description' });
20722072
testWrapper.checkLabelsWidthInGroup({ columnIndex: 0, groupColumnIndex: 1, etalonLabelText: 'Home Address' });
20732073
});

0 commit comments

Comments
 (0)