Skip to content

Commit 7625adf

Browse files
authored
DataGrid - Focus gets removed from rowsview when datagrid repaints on focusChanged event - T1224663 (#28714)
1 parent 5150fd0 commit 7625adf

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

e2e/testcafe-devextreme/tests/dataGrid/focus/focus.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,30 @@ test('DataGrid - FilterRow cell loses focus when focusedRowEnabled is true and e
240240
});
241241
});
242242
});
243+
244+
['onFocusedRowChanged', 'onFocusedRowChanging'].forEach((event) => {
245+
test(`Focus should be preserved on datagrid when rowsview repaints in ${event} event (T1224663)`, async (t) => {
246+
const dataGrid = new DataGrid('#container');
247+
248+
await t
249+
.click(dataGrid.getDataCell(0, 0).element)
250+
.expect(dataGrid.getDataRow(0).isFocusedRow)
251+
.ok();
252+
253+
await t
254+
.pressKey('down')
255+
.expect(dataGrid.getDataRow(1).isFocusedRow)
256+
.ok();
257+
}).before(async () => createWidget('dxDataGrid', {
258+
dataSource: [
259+
{ id: 1, name: 'name 1' },
260+
{ id: 2, name: 'name 2' },
261+
{ id: 3, name: 'name 3' },
262+
],
263+
keyExpr: 'id',
264+
focusedRowEnabled: true,
265+
[event]: (e) => {
266+
e.component.repaint();
267+
},
268+
}));
269+
});

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const ATTRIBUTES = {
44
};
55

66
export const ROWS_VIEW_CLASS = 'rowsview';
7+
export const TABLE_CLASS = 'table';
78
export const EDIT_FORM_CLASS = 'edit-form';
89
export const GROUP_FOOTER_CLASS = 'group-footer';
910
export const ROW_CLASS = 'dx-row';

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

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
import { isDeferred, isDefined, isEmptyObject } from '@js/core/utils/type';
2525
import * as accessibility from '@js/ui/shared/accessibility';
2626
import { focused } from '@js/ui/widget/selectors';
27+
import { isElementInDom } from '@ts/core/utils/m_dom';
2728
import type { AdaptiveColumnsController } from '@ts/grids/grid_core/adaptivity/m_adaptivity';
2829
import type { DataController } from '@ts/grids/grid_core/data_controller/m_data_controller';
2930
import type { EditingController } from '@ts/grids/grid_core/editing/m_editing';
@@ -71,6 +72,7 @@ import {
7172
REVERT_BUTTON_CLASS,
7273
ROWS_VIEW,
7374
ROWS_VIEW_CLASS,
75+
TABLE_CLASS,
7476
WIDGET_CLASS,
7577
} from './const';
7678
import { GridCoreKeyboardNavigationDom } from './dom';
@@ -331,18 +333,32 @@ export class KeyboardNavigationController extends modules.ViewController {
331333

332334
this._documentClickHandler = this._documentClickHandler || this.createAction((e) => {
333335
const $target = $(e.event.target);
334-
const isCurrentRowsViewClick = this._isEventInCurrentGrid(e.event)
335-
&& $target.closest(`.${this.addWidgetPrefix(ROWS_VIEW_CLASS)}`).length;
336-
const isEditorOverlay = $target.closest(
337-
`.${DROPDOWN_EDITOR_OVERLAY_CLASS}`,
338-
).length;
339-
const isColumnResizing = !!this._columnResizerController && this._columnResizerController.isResizing();
340-
if (!isCurrentRowsViewClick && !isEditorOverlay && !isColumnResizing) {
341-
const targetInsideFocusedView = this._focusedView
342-
? $target.parents().filter(this._focusedView.element()).length > 0
343-
: false;
344-
345-
!targetInsideFocusedView && this._resetFocusedCell(true);
336+
337+
const tableSelector = `.${this.addWidgetPrefix(TABLE_CLASS)}`;
338+
const rowsViewSelector = `.${this.addWidgetPrefix(ROWS_VIEW_CLASS)}`;
339+
const editorOverlaySelector = `.${DROPDOWN_EDITOR_OVERLAY_CLASS}`;
340+
341+
// if click was on the datagrid table, but the target element is no more presented in the DOM
342+
const needKeepFocus = !!$target.closest(tableSelector).length && !isElementInDom($target);
343+
344+
if (needKeepFocus) {
345+
e.event.preventDefault();
346+
return;
347+
}
348+
349+
const isRowsViewClick = this._isEventInCurrentGrid(e.event) && !!$target.closest(rowsViewSelector).length;
350+
const isEditorOverlayClick = !!$target.closest(editorOverlaySelector).length;
351+
const isColumnResizing = !!this._columnResizerController?.isResizing();
352+
353+
if (!isRowsViewClick && !isEditorOverlayClick && !isColumnResizing) {
354+
const isClickOutsideFocusedView = this._focusedView
355+
? $target.closest(this._focusedView.element()).length === 0
356+
: true;
357+
358+
if (isClickOutsideFocusedView) {
359+
this._resetFocusedCell(true);
360+
}
361+
346362
this._resetFocusedView();
347363
}
348364
});

0 commit comments

Comments
 (0)