diff --git a/packages/devextreme/js/__internal/grids/data_grid/focus/m_focus.ts b/packages/devextreme/js/__internal/grids/data_grid/focus/m_focus.ts index 25bd6b720df0..231effd4ac54 100644 --- a/packages/devextreme/js/__internal/grids/data_grid/focus/m_focus.ts +++ b/packages/devextreme/js/__internal/grids/data_grid/focus/m_focus.ts @@ -5,6 +5,7 @@ import type { DataController } from '@ts/grids/grid_core/data_controller/data_co import type { DataSourceController } from '@ts/grids/grid_core/data_source/data_source_controller'; import type { FocusDataSourceControllerExtension } from '@ts/grids/grid_core/focus/extenders/focus_data_source_controller'; import { focusModule } from '@ts/grids/grid_core/focus/focus_module'; +import type { KeyboardNavigationController } from '@ts/grids/grid_core/keyboard_navigation/m_keyboard_navigation'; import type { ModuleType } from '@ts/grids/grid_core/m_types'; import type { GroupingDataControllerExtension, GroupingDataSourceAdapter } from '../grouping/m_grouping'; @@ -29,6 +30,13 @@ const data = (Base: DataControllerBase) => class FocusDataControllerExtender ext protected declare dataSourceController: DataSourceController & FocusDataSourceControllerExtension; + protected keyboardNavigationController!: KeyboardNavigationController; + + public init(): void { + this.keyboardNavigationController = this.getController('keyboardNavigation'); + super.init(); + } + private changeRowExpand(path, isRowClick) { // @ts-expect-error if (this.option('focusedRowEnabled') && Array.isArray(path) && this.isRowExpanded(path)) { diff --git a/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts b/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts index 8de826e673db..febc40c8dc70 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts @@ -75,11 +75,11 @@ export class FocusController extends core.ViewController { this._resetFocusedRow(); } else if (isRefreshWithItems || isPartialUpdateWithDeleting) { dataController._updatePageIndexes(); - dataController._updateFocusedRowIfNeeded(e, forceUpdateFocusedRow); + this.updateFocusedRowIfNeeded(e, forceUpdateFocusedRow); } else if (isAppendOrPrepend) { dataController._updatePageIndexes(); } else if (isPartialUpdate) { - dataController._updateFocusedRowIfNeeded(e, forceUpdateFocusedRow); + this.updateFocusedRowIfNeeded(e, forceUpdateFocusedRow); this.resetStaleFocusedRowAfterPartialUpdate(e); } } @@ -100,6 +100,57 @@ export class FocusController extends core.ViewController { } } + private updateFocusedRowIfNeeded(e: DataChange, forceUpdate = false): void { + const operationTypes = e.operationTypes || {}; + const { + reload, fullReload, pageIndex, paging, + } = operationTypes; + const isVirtualScrolling = this.getKeyboardController()._isVirtualScrolling(); + const pagingWithoutVirtualScrolling = paging && !isVirtualScrolling; + const focusedRowKey = this.option('focusedRowKey'); + const isAutoNavigate = this.isAutoNavigateToFocusedRow(); + const isReload = reload && pageIndex === false; + const rowIndexByKey = this.getDataController().getRowIndexByKey(focusedRowKey); + + switch (true) { + case forceUpdate: { + this._focusRowByKeyOrIndex(); + break; + } + case isReload && !fullReload && isDefined(focusedRowKey): { + this._navigateToRow(focusedRowKey, true) + .done((focusedRowIndex) => { + if (focusedRowIndex < 0) { + this._focusRowByIndex(undefined, operationTypes); + } + }); + break; + } + case pagingWithoutVirtualScrolling && isAutoNavigate: { + const focusedRowIndex = this.option('focusedRowIndex')!; + const isValidRowIndexByKey = rowIndexByKey >= 0; + const isValidFocusedRowIndex = focusedRowIndex >= 0; + const isSameRowIndex = focusedRowIndex === rowIndexByKey; + + if (isValidFocusedRowIndex && (isSameRowIndex || !isValidRowIndexByKey)) { + this._focusRowByIndex(focusedRowIndex, operationTypes); + } + break; + } + case pagingWithoutVirtualScrolling && !isAutoNavigate && (rowIndexByKey < 0): { + this.option('focusedRowIndex', -1); + break; + } + case operationTypes.fullReload: { + this._focusRowByKeyOrIndex(); + break; + } + default: { + break; + } + } + } + public optionChanged(args) { const { name, value, previousValue } = args; @@ -627,7 +678,6 @@ export const columns = (Base: ModuleType) => class FocusColum export interface FocusDataControllerExtension { _updatePageIndexes: () => void; - _updateFocusedRowIfNeeded: (e: DataChange, forceUpdate?: boolean) => void; } export const focusDataControllerExtender = ( @@ -639,11 +689,8 @@ export const focusDataControllerExtender = ( protected _focusController!: FocusController; - protected keyboardNavigationController!: KeyboardNavigationController; - public init(): void { this._focusController = this.getController('focus'); - this.keyboardNavigationController = this.getController('keyboardNavigation'); super.init(); } @@ -671,57 +718,6 @@ export const focusDataControllerExtender = ( return this._isPagingByRendering; } - public _updateFocusedRowIfNeeded(e, forceUpdate = false) { - const operationTypes = e.operationTypes || {}; - const { - reload, fullReload, pageIndex, paging, - } = operationTypes; - const isVirtualScrolling = this.keyboardNavigationController._isVirtualScrolling(); - const pagingWithoutVirtualScrolling = paging && !isVirtualScrolling; - const focusedRowKey = this.option('focusedRowKey'); - const isAutoNavigate = this._focusController.isAutoNavigateToFocusedRow(); - const isReload = reload && pageIndex === false; - const rowIndexByKey = this.getRowIndexByKey(focusedRowKey); - - switch (true) { - case forceUpdate: { - this._focusController._focusRowByKeyOrIndex(); - break; - } - case isReload && !fullReload && isDefined(focusedRowKey): { - this._focusController._navigateToRow(focusedRowKey, true) - .done((focusedRowIndex) => { - if (focusedRowIndex < 0) { - this._focusController._focusRowByIndex(undefined, operationTypes); - } - }); - break; - } - case pagingWithoutVirtualScrolling && isAutoNavigate: { - const focusedRowIndex = this.option('focusedRowIndex')!; - const isValidRowIndexByKey = rowIndexByKey >= 0; - const isValidFocusedRowIndex = focusedRowIndex >= 0; - const isSameRowIndex = focusedRowIndex === rowIndexByKey; - - if (isValidFocusedRowIndex && (isSameRowIndex || !isValidRowIndexByKey)) { - this._focusController._focusRowByIndex(focusedRowIndex, operationTypes); - } - break; - } - case pagingWithoutVirtualScrolling && !isAutoNavigate && (rowIndexByKey < 0): { - this.option('focusedRowIndex', -1); - break; - } - case operationTypes.fullReload: { - this._focusController._focusRowByKeyOrIndex(); - break; - } - default: { - break; - } - } - } - /** * @extended: TreeList's focus */