From aae6443421c7b258a5aaa0fb0c139e7a434515c0 Mon Sep 17 00:00:00 2001 From: teodosiah Date: Tue, 20 Oct 2026 15:23:16 +0300 Subject: [PATCH 1/3] fix(grids): preserve column formatting in newly added rows --- .../grids/core/src/cell.component.html | 14 +++++++- .../grid/src/expandable-cell.component.html | 14 +++++++- .../grids/grid/src/grid-add-row.spec.ts | 33 ++++++++++++++++++- .../src/hierarchical-grid-add-row.spec.ts | 24 ++++++++++++++ .../tree-grid/src/tree-cell.component.html | 14 +++++++- .../src/tree-grid-add-row-ui.spec.ts | 24 ++++++++++++++ src/app/grid-add-row/grid-add-row.sample.html | 2 +- 7 files changed, 120 insertions(+), 5 deletions(-) diff --git a/projects/igniteui-angular/grids/core/src/cell.component.html b/projects/igniteui-angular/grids/core/src/cell.component.html index ffb36674e6b..0b46e96ab61 100644 --- a/projects/igniteui-angular/grids/core/src/cell.component.html +++ b/projects/igniteui-angular/grids/core/src/cell.component.html @@ -76,7 +76,19 @@ [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata" >{{ - !isEmptyAddRowCell ? value : (column.header || column.field) + !isEmptyAddRowCell + ? (formatter + ? (value | columnFormatter:formatter:rowData:columnData) + : column.dataType === "number" + ? (value | number:column.pipeArgs.digitsInfo:grid.locale) + : (column.dataType === 'date' || column.dataType === 'time' || column.dataType === 'dateTime') + ? (value | date:column.pipeArgs.format:column.pipeArgs.timezone:grid.locale) + : column.dataType === 'currency' + ? (value | currency:currencyCode:column.pipeArgs.display:column.pipeArgs.digitsInfo:grid.locale) + : column.dataType === 'percent' + ? (value | percent:column.pipeArgs.digitsInfo:grid.locale) + : value) + : (column.header || column.field) }} } diff --git a/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html index 80f883bdf3f..2ad60d25e9e 100644 --- a/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html +++ b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html @@ -61,7 +61,19 @@ [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata"> - {{ value ? value : (column.header || column.field) }} + {{ value + ? (formatter + ? (value | columnFormatter:formatter:rowData:columnData) + : column.dataType === "number" + ? (value | number:column.pipeArgs.digitsInfo:grid.locale) + : (column.dataType === 'date' || column.dataType === 'time' || column.dataType === 'dateTime') + ? (value | date:column.pipeArgs.format:column.pipeArgs.timezone:grid.locale) + : column.dataType === 'currency' + ? (value | currency:currencyCode:column.pipeArgs.display:column.pipeArgs.digitsInfo:grid.locale) + : column.dataType === 'percent' + ? (value | percent:column.pipeArgs.digitsInfo:grid.locale) + : value) + : (column.header || column.field) }} } diff --git a/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts index 566dafa6e3f..0ace12be450 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts @@ -16,7 +16,7 @@ import { UIInteractions, wait } from '../../../test-utils/ui-interactions.spec'; import { IgxGridRowComponent } from './grid-row.component'; import { takeUntil, first } from 'rxjs/operators'; import { Subject } from 'rxjs'; -import { DefaultSortingStrategy, IgxStringFilteringOperand, SortingDirection, TransactionType } from 'igniteui-angular/core'; +import { DefaultSortingStrategy, GridColumnDataType, IgxStringFilteringOperand, SortingDirection, TransactionType } from 'igniteui-angular/core'; import { IgxGridMRLNavigationService } from 'igniteui-angular/grids/core'; const DEBOUNCETIME = 60; @@ -64,6 +64,37 @@ describe('IgxGrid - Row Adding #grid', () => { actionStrip = fixture.componentInstance.actionStrip; }); + [ + { dataType: GridColumnDataType.Date, value: new Date(2024, 0, 23), pipeArgs: { format: 'dd/MM/yyyy' }, expected: '23/01/2024' }, + { dataType: GridColumnDataType.Number, value: 0, pipeArgs: { digitsInfo: '1.2-2' }, expected: '0.00' }, + { dataType: GridColumnDataType.Percent, value: 0.25, pipeArgs: { digitsInfo: '1.1-1' }, expected: '25.0%' }, + { dataType: GridColumnDataType.Currency, value: 12.5, pipeArgs: { currencyCode: 'USD', digitsInfo: '1.2-2' }, expected: '$12.50' } + ].forEach(({ dataType, value, pipeArgs, expected }) => { + it(`Should format ${dataType} cells after leaving the editor in an uncommitted add row`, () => { + fixture.componentInstance.data = []; + const column = grid.getColumnByName('ContactName'); + column.dataType = dataType; + column.pipeArgs = pipeArgs; + fixture.detectChanges(); + + grid.beginAddRowById(null); + fixture.detectChanges(); + const cell = grid.gridAPI.get_cell_by_index(0, 'ContactName'); + expect(cell.nativeElement?.textContent.trim()).toBe('ContactName'); + + cell.setEditMode(true); + fixture.detectChanges(); + cell.editValue = value; + grid.gridAPI.get_cell_by_index(0, 'CompanyName').setEditMode(true); + fixture.detectChanges(); + + expect(grid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); + expect(cell.editMode).toBeFalse(); + expect(cell.value).toEqual(value); + expect(cell.nativeElement?.textContent.trim()).toBe(expected); + }); + }); + it('Should be able to enter add row mode on action strip click', () => { const row = grid.rowList.first; actionStrip.show(row); diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts index b1cc31bd3d0..b11a5f0c430 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts @@ -6,6 +6,7 @@ import { wait } from '../../../test-utils/ui-interactions.spec'; import { By } from '@angular/platform-browser'; import { IgxHierarchicalGridComponent } from './hierarchical-grid.component'; import { IgxGridNavigationService } from 'igniteui-angular/grids/core'; +import { GridColumnDataType } from 'igniteui-angular/core'; describe('IgxHierarchicalGrid - Add Row UI #tGrid', () => { let fixture; @@ -37,6 +38,29 @@ describe('IgxHierarchicalGrid - Add Row UI #tGrid', () => { _actionStrip = fixture.componentInstance.actionStrip; }); + it('Should format dates after leaving the editor in an uncommitted add row', () => { + const column = hierarchicalGrid.getColumnByName('ProductName'); + column.dataType = GridColumnDataType.Date; + column.pipeArgs = { format: 'dd/MM/yyyy' }; + fixture.componentInstance.data = []; + fixture.detectChanges(); + + hierarchicalGrid.beginAddRowById(null); + fixture.detectChanges(); + const cell = hierarchicalGrid.gridAPI.get_cell_by_index(0, 'ProductName'); + expect(cell.nativeElement?.textContent.trim()).toBe('ProductName'); + + cell.setEditMode(true); + fixture.detectChanges(); + cell.editValue = new Date(2024, 0, 23); + hierarchicalGrid.gridAPI.get_cell_by_index(0, 'ChildLevels').setEditMode(true); + fixture.detectChanges(); + + expect(hierarchicalGrid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); + expect(cell.editMode).toBeFalse(); + expect(cell.nativeElement?.textContent.trim()).toBe('23/01/2024'); + }); + it('Should collapse an expanded record when beginAddRow is called for it', () => { const row = hierarchicalGrid.rowList.first; hierarchicalGrid.expandRow(row.key); diff --git a/projects/igniteui-angular/grids/tree-grid/src/tree-cell.component.html b/projects/igniteui-angular/grids/tree-grid/src/tree-cell.component.html index 70ac5d9b5f4..c8676af1d4c 100644 --- a/projects/igniteui-angular/grids/tree-grid/src/tree-cell.component.html +++ b/projects/igniteui-angular/grids/tree-grid/src/tree-cell.component.html @@ -73,7 +73,19 @@ [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata">{{ - !isEmptyAddRowCell ? value : (column.header || column.field) + !isEmptyAddRowCell + ? (formatter + ? (value | columnFormatter:formatter:rowData) + : column.dataType === "number" + ? (value | number:column.pipeArgs.digitsInfo:grid.locale) + : (column.dataType === 'date' || column.dataType === 'time' || column.dataType === 'dateTime') + ? (value | date:column.pipeArgs.format:column.pipeArgs.timezone:grid.locale) + : column.dataType === 'currency' + ? (value | currency:currencyCode:column.pipeArgs.display:column.pipeArgs.digitsInfo:grid.locale) + : column.dataType === 'percent' + ? (value | percent:column.pipeArgs.digitsInfo:grid.locale) + : value) + : (column.header || column.field) }} } diff --git a/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts b/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts index 17e30376260..b9c9639c8b7 100644 --- a/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts +++ b/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts @@ -9,6 +9,7 @@ import { IgxTreeGridRowComponent } from './tree-grid-row.component'; import { first } from 'rxjs/operators'; import { wait } from '../../../test-utils/ui-interactions.spec'; import { IRowDataCancelableEventArgs } from 'igniteui-angular/grids/core'; +import { GridColumnDataType } from 'igniteui-angular/core'; describe('IgxTreeGrid - Add Row UI #tGrid', () => { let fix; @@ -39,6 +40,29 @@ describe('IgxTreeGrid - Add Row UI #tGrid', () => { actionStrip = fix.componentInstance.actionStrip; }); + it('should format dates after leaving the editor in an uncommitted add row', () => { + fix.componentInstance.data = []; + const column = treeGrid.getColumnByName('Name'); + column.dataType = GridColumnDataType.Date; + column.pipeArgs = { format: 'dd/MM/yyyy' }; + fix.detectChanges(); + + treeGrid.beginAddRowById(null); + fix.detectChanges(); + const cell = treeGrid.gridAPI.get_cell_by_index(0, 'Name'); + expect(cell.nativeElement?.textContent.trim()).toBe('Name'); + + cell.setEditMode(true); + fix.detectChanges(); + cell.editValue = new Date(2024, 0, 23); + treeGrid.gridAPI.get_cell_by_index(0, 'JobTitle').setEditMode(true); + fix.detectChanges(); + + expect(treeGrid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); + expect(cell.editMode).toBeFalse(); + expect(cell.nativeElement?.textContent.trim()).toBe('23/01/2024'); + }); + it('should show action strip "add row" button only for root level rows.', () => { actionStrip.show(treeGrid.rowList.first); fix.detectChanges(); diff --git a/src/app/grid-add-row/grid-add-row.sample.html b/src/app/grid-add-row/grid-add-row.sample.html index abd3b0fe7b3..b79ee0bbf09 100644 --- a/src/app/grid-add-row/grid-add-row.sample.html +++ b/src/app/grid-add-row/grid-add-row.sample.html @@ -5,7 +5,7 @@ [data]="data" [width]="'800px'" [height]="'500px'" - + [primaryKey]="'ID'" (mouseleave)="onMouseLeave(actionstrip)" (mouseover)="onMouseOver($event, grid, actionstrip)" [rowEditable]="true" From 443323e2ca1e4384d85ec9cd77efe661a148532d Mon Sep 17 00:00:00 2001 From: teodosiah Date: Wed, 21 Oct 2026 09:19:45 +0300 Subject: [PATCH 2/3] fix(grids): address copilot comments --- .../grids/grid/src/grid-add-row.spec.ts | 30 +++++++++++++++++-- .../src/hierarchical-grid-add-row.spec.ts | 4 +-- .../src/tree-grid-add-row-ui.spec.ts | 11 ++++--- src/app/grid-add-row/grid-add-row.sample.ts | 2 +- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts index 0ace12be450..95befbfe73d 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts @@ -88,8 +88,8 @@ describe('IgxGrid - Row Adding #grid', () => { grid.gridAPI.get_cell_by_index(0, 'CompanyName').setEditMode(true); fixture.detectChanges(); - expect(grid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); - expect(cell.editMode).toBeFalse(); + expect(grid.gridAPI.get_row_by_index(0).addRowUI).toBe(true); + expect(cell.editMode).toBe(false); expect(cell.value).toEqual(value); expect(cell.nativeElement?.textContent.trim()).toBe(expected); }); @@ -885,6 +885,32 @@ describe('IgxGrid - Row Adding #grid', () => { expect(row.expanded).toBeFalse(); expect(grid.gridAPI.get_row_by_index(1).addRowUI).toBeTrue(); }); + + it('Should format the expandable first column cell after leaving the editor in an uncommitted add row', () => { + grid.rowEditable = true; + fixture.componentInstance.data = []; + const column = grid.getColumnByName('ContactName'); + column.dataType = GridColumnDataType.Number; + column.pipeArgs = { digitsInfo: '1.2-2' }; + fixture.detectChanges(); + + grid.beginAddRowById(null); + fixture.detectChanges(); + const cell = grid.gridAPI.get_cell_by_index(0, 'ContactName'); + expect(cell.nativeElement?.tagName.toLowerCase()).toBe('igx-expandable-grid-cell'); + expect(cell.nativeElement?.querySelector('.igx-grid__td-text')?.textContent.trim()).toBe('ContactName'); + + cell.setEditMode(true); + fixture.detectChanges(); + cell.editValue = 0; + grid.gridAPI.get_cell_by_index(0, 'CompanyName').setEditMode(true); + fixture.detectChanges(); + + expect(grid.gridAPI.get_row_by_index(0).addRowUI).toBe(true); + expect(cell.editMode).toBe(false); + expect(cell.value).toBe(0); + expect(cell.nativeElement?.querySelector('.igx-grid__td-text')?.textContent.trim()).toBe('0.00'); + }); }); describe('Row Adding - MRL tests', () => { diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts index b11a5f0c430..c4888d62090 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid-add-row.spec.ts @@ -56,8 +56,8 @@ describe('IgxHierarchicalGrid - Add Row UI #tGrid', () => { hierarchicalGrid.gridAPI.get_cell_by_index(0, 'ChildLevels').setEditMode(true); fixture.detectChanges(); - expect(hierarchicalGrid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); - expect(cell.editMode).toBeFalse(); + expect(hierarchicalGrid.gridAPI.get_row_by_index(0).addRowUI).toBe(true); + expect(cell.editMode).toBe(false); expect(cell.nativeElement?.textContent.trim()).toBe('23/01/2024'); }); diff --git a/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts b/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts index b9c9639c8b7..4b210a0a4e1 100644 --- a/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts +++ b/projects/igniteui-angular/grids/tree-grid/src/tree-grid-add-row-ui.spec.ts @@ -42,6 +42,8 @@ describe('IgxTreeGrid - Add Row UI #tGrid', () => { it('should format dates after leaving the editor in an uncommitted add row', () => { fix.componentInstance.data = []; + treeGrid.getColumnByName('ID').hidden = true; + treeGrid.getColumnByName('ParentID').hidden = true; const column = treeGrid.getColumnByName('Name'); column.dataType = GridColumnDataType.Date; column.pipeArgs = { format: 'dd/MM/yyyy' }; @@ -50,7 +52,8 @@ describe('IgxTreeGrid - Add Row UI #tGrid', () => { treeGrid.beginAddRowById(null); fix.detectChanges(); const cell = treeGrid.gridAPI.get_cell_by_index(0, 'Name'); - expect(cell.nativeElement?.textContent.trim()).toBe('Name'); + expect(cell.nativeElement?.tagName.toLowerCase()).toBe('igx-tree-grid-cell'); + expect(cell.nativeElement.querySelector('.igx-grid__td-text').textContent.trim()).toBe('Name'); cell.setEditMode(true); fix.detectChanges(); @@ -58,9 +61,9 @@ describe('IgxTreeGrid - Add Row UI #tGrid', () => { treeGrid.gridAPI.get_cell_by_index(0, 'JobTitle').setEditMode(true); fix.detectChanges(); - expect(treeGrid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue(); - expect(cell.editMode).toBeFalse(); - expect(cell.nativeElement?.textContent.trim()).toBe('23/01/2024'); + expect(treeGrid.gridAPI.get_row_by_index(0).addRowUI).toBe(true); + expect(cell.editMode).toBe(false); + expect(cell.nativeElement.querySelector('.igx-grid__td-text').textContent.trim()).toBe('23/01/2024'); }); it('should show action strip "add row" button only for root level rows.', () => { diff --git a/src/app/grid-add-row/grid-add-row.sample.ts b/src/app/grid-add-row/grid-add-row.sample.ts index f436435263c..52c166abb44 100644 --- a/src/app/grid-add-row/grid-add-row.sample.ts +++ b/src/app/grid-add-row/grid-add-row.sample.ts @@ -76,7 +76,7 @@ export class GridAddRowSampleComponent implements OnInit { } public add() { - this.grid.addRow({ ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative'}); + this.grid.addRow({ ID: 'TEST', CompanyName: 'Test Company Name', ContactName: 'Test Contact Name', ContactTitle: 'Test Title'}); } public beginAddRowAtIndex(index: string) { From de3d14fb332c98c5c77c9985af703fd3b44c1b08 Mon Sep 17 00:00:00 2001 From: teodosiah Date: Wed, 21 Oct 2026 15:45:19 +0300 Subject: [PATCH 3/3] fix(grids): show zero in master-detail add row cell --- .../grids/grid/src/expandable-cell.component.html | 2 +- src/app/grid-add-row/grid-add-row.sample.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html index 2ad60d25e9e..9022907df91 100644 --- a/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html +++ b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html @@ -61,7 +61,7 @@ [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata"> - {{ value + {{ !isEmptyAddRowCell ? (formatter ? (value | columnFormatter:formatter:rowData:columnData) : column.dataType === "number" diff --git a/src/app/grid-add-row/grid-add-row.sample.ts b/src/app/grid-add-row/grid-add-row.sample.ts index 52c166abb44..636b4cd556e 100644 --- a/src/app/grid-add-row/grid-add-row.sample.ts +++ b/src/app/grid-add-row/grid-add-row.sample.ts @@ -76,7 +76,12 @@ export class GridAddRowSampleComponent implements OnInit { } public add() { - this.grid.addRow({ ID: 'TEST', CompanyName: 'Test Company Name', ContactName: 'Test Contact Name', ContactTitle: 'Test Title'}); + let id = 'TEST'; + let suffix = 1; + while (this.data.some(row => row.ID === id)) { + id = `TEST${suffix++}`; + } + this.grid.addRow({ ID: id, CompanyName: 'Test Company Name', ContactName: 'Test Contact Name', ContactTitle: 'Test Title'}); } public beginAddRowAtIndex(index: string) {