From de0bed180ce41b4b28132997c03747853f9d72e5 Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Wed, 14 Jan 2026 16:59:59 +0200 Subject: [PATCH 1/3] fix(grid): fix out of bounds row index when navigating down from last layout row --- .../lib/grids/grid-mrl-navigation.service.ts | 3 ++ .../grids/grid/grid-mrl-keyboard-nav.spec.ts | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts index 1f0cd65ee7a..ad01cad5c9c 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts @@ -128,6 +128,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { const nextBlock = !this.isDataRow(this.activeNode.row) || (previous ? currentRowStart === 1 : currentRowStart === this.lastRowStartPerBlock()); const nextRI = previous ? this.activeNode.row - 1 : this.activeNode.row + 1; + if (!previous && nextBlock && nextRI >= this.grid.dataView.length) { + return { row: this.activeNode.row, column: this.activeNode.column }; + } if (nextBlock && !this.isDataRow(nextRI)) { return {row: nextRI, column: this.activeNode.column}; } diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts index a4b64813680..2b7384c0c7e 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts @@ -297,6 +297,40 @@ describe('IgxGrid Multi Row Layout - Keyboard navigation #grid', () => { GridFunctions.verifyGridContentActiveDescendant(GridFunctions.getGridContent(fix), cell.nativeElement.id); }); + it('should not return an out of bounds row index when navigating down from the last layout row', () => { + fix.componentInstance.data = SampleTestData.contactInfoDataFull().slice(0, 10); + fix.componentInstance.colGroups = [{ + group: 'group1', + columns: [ + { field: 'ID', rowStart: 1, colStart: 1 }, + { field: 'CompanyName', rowStart: 1, colStart: 2 }, + { field: 'ContactName', rowStart: 1, colStart: 3 }, + { field: 'ContactTitle', rowStart: 1, colStart: 4 }, + { field: 'Address', rowStart: 1, colStart: 5 }, + { field: 'City', rowStart: 2, colStart: 1 }, + { field: 'Region', rowStart: 2, colStart: 2 }, + { field: 'PostalCode', rowStart: 2, colStart: 3 }, + { field: 'Phone', rowStart: 2, colStart: 4 }, + { field: 'Fax', rowStart: 2, colStart: 5 } + ] + }]; + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + const lastRowIndex = grid.dataView.length - 1; + const navService = grid.navigation as IgxGridMRLNavigationService; + const col = grid.getColumnByName('City'); + navService.setActiveNode({ + row: lastRowIndex, + column: col.visibleIndex, + layout: navService.layout(col.visibleIndex) + }); + + const nextPos = navService.getNextVerticalPosition(); + expect(nextPos.row).toBe(lastRowIndex); + expect(nextPos.column).toBe(navService.activeNode.column); + }); + it('should navigate up correctly', () => { fix.componentInstance.colGroups = [{ group: 'group1', From db37e64768b40b480ccf999938facb5966c5a81c Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 15 Jan 2026 13:35:55 +0200 Subject: [PATCH 2/3] fix(grid): remove out of bounds check for next row navigation --- .../src/lib/grids/grid-mrl-navigation.service.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts index ad01cad5c9c..68e1c666e26 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts @@ -128,9 +128,6 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { const nextBlock = !this.isDataRow(this.activeNode.row) || (previous ? currentRowStart === 1 : currentRowStart === this.lastRowStartPerBlock()); const nextRI = previous ? this.activeNode.row - 1 : this.activeNode.row + 1; - if (!previous && nextBlock && nextRI >= this.grid.dataView.length) { - return { row: this.activeNode.row, column: this.activeNode.column }; - } if (nextBlock && !this.isDataRow(nextRI)) { return {row: nextRI, column: this.activeNode.column}; } @@ -358,7 +355,8 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { private hasNextVerticalPosition(prev = false) { if ((prev && this.activeNode.row === 0 && (!this.isDataRow(this.activeNode.row) || this.activeNode.layout.rowStart === 1)) || - (!prev && this.activeNode.row >= this.grid.dataView.length - 1 && this.activeNode.column === this.lastColIndexPerMRLBlock())) { + (!prev && this.activeNode.row >= this.grid.dataView.length - 1 && + this.activeNode.layout.rowStart === this.lastRowStartPerBlock())) { return false; } return true; From d9203e6b89568957dde903bb5f07b86ee02f7a4b Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Thu, 15 Jan 2026 13:48:16 +0200 Subject: [PATCH 3/3] test(grid): import IgxGridMRLNavigationService for keyboard navigation tests --- .../src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts index 2b7384c0c7e..0206e5b5303 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts @@ -12,6 +12,7 @@ import { GridFunctions, GRID_MRL_BLOCK } from '../../test-utils/grid-functions.s import { CellType } from '../common/grid.interface'; import { IgxColumnLayoutComponent } from '../columns/column-layout.component'; import { IGridCellEventArgs, IgxColumnComponent } from '../public_api'; +import { IgxGridMRLNavigationService } from '../grid-mrl-navigation.service'; const DEBOUNCE_TIME = 30; const CELL_CSS_CLASS = '.igx-grid__td';