Skip to content

Commit aa6282b

Browse files
Form: fix get item by path (T1311534) (#31492)
1 parent 305cdc0 commit aa6282b

File tree

6 files changed

+1246
-1090
lines changed

6 files changed

+1246
-1090
lines changed

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,11 +1448,11 @@ class Form extends Widget<FormProperties> {
14481448
_getItemByField(field: string | {
14491449
fieldName: string;
14501450
fieldPath: string[];
1451-
}, items: PreparedItem[]): PreparedItem | false {
1451+
}, items: PreparedItem[]): PreparedItem | null {
14521452
const fieldParts = isObject(field) ? field : this._getFieldParts(field);
14531453
const { fieldName } = fieldParts;
14541454
const { fieldPath } = fieldParts;
1455-
let resultItem: PreparedItem | false = false;
1455+
let resultItem: PreparedItem | null = null;
14561456

14571457
if (items.length) {
14581458
each(items, (_index: number, item: PreparedItem): boolean => {
@@ -1491,34 +1491,24 @@ class Form extends Widget<FormProperties> {
14911491
fieldName: string;
14921492
fieldPath: string[];
14931493
} {
1494-
const fieldSeparator = '.';
1495-
let fieldName = field;
1496-
let separatorIndex = fieldName.indexOf(fieldSeparator);
1497-
const resultPath = [];
1498-
1499-
while (separatorIndex !== -1) {
1500-
// @ts-expect-error ts-error
1501-
resultPath.push(fieldName.substr(0, separatorIndex));
1502-
fieldName = fieldName.substr(separatorIndex + 1);
1503-
separatorIndex = fieldName.indexOf(fieldSeparator);
1504-
}
1494+
const [fieldName, ...fieldPath] = field.split('.').reverse();
15051495

15061496
return {
15071497
fieldName,
1508-
fieldPath: resultPath.reverse(),
1498+
fieldPath,
15091499
};
15101500
}
15111501

15121502
_getItemByFieldPath(
15131503
path: string[],
15141504
fieldName: string,
15151505
item: Item,
1516-
): Item | false {
1506+
): Item | null {
15171507
const { itemType } = item;
15181508
const subItemsField = this._getSubItemField(itemType);
15191509

15201510
const isItemWithSubItems = itemType === 'group' || itemType === 'tabbed' || (item as TabItem).title;
1521-
let result: Item | false = false;
1511+
let result: Item | null = null;
15221512

15231513
do {
15241514
if (isItemWithSubItems) {
@@ -1534,7 +1524,7 @@ class Form extends Widget<FormProperties> {
15341524
pathNode = path.pop();
15351525
}
15361526

1537-
if (!path.length) {
1527+
if (!path.length && nameWithoutSpaces === pathNode) {
15381528
result = this._getItemByField(fieldName, item[subItemsField]);
15391529

15401530
// eslint-disable-next-line max-depth
@@ -1543,10 +1533,15 @@ class Form extends Widget<FormProperties> {
15431533
}
15441534
}
15451535

1546-
if (!isGroupWithName || (isGroupWithName && nameWithoutSpaces === pathNode)) {
1536+
const isGroupPathNodeOrUnnamed = !isGroupWithName
1537+
|| (isGroupWithName && nameWithoutSpaces === pathNode);
1538+
1539+
if (isGroupPathNodeOrUnnamed && path.length) {
1540+
result = this._searchItemInEverySubItem(path, fieldName, item[subItemsField]);
1541+
15471542
// eslint-disable-next-line max-depth
1548-
if (path.length) {
1549-
result = this._searchItemInEverySubItem(path, fieldName, item[subItemsField]);
1543+
if (!result) {
1544+
break;
15501545
}
15511546
}
15521547
} else {
@@ -1565,20 +1560,17 @@ class Form extends Widget<FormProperties> {
15651560
path: string[],
15661561
fieldName: string,
15671562
items: Item[],
1568-
): Item | false {
1569-
let result: Item | false = false;
1563+
): Item | null {
1564+
let result: Item | null = null;
15701565
each(items, (_index: number, groupItem: GroupItem): boolean => {
15711566
result = this._getItemByFieldPath(path.slice(), fieldName, groupItem);
1567+
15721568
if (result) {
15731569
return false;
15741570
}
15751571
return true;
15761572
});
15771573

1578-
if (!result) {
1579-
return false;
1580-
}
1581-
15821574
return result;
15831575
}
15841576

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)