Skip to content

Commit bca75fd

Browse files
authored
DataGrid - Tab key should activate editor with virtual scrolling enabled (T1290811) (DevExpress#30668)
1 parent c93b676 commit bca75fd

File tree

2 files changed

+118
-25
lines changed

2 files changed

+118
-25
lines changed

e2e/testcafe-devextreme/tests/dataGrid/common/keyboardNavigation/startEditing.functional.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import DataGrid from 'devextreme-testcafe-models/dataGrid';
2+
import { ClientFunction } from 'testcafe';
23
import url from '../../../../helpers/getPageUrl';
34
import { createWidget } from '../../../../helpers/createWidget';
45

@@ -36,6 +37,86 @@ test('Editing should start by pressing enter after scrolling content with scroll
3637
});
3738
});
3839

40+
test('editing.allowUpdating callback should receive correct row on tab key on first cell with virtual scrolling (T1290811)', async (t) => {
41+
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
42+
43+
await dataGrid.scrollBy({ y: 10000 });
44+
45+
await t
46+
.click(dataGrid.getDataCell(49, 0).element)
47+
.expect(dataGrid.getDataCell(49, 0).getEditor().element.focused).ok();
48+
49+
await t
50+
.pressKey('tab')
51+
.expect(dataGrid.getDataCell(49, 1).getEditor().element.focused).ok();
52+
53+
const eventRowKeys = await ClientFunction(() => (window as any).eventRowKeys)();
54+
const uniqueRowKeys = [...new Set(eventRowKeys)];
55+
56+
await t.expect(uniqueRowKeys).eql([49]);
57+
}).before(async () => {
58+
await createWidget('dxDataGrid', {
59+
dataSource: [...new Array(50)].map((_, i) => ({
60+
id: i,
61+
data: `Row ${i}`,
62+
})),
63+
keyExpr: 'id',
64+
columns: ['id', 'data'],
65+
editing: {
66+
mode: 'cell',
67+
allowUpdating: (e) => {
68+
(window as any).eventRowKeys ??= [];
69+
(window as any).eventRowKeys.push(e.row?.key);
70+
return true;
71+
},
72+
},
73+
scrolling: {
74+
mode: 'virtual',
75+
},
76+
height: 300,
77+
});
78+
});
79+
80+
test('editing.allowUpdating callback should receive correct row on tab key on last cell with virtual scrolling (T1290811)', async (t) => {
81+
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
82+
83+
await dataGrid.scrollBy({ y: 10000 });
84+
85+
await t
86+
.click(dataGrid.getDataCell(48, 1).element)
87+
.expect(dataGrid.getDataCell(48, 1).getEditor().element.focused).ok();
88+
89+
await t
90+
.pressKey('tab')
91+
.expect(dataGrid.getDataCell(49, 0).getEditor().element.focused).ok();
92+
93+
const eventRowKeys = await ClientFunction(() => (window as any).eventRowKeys)();
94+
const uniqueRowKeys = [...new Set(eventRowKeys)];
95+
96+
await t.expect(uniqueRowKeys).eql([48, 49]);
97+
}).before(async () => {
98+
await createWidget('dxDataGrid', {
99+
dataSource: [...new Array(50)].map((_, i) => ({
100+
id: i,
101+
data: `Row ${i}`,
102+
})),
103+
keyExpr: 'id',
104+
columns: ['id', 'data'],
105+
editing: {
106+
mode: 'cell',
107+
allowUpdating: (e) => {
108+
(window as any).eventRowKeys ??= [];
109+
(window as any).eventRowKeys.push(e.row?.key);
110+
return true;
111+
},
112+
},
113+
scrolling: {
114+
mode: 'virtual',
115+
},
116+
height: 300,
117+
});
118+
});
119+
39120
test('DataGrid should not remove the minus symbol when editing started (T1201166)', async (t) => {
40121
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
41122

packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -959,49 +959,52 @@ export class KeyboardNavigationController extends modules.ViewController {
959959

960960
private _editingCellTabHandler(eventArgs, direction) {
961961
const eventTarget = eventArgs.originalEvent.target;
962-
let $cell = this._getCellElementFromTarget(eventTarget);
963-
let isEditingAllowed;
964-
const $event = eventArgs.originalEvent;
965-
const elementType = this._getElementType(eventTarget);
962+
const $targetCell = this._getCellElementFromTarget(eventTarget);
963+
const isCommandCell = $targetCell.is(COMMAND_CELL_SELECTOR);
966964

967-
if ($cell.is(COMMAND_CELL_SELECTOR)) {
965+
if (isCommandCell) {
968966
return !this._targetCellTabHandler(eventArgs, direction);
969967
}
970968

971-
this._updateFocusedCellPosition($cell);
969+
this._updateFocusedCellPosition($targetCell);
970+
971+
const elementType = this._getElementType(eventTarget);
972972
const nextCellInfo = this._getNextCellByTabKey(
973-
$event,
973+
eventArgs.originalEvent,
974974
direction,
975975
elementType,
976976
);
977-
$cell = nextCellInfo.$cell;
977+
const $nextCell = nextCellInfo.$cell;
978978

979-
if (!$cell || this._handleTabKeyOnMasterDetailCell($cell, direction)) {
979+
if (!$nextCell || this._handleTabKeyOnMasterDetailCell($nextCell, direction)) {
980980
return false;
981981
}
982982

983-
const column = this._getColumnByCellElement($cell);
984-
const $row = $cell.parent();
985-
const rowIndex = this._getRowIndex($row);
986-
const row = this._dataController.items()[rowIndex] as any;
987-
const editingController = this._editingController;
983+
let isEditingAllowed = false;
984+
const column = this._getColumnByCellElement($nextCell);
988985

989-
if (column && column.allowEditing) {
986+
if (column?.allowEditing) {
987+
const $row = $nextCell.parent();
988+
const rowIndex = this._getLocalRowIndex($row);
989+
const row = this._dataController.items()[rowIndex] as any;
990990
const isDataRow = !row || row.rowType === 'data';
991-
isEditingAllowed = editingController.allowUpdating({ row })
992-
? isDataRow
993-
: row && row.isNewRow;
991+
992+
isEditingAllowed = this._editingController.allowUpdating({ row })
993+
? isDataRow : row?.isNewRow;
994994
}
995995

996996
if (!isEditingAllowed) {
997997
this._closeEditCell();
998998
}
999999

1000-
if (this._focusCell($cell, !nextCellInfo.isHighlighted)) {
1001-
if (!this._isRowEditMode() && isEditingAllowed) {
1000+
const nextCellFocused = this._focusCell($nextCell, !nextCellInfo.isHighlighted);
1001+
1002+
if (nextCellFocused) {
1003+
const isRowMode = this._isRowEditMode();
1004+
if (!isRowMode && isEditingAllowed) {
10021005
this._editFocusedCell();
10031006
} else {
1004-
this._focusInteractiveElement($cell, eventArgs.shift);
1007+
this._focusInteractiveElement($nextCell, eventArgs.shift);
10051008
}
10061009
}
10071010

@@ -2345,11 +2348,14 @@ export class KeyboardNavigationController extends modules.ViewController {
23452348
columnIndex: number,
23462349
): void {
23472350
const $cell = this._getFocusedCell();
2348-
const rowIndex = this._getRowIndex($cell?.parent());
2351+
const $row = $cell?.parent();
2352+
2353+
const rowIndex = this.getRowIndex();
23492354
const localRowIndex = Math.min(
2350-
rowIndex - this._dataController.getRowIndexOffset(),
2355+
this._getLocalRowIndex($row),
23512356
this._dataController.items().length - 1,
23522357
);
2358+
23532359
const isEditingCell = this._editingController.isEditCell(
23542360
localRowIndex,
23552361
columnIndex,
@@ -2491,8 +2497,8 @@ export class KeyboardNavigationController extends modules.ViewController {
24912497
}
24922498
}
24932499

2494-
private _getRowIndex($row) {
2495-
let rowIndex = this._rowsView.getRowIndex($row);
2500+
private _getRowIndex($row): number {
2501+
let rowIndex = this._getLocalRowIndex($row);
24962502

24972503
if (rowIndex >= 0) {
24982504
rowIndex += this._dataController.getRowIndexOffset();
@@ -2501,6 +2507,12 @@ export class KeyboardNavigationController extends modules.ViewController {
25012507
return rowIndex;
25022508
}
25032509

2510+
protected _getLocalRowIndex($row): number {
2511+
const rowIndex = this._rowsView.getRowIndex($row);
2512+
2513+
return rowIndex;
2514+
}
2515+
25042516
private _hasSkipRow($row) {
25052517
const row = $row && $row.get(0);
25062518
return row && row.style.display === 'none';

0 commit comments

Comments
 (0)