Skip to content

Commit 3ebd70c

Browse files
author
Alyar
committed
DataGrid: Fix header focus not restoring when multiple grouping applied (T1325775)
1 parent 0459f67 commit 3ebd70c

File tree

2 files changed

+104
-17
lines changed

2 files changed

+104
-17
lines changed

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,90 @@ test('Tab key on the focused group row should be handled by default behavior (T8
13401340
});
13411341
});
13421342

1343+
test('DataGrid - Focus should move back to headers on Shift+Tab when multiple grouping is applied (T1325775)', async (t) => {
1344+
const dataGrid = new DataGrid('#container');
1345+
const headerRow = dataGrid.getHeaders().getHeaderRow(0);
1346+
const headerCell = headerRow.getHeaderCell(2);
1347+
const stateGroupRow = dataGrid.getGroupRow(0);
1348+
const cityGroupRow = dataGrid.getGroupRow(1);
1349+
const firstDataCell = dataGrid.getDataCell(2, 2);
1350+
1351+
await t
1352+
.expect(dataGrid.isReady())
1353+
.ok();
1354+
1355+
await addFocusableElementBefore('#container');
1356+
1357+
await t
1358+
.click(Selector('#focusable-start'))
1359+
.pressKey('tab')
1360+
.expect(headerCell.isFocused)
1361+
.ok()
1362+
1363+
.pressKey('tab')
1364+
.expect(stateGroupRow.isFocused)
1365+
.ok()
1366+
1367+
.pressKey('tab')
1368+
.expect(cityGroupRow.isFocused)
1369+
.ok()
1370+
1371+
.pressKey('tab')
1372+
.expect(firstDataCell.isFocused)
1373+
.ok()
1374+
1375+
.pressKey('shift+tab')
1376+
.expect(cityGroupRow.isFocused)
1377+
.ok()
1378+
1379+
.pressKey('shift+tab')
1380+
.expect(stateGroupRow.isFocused)
1381+
.ok()
1382+
1383+
.pressKey('shift+tab')
1384+
.expect(headerCell.isFocused)
1385+
.ok();
1386+
}).before(async () => {
1387+
await createWidget('dxDataGrid', {
1388+
showBorders: true,
1389+
keyExpr: 'id',
1390+
dataSource: [
1391+
{
1392+
id: 1,
1393+
state: 'Arkansas',
1394+
city: 'Bentonville',
1395+
company: 'Super Mart of the West',
1396+
},
1397+
{
1398+
id: 2,
1399+
state: 'Arkansas',
1400+
city: 'Bentonville',
1401+
company: 'Electronics Depot',
1402+
},
1403+
{
1404+
id: 3,
1405+
state: 'California',
1406+
city: 'Cupertino',
1407+
company: 'Braeburn',
1408+
},
1409+
],
1410+
grouping: {
1411+
autoExpandAll: true,
1412+
},
1413+
columns: [
1414+
{
1415+
dataField: 'state',
1416+
groupIndex: 0,
1417+
},
1418+
{
1419+
dataField: 'city',
1420+
groupIndex: 1,
1421+
},
1422+
'company',
1423+
],
1424+
});
1425+
});
1426+
13431427
test('Row should not be focused by "focusedRowIndex" after change "pageIndex" by pager if "autoNavigateToFocused" row is false', async (t) => {
13441428
const dataGrid = new DataGrid('#container');
13451429
await t

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

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -802,8 +802,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo
802802
return;
803803
}
804804

805-
const focusedViewElement = this._focusedView?.element();
806-
$(focusedViewElement).addClass(FOCUS_STATE_CLASS);
805+
$(this._focusedView?.element()).addClass(FOCUS_STATE_CLASS);
807806

808807
const { isLastValidCell, isOriginalHandlerRequired } = this._getTabBoundaryInfo(event);
809808

@@ -1106,6 +1105,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo
11061105

11071106
// Handle row transition — fires focusedRowChanging event
11081107
$cell = this._checkNewLineTransition($event, $cell)!;
1108+
11091109
if (!$cell) {
11101110
return false;
11111111
}
@@ -2058,13 +2058,15 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo
20582058
}
20592059

20602060
protected _isFirstValidCell(cellPosition) {
2061-
let isFirstValidCell = false;
2061+
if (cellPosition.rowIndex !== 0) {
2062+
return false;
2063+
}
20622064

2063-
if (cellPosition.rowIndex === 0 && cellPosition.columnIndex >= 0) {
2064-
isFirstValidCell = isFirstValidCell || !this._hasValidCellBeforePosition(cellPosition);
2065+
if (this._isFullRowFocusType(cellPosition.rowIndex) && cellPosition.columnIndex > 0) {
2066+
return true;
20652067
}
20662068

2067-
return isFirstValidCell;
2069+
return cellPosition.columnIndex >= 0 && !this._hasValidCellBeforePosition(cellPosition);
20682070
}
20692071

20702072
private _hasValidCellBeforePosition(cellPosition) {
@@ -2099,36 +2101,37 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo
20992101
}
21002102

21012103
protected _isLastValidCell(cellPosition) {
2102-
const nextColumnIndex = cellPosition.columnIndex >= 0 ? cellPosition.columnIndex + 1 : 0;
21032104
const { rowIndex } = cellPosition;
2104-
const checkingPosition = {
2105-
columnIndex: nextColumnIndex,
2106-
rowIndex,
2107-
};
2108-
const visibleRows = this._dataController.getVisibleRows();
2109-
const row = visibleRows && visibleRows[rowIndex];
2110-
const isLastRow = this._isLastRow(rowIndex);
21112105

2112-
if (!isLastRow) {
2106+
if (!this._isLastRow(rowIndex)) {
21132107
return false;
21142108
}
21152109

2116-
const isFullRowFocus = row?.rowType === 'group' || row?.rowType === 'groupFooter';
2117-
if (isFullRowFocus && cellPosition.columnIndex > 0) {
2110+
if (this._isFullRowFocusType(rowIndex) && cellPosition.columnIndex > 0) {
21182111
return true;
21192112
}
21202113

21212114
if (cellPosition.columnIndex === this._getVisibleColumnCount() - 1) {
21222115
return true;
21232116
}
21242117

2118+
const nextColumnIndex = cellPosition.columnIndex >= 0 ? cellPosition.columnIndex + 1 : 0;
2119+
const checkingPosition = { columnIndex: nextColumnIndex, rowIndex };
2120+
21252121
if (this._isCellByPositionValid(checkingPosition)) {
21262122
return false;
21272123
}
21282124

21292125
return this._isLastValidCell(checkingPosition);
21302126
}
21312127

2128+
private _isFullRowFocusType(rowIndex: number): boolean {
2129+
const visibleRows = this._dataController.getVisibleRows();
2130+
const row = visibleRows && visibleRows[rowIndex];
2131+
2132+
return row?.rowType === 'group' || row?.rowType === 'groupFooter';
2133+
}
2134+
21322135
// #endregion Cell_Position
21332136
// #region DOM_Manipulation
21342137
/**

0 commit comments

Comments
 (0)