Skip to content
Open
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ All notable changes for each version of this project will be documented in this

### Bug Fixes

- `IgxGridComponent`, `IgxTreeGridComponent`, `IgxHierarchicalGridComponent`
- Cells in an uncommitted new row now apply column formatting after leaving the cell editor, while empty cells retain their column-header placeholders.
- **Forms**
- `igx-checkbox`, `igx-switch` and `igx-radio-group` no longer turn invalid while the bound Signal Forms field is untouched and pristine, e.g. right after `reset()` or when a cross-field rule makes a pristine field required. The invalid state now shows only once the field is touched or dirty, as with reactive and template-driven forms.
- `IgxAccordionComponent`
- When `singleBranchExpand` is set initially and the panels are rendered with `@for`, the panels collapsed on init no longer keep `aria-expanded="true"` and no `ExpressionChangedAfterItHasBeenCheckedError` is thrown in development mode.
- `IgxCarouselComponent`
Expand Down
25 changes: 24 additions & 1 deletion projects/igniteui-angular/grids/core/src/cell.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
</div>
}
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,30 @@
[containerClass]="'igx-grid__td-text'"
[metadata]="searchMetadata"
>
{{ value ? value : column.header || column.field }}
{{ !isEmptyAddRowCell
? (formatter
? (value | columnFormatter: formatter : rowData)
Comment thread
teodosiah marked this conversation as resolved.
: 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 }}
</div>
}
</ng-template>
Expand Down
59 changes: 58 additions & 1 deletion projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { advance, useFakeClock } from '../../../test-utils/helper-utils.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';
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { DefaultGridMasterDetailComponent, ColumnLayoutTestComponent } from '../../../test-utils/grid-shared-components.spec';
Expand Down Expand Up @@ -66,6 +66,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);
Expand Down Expand Up @@ -928,6 +959,32 @@ describe('IgxGrid - Row Adding #grid', () => {
expect(row.expanded).toBe(false);
expect(grid.gridAPI.get_row_by_index(1).addRowUI).toBe(true);
});

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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
import { describe, it, expect, beforeEach } from 'vitest';

describe('IgxHierarchicalGrid - Add Row UI #hGrid', () => {
Expand Down Expand Up @@ -38,6 +39,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
</div>
}
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
import { describe, it, expect, beforeEach, vi } from 'vitest';

describe('IgxTreeGrid - Add Row UI #tGrid', () => {
Expand Down Expand Up @@ -40,6 +41,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');
Comment thread
Copilot marked this conversation as resolved.
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();
Expand Down
2 changes: 1 addition & 1 deletion src/app/grid-add-row/grid-add-row.sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[data]="data"
[width]="'800px'"
[height]="'500px'"

[primaryKey]="'ID'"
Comment thread
teodosiah marked this conversation as resolved.
(mouseleave)="onMouseLeave(actionstrip)"
(mouseover)="onMouseOver($event, grid, actionstrip)"
[rowEditable]="true"
Expand Down
7 changes: 6 additions & 1 deletion src/app/grid-add-row/grid-add-row.sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.grid.data.some(record => record.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) {
Expand Down
Loading