diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cd962b625b..8fac8cf1c3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes for each version of this project will be documented in this - `IgxGridComponent`, `IgxTreeGridComponent`, `IgxHierarchicalGridComponent` - Excel-style filtering now preselects custom conditions in the filter dialog when no filter value has been entered yet. + - Cells in an uncommitted new row now apply column formatting after leaving the cell editor, while empty cells retain their column-header placeholders. ## 22.2.3 diff --git a/projects/igniteui-angular/grids/core/src/cell.component.html b/projects/igniteui-angular/grids/core/src/cell.component.html index 7764bc012d8..c8478205197 100644 --- a/projects/igniteui-angular/grids/core/src/cell.component.html +++ b/projects/igniteui-angular/grids/core/src/cell.component.html @@ -128,7 +128,30 @@ [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/grid/src/expandable-cell.component.html b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html index 30ac3ff452e..1e4b688f1b8 100644 --- a/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html +++ b/projects/igniteui-angular/grids/grid/src/expandable-cell.component.html @@ -134,7 +134,30 @@ [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata" > - {{ value ? 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/grid/src/grid-add-row.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts index 566dafa6e3f..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 @@ -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).toBe(true); + expect(cell.editMode).toBe(false); + 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); @@ -854,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 f9d6b86f83c..66625842731 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 #hGrid', () => { let fixture; @@ -37,6 +38,29 @@ describe('IgxHierarchicalGrid - Add Row UI #hGrid', () => { _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).toBe(true); + expect(cell.editMode).toBe(false); + 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 5307822ece4..31b7df4c020 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 @@ -126,7 +126,30 @@ [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 c6d2d2a8906..4dec1984ffe 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,32 @@ 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 = []; + 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' }; + fix.detectChanges(); + + treeGrid.beginAddRowById(null); + fix.detectChanges(); + const cell = treeGrid.gridAPI.get_cell_by_index(0, '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(); + 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).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.', () => { 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" 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 4a2caa04259..f294f8b3e76 100644 --- a/src/app/grid-add-row/grid-add-row.sample.ts +++ b/src/app/grid-add-row/grid-add-row.sample.ts @@ -77,7 +77,12 @@ export class GridAddRowSampleComponent implements OnInit { } public add() { - this.grid.addRow({ ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative'}); + 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) {