Skip to content

Commit

Permalink
DataGrid: Fix the onFocusedRowChanged event that does not raise when …
Browse files Browse the repository at this point in the history
…push API is used to remove a focused row (T1233973) (#27808)
  • Loading branch information
Alyar666 authored Jul 19, 2024
1 parent 0f92630 commit a2192ad
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ export class DataController extends DataHelperMixin(modules.Controller) {
this.dataErrorOccurred.fire(e);
}

private _handleDataPushed(changes) {
protected _handleDataPushed(changes) {
this.pushed.fire(changes);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,8 @@ const columns = (Base: ModuleType<ColumnsController>) => class FocusColumnsExten
};

const data = (Base: ModuleType<DataController>) => class FocusDataControllerExtender extends Base {
private _needToUpdateFocusedRowByIndex = false;

protected _applyChange(change) {
if (change && change.changeType === 'updateFocusedRow') return;

Expand All @@ -548,7 +550,10 @@ const data = (Base: ModuleType<DataController>) => class FocusDataControllerExte
const isPartialUpdate = e.changeType === 'update' && e.repaintChangesOnly;
const isPartialUpdateWithDeleting = isPartialUpdate && e.changeTypes && e.changeTypes.indexOf('remove') >= 0;

if (e.changeType === 'refresh' && e.items.length || isPartialUpdateWithDeleting) {
if (this._needToUpdateFocusedRowByIndex) {
this._needToUpdateFocusedRowByIndex = false;
this._focusController._focusRowByIndex();
} else if (e.changeType === 'refresh' && e.items.length || isPartialUpdateWithDeleting) {
this._updatePageIndexes();
this._updateFocusedRow(e);
} else if (e.changeType === 'append' || e.changeType === 'prepend') {
Expand All @@ -559,6 +564,14 @@ const data = (Base: ModuleType<DataController>) => class FocusDataControllerExte
}
}

protected _handleDataPushed(changes) {
super._handleDataPushed(changes);

const focusedRowKey = this.option('focusedRowKey');

this._needToUpdateFocusedRowByIndex = changes?.some((change) => change.type === 'remove' && equalByValue(change.key, focusedRowKey));
}

private _updatePageIndexes() {
const prevRenderingPageIndex = this._lastRenderingPageIndex || 0;
const renderingPageIndex = this._rowsScrollController ? this._rowsScrollController.pageIndex() : 0;
Expand Down
66 changes: 66 additions & 0 deletions packages/devextreme/testing/testcafe/tests/dataGrid/focus/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,70 @@ test('Should remove dx-focused class on blur event from the cell', async (t) =>
}, {
dependencies: { reshapeOnPush },
})));

// T1233973
test(`DataGrid should restore focused row by index after row removed via push API' (reshapeOnPush=${reshapeOnPush})`, async (t) => {
const dataGrid = new DataGrid(GRID_SELECTOR);

await t
.expect(dataGrid.getDataRow(2).isFocusedRow)
.ok()
.expect(dataGrid.getDataRow(2).element.textContent)
.eql('Item 3')
.expect(dataGrid.option('focusedRowKey'))
.eql(2)
.expect(ClientFunction(() => (window as any).onFocusedRowChangedCounter)())
.eql(1);

await dataGrid.apiPush([{
type: 'remove',
key: 2,
}]);

await t
.expect(dataGrid.getDataRow(2).isFocusedRow)
.ok()
.expect(dataGrid.getDataRow(2).element.textContent)
.eql('Item 4')
.expect(dataGrid.option('focusedRowKey'))
.eql(3)
.expect(ClientFunction(() => (window as any).onFocusedRowChangedCounter)())
.eql(2);
}).before(async () => createWidget('dxDataGrid', ClientFunction(() => {
const { DevExpress } = (window as any);
const store = new DevExpress.data.ArrayStore({
data: [
{ id: 0, name: 'Item 1 ' },
{ id: 1, name: 'Item 2' },
{ id: 2, name: 'Item 3' },
{ id: 3, name: 'Item 4' },
{ id: 4, name: 'Item 5' },
],
key: 'id',
});
const dataSource = new DevExpress.data.DataSource({ store, reshapeOnPush });

return {
columns: ['name'],
dataSource,
keyExpr: 'id',
focusedRowEnabled: true,
focusedRowKey: 2,
onFocusedRowChanged: () => {
const global = window as Window & typeof globalThis
& { onFocusedRowChangedCounter: number };

if (!global.onFocusedRowChangedCounter) {
global.onFocusedRowChangedCounter = 0;
}
global.onFocusedRowChangedCounter += 1;
},
};
}, {
dependencies: { reshapeOnPush },
}))).after(async () => {
await ClientFunction(() => {
delete (window as any).onFocusedRowChangedCounter;
})();
});
});

0 comments on commit a2192ad

Please sign in to comment.