From 664a12999a09887f29237a93659d1a5c430548b2 Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Mon, 27 Apr 2026 18:05:22 +0800 Subject: [PATCH 1/4] fix --- .../devextreme/js/__internal/grids/grid_core/pager/m_pager.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts index ad7118d25190..fdf9ce3e4533 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts @@ -9,6 +9,10 @@ const PAGER_CLASS = 'pager'; export const MAX_PAGES_COUNT = 10; const getPageIndex = function (dataController) { + if (dataController.pageSize() === 0) { + return dataController.pageCount(); + } + // eslint-disable-next-line radix return 1 + (parseInt(dataController.pageIndex()) || 0); }; From 29f7c0253554cb28a61676be9aca1104eb5ee922 Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Tue, 28 Apr 2026 18:37:00 +0800 Subject: [PATCH 2/4] implement test --- .../tests/dataGrid/common/pager.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/e2e/testcafe-devextreme/tests/dataGrid/common/pager.ts b/e2e/testcafe-devextreme/tests/dataGrid/common/pager.ts index 9b7973b975dd..c776369d4d95 100644 --- a/e2e/testcafe-devextreme/tests/dataGrid/common/pager.ts +++ b/e2e/testcafe-devextreme/tests/dataGrid/common/pager.ts @@ -238,6 +238,41 @@ test('Page index should not reset when scrolling while the grid is being refresh height: 440, })); +test('Pager info should show page 1 of 1 after changing pageSize to \'all\' with virtual scrolling', async (t) => { + const dataGrid = new DataGrid('#container'); + const pager = dataGrid.getPager(); + + await t + .click(pager.getNavPage('5').element) + .expect(pager.getNavPage('5').selected) + .ok() + .expect(pager.getInfoText().textContent) + .eql('Page 5 of 10 (50 items)'); + + await t + .click(pager.getPageSize(1).element) + .expect(pager.getInfoText().textContent) + .eql('Page 1 of 1 (50 items)'); +}).before(async () => createWidget('dxDataGrid', { + dataSource: [...new Array(50).keys()].map((i) => ({ id: i })), + keyExpr: 'id', + showBorders: true, + scrolling: { + mode: 'virtual', + }, + paging: { + pageSize: 5, + }, + pager: { + visible: true, + allowedPageSizes: [5, 'all'], + showPageSizeSelector: true, + showInfo: true, + showNavigationButtons: true, + }, + height: 400, +})); + test('No error should occur if dataSource is not defined and pageIndex is promise chained (T1256070)', async (t) => { const dataGrid = new DataGrid('#container'); From 09c0b62d25d12b2cbdd7f3304250901c8cdeff67 Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Wed, 6 May 2026 18:24:56 +0800 Subject: [PATCH 3/4] refix --- .../data_controller/m_data_controller.ts | 44 +++++++------------ .../grids/grid_core/pager/m_pager.ts | 4 -- .../virtual_scrolling/m_virtual_scrolling.ts | 11 ++--- 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts index e8fe7487c881..a1a0e22da3b4 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts @@ -102,8 +102,6 @@ export class DataController extends DataHelperMixin(modules.Controller) { protected _isPaging!: boolean; - private _currentOperationTypes: any | null; - protected _isLoading!: boolean; private _isCustomLoading!: boolean; @@ -212,12 +210,7 @@ export class DataController extends DataHelperMixin(modules.Controller) { this._validatingController = this.getController('validating'); this._isPaging = false; - this._currentOperationTypes = null; - this._dataChangedHandler = (e) => { - this._currentOperationTypes = this._dataSource.operationTypes(); - this._handleDataChanged(e); - this._currentOperationTypes = null; - }; + this._dataChangedHandler = this._handleDataChanged.bind(this); this._columnsChangedHandler = this._handleColumnsChanged.bind(this); this._loadingChangedHandler = this._handleLoadingChanged.bind(this); this._loadErrorHandler = this._handleLoadError.bind(this); @@ -1231,36 +1224,33 @@ export class DataController extends DataHelperMixin(modules.Controller) { } } - public updateItems(change?, isDataChanged?) { - change = change || {}; - const that = this; - change.isFirstRender = !that.changed.fired(); + public updateItems(change: any = {}, isDataChanged?: boolean) { + change.isFirstRender = !this.changed.fired(); - if (that._repaintChangesOnly !== undefined) { - change.repaintChangesOnly = change.repaintChangesOnly ?? that._repaintChangesOnly; - change.needUpdateDimensions = change.needUpdateDimensions || that._needUpdateDimensions; + if (this._repaintChangesOnly !== undefined) { + change.repaintChangesOnly ??= this._repaintChangesOnly; + change.needUpdateDimensions ??= this._needUpdateDimensions; } else if (change.changes) { - change.repaintChangesOnly = that.option('repaintChangesOnly'); + change.repaintChangesOnly = this.option('repaintChangesOnly'); } else if (isDataChanged) { - const operationTypes = that.dataSource().operationTypes(); + const operationTypes = this.dataSource().operationTypes(); - change.repaintChangesOnly = operationTypes && !operationTypes.grouping && !operationTypes.filtering && that.option('repaintChangesOnly'); change.isDataChanged = true; - if (operationTypes && (operationTypes.reload || operationTypes.paging || operationTypes.groupExpanding)) { - change.needUpdateDimensions = true; - } + change.operationTypes = operationTypes; + change.repaintChangesOnly = operationTypes && !operationTypes.grouping && !operationTypes.filtering && this.option('repaintChangesOnly'); + change.needUpdateDimensions = operationTypes && (operationTypes.reload || operationTypes.paging || operationTypes.groupExpanding); } - if (that._updateLockCount && !change.cancel) { - that._changes.push(change); + if (this._updateLockCount && !change.cancel) { + this._changes.push(change); return; } - that._updateItemsCore(change); + this._updateItemsCore(change); if (change.cancel) return; - that._fireChanged(change); + this._fireChanged(change); } public loadingOperationTypes() { @@ -1273,10 +1263,6 @@ export class DataController extends DataHelperMixin(modules.Controller) { * @extended: virtual_scrolling, focus */ protected _fireChanged(change) { - if (this._currentOperationTypes) { - change.operationTypes = this._currentOperationTypes; - this._currentOperationTypes = null; - } deferRender(() => { this.changed.fire(change); }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts index fdf9ce3e4533..ad7118d25190 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts @@ -9,10 +9,6 @@ const PAGER_CLASS = 'pager'; export const MAX_PAGES_COUNT = 10; const getPageIndex = function (dataController) { - if (dataController.pageSize() === 0) { - return dataController.pageCount(); - } - // eslint-disable-next-line radix return 1 + (parseInt(dataController.pageIndex()) || 0); }; diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts index c2717eba9ca3..5a30993d5fa6 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts @@ -1004,18 +1004,19 @@ export const data = (Base: ModuleType) => class VirtualScrolling }; } - private _updateVisiblePageIndex(currentPageIndex?) { + private _updateVisiblePageIndex(value?: number): void { if (!this._rowsScrollController) { return; } - if (isDefined(currentPageIndex)) { - this._silentOption(VISIBLE_PAGE_INDEX, currentPageIndex); + + if (isDefined(value)) { + this._silentOption(VISIBLE_PAGE_INDEX, value); this.pageChanged.fire(); return; } - const viewPortItemIndex = this._rowsScrollController.getViewportItemIndex(); - const newPageIndex = Math.floor(viewPortItemIndex / this.pageSize()); + const viewportItemIndex = this._rowsScrollController.getViewportItemIndex(); + const newPageIndex = Math.floor(viewportItemIndex / this.pageSize()); if (this.pageIndex() !== newPageIndex) { this._silentOption(VISIBLE_PAGE_INDEX, newPageIndex); From b6ffd33930662122d9ae6f9b88caf0ccfa7f8ba5 Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Wed, 6 May 2026 19:12:43 +0800 Subject: [PATCH 4/4] fix tests --- .../grids/grid_core/data_controller/m_data_controller.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts index a1a0e22da3b4..d46e454abbc7 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_controller/m_data_controller.ts @@ -102,6 +102,8 @@ export class DataController extends DataHelperMixin(modules.Controller) { protected _isPaging!: boolean; + private _currentOperationTypes: any | null; + protected _isLoading!: boolean; private _isCustomLoading!: boolean; @@ -210,6 +212,7 @@ export class DataController extends DataHelperMixin(modules.Controller) { this._validatingController = this.getController('validating'); this._isPaging = false; + this._currentOperationTypes = null; this._dataChangedHandler = this._handleDataChanged.bind(this); this._columnsChangedHandler = this._handleColumnsChanged.bind(this); this._loadingChangedHandler = this._handleLoadingChanged.bind(this); @@ -554,6 +557,7 @@ export class DataController extends DataHelperMixin(modules.Controller) { let isAsyncDataSourceApplying = false; this._useSortingGroupingFromColumns = false; + this._currentOperationTypes = this.dataSource().operationTypes(); if (dataSource && !that._isDataSourceApplying) { that._isDataSourceApplying = true; @@ -1163,6 +1167,7 @@ export class DataController extends DataHelperMixin(modules.Controller) { const changeType = change.changeType || 'refresh'; change.changeType = changeType; + change.operationTypes = this._currentOperationTypes; if (dataSource) { const cachedProcessedItems = this._cachedProcessedItems; @@ -1236,7 +1241,6 @@ export class DataController extends DataHelperMixin(modules.Controller) { const operationTypes = this.dataSource().operationTypes(); change.isDataChanged = true; - change.operationTypes = operationTypes; change.repaintChangesOnly = operationTypes && !operationTypes.grouping && !operationTypes.filtering && this.option('repaintChangesOnly'); change.needUpdateDimensions = operationTypes && (operationTypes.reload || operationTypes.paging || operationTypes.groupExpanding); }