Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: IgniteUI/igniteui-angular
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 14.2.3
Choose a base ref
...
head repository: IgniteUI/igniteui-angular
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 14.2.4
Choose a head ref

Commits on Sep 13, 2022

  1. chore(*): Sync editValue changes with the formControl value and mark …

    …as touched for better custom template handling.
    MKirova authored and MKirova committed Sep 13, 2022

    Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    suzuki-shunsuke Shunsuke Suzuki
    Copy the full SHA
    e0e299a View commit details
  2. chore(*): Add some custom edit template tests.

    MKirova authored and MKirova committed Sep 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    91d0fb1 View commit details
  3. chore(*): Simplify and fix tests due to reused data object.

    MKirova authored and MKirova committed Sep 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    c935538 View commit details

Commits on Sep 14, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    1478c5b View commit details

Commits on Sep 16, 2022

  1. chore(*): Get/Set editValue from/to formControl value.

    MKirova authored and MKirova committed Sep 16, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    3a6c058 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    58ddf50 View commit details
  3. chore(*): Emit events first before reseting to old value on cancel.

    MKirova authored and MKirova committed Sep 16, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    03384c0 View commit details

Commits on Sep 19, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    6fe51ec View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    2d8e5b7 View commit details
  3. chore(*): Ensure when trigger is blur it triggers validation only aft…

    …er cell exits edit mode.
    MKirova authored and MKirova committed Sep 19, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    1e7ff45 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    5874dd9 View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    5713a5d View commit details
  6. Copy the full SHA
    405f924 View commit details
  7. chore(*): Use a intermediate pending value when trigger is blur.

    MKirova authored and MKirova committed Sep 19, 2022
    Copy the full SHA
    6320cac View commit details
  8. Copy the full SHA
    bd277ad View commit details

Commits on Sep 20, 2022

  1. chore(*): Fix tests.

    MKirova authored and MKirova committed Sep 20, 2022
    Copy the full SHA
    7e17d7a View commit details

Commits on Sep 21, 2022

  1. chore(*): Detect changes before opening tootip to ensure it has been …

    …initialized.
    MKirova authored and MKirova committed Sep 21, 2022
    Copy the full SHA
    54f0f74 View commit details

Commits on Sep 27, 2022

  1. fix(excel-exporter): export correct number of rows#12086 (#12121)

    * fix(excel-exporter): export correct number of rows#12086
    
    * fix(excel-exporter): fix total rowCount with multi col headers#12086
    
    * fix(excel-exporter): fix spacing#12086
    georgianastasov authored Sep 27, 2022
    Copy the full SHA
    6012f3f View commit details
  2. Copy the full SHA
    a1e542c View commit details

Commits on Sep 28, 2022

  1. chore(*): Fix issue with grid's updateCell api.

    MKirova authored and MKirova committed Sep 28, 2022
    Copy the full SHA
    3252cc1 View commit details

Commits on Sep 29, 2022

  1. chore(*): Prevent marking as touched for initial value of cell.

    MKirova authored and MKirova committed Sep 29, 2022
    Copy the full SHA
    49c1b52 View commit details
  2. chore(*): Add back explicit markAsTouched on formControl valueChanges…

    … for the tests.
    MKirova authored and MKirova committed Sep 29, 2022
    Copy the full SHA
    83650c8 View commit details
  3. chore(*): Ensure correct value is set on create.

    MKirova authored and MKirova committed Sep 29, 2022
    Copy the full SHA
    9872f01 View commit details

Commits on Oct 17, 2022

  1. chore(*): Merge from base.

    MKirova authored and MKirova committed Oct 17, 2022
    Copy the full SHA
    a9d1736 View commit details

Commits on Oct 26, 2022

  1. Copy the full SHA
    e7e6440 View commit details
  2. Merge pull request #12076 from IgniteUI/mkirova/editValue-formControl…

    …-auto-sync
    
    chore(*): Sync editValue changes with the formControl value and mark …
    dkamburov authored Oct 26, 2022
    Copy the full SHA
    64fff25 View commit details
6 changes: 3 additions & 3 deletions projects/igniteui-angular/src/lib/grids/cell.component.ts
Original file line number Diff line number Diff line change
@@ -871,11 +871,11 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT
*/
public ngOnChanges(changes: SimpleChanges): void {
if (changes.editMode && changes.editMode.currentValue && this.formControl) {
// while in edit mode subscribe to value changes on the current form control and set to editValue
// ensure when values change, form control is forced to be marked as touche.
this.formControl.valueChanges.pipe(takeWhile(x => this.editMode)).subscribe(value => {
this.editValue = value;
this.formControl.markAsTouched();
});
// while in edit mode subscribe to value changes on the current form control and set to editValue
this.formControl.statusChanges.pipe(takeWhile(x => this.editMode)).subscribe(status => {
if (status === 'INVALID' && this.errorTooltip.length > 0) {
this.cdr.detectChanges();
@@ -948,7 +948,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT
cell = this.grid.crudService.createCell(this);
}
cell.editValue = val;
this.formControl.setValue(val);
this.grid.gridAPI.update_cell(cell);
this.grid.crudService.endCellEdit();
this.cdr.markForCheck();
@@ -1060,6 +1059,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT

const isTargetErrorIcon = event && event.target && event.target === this.errorIcon?.el.nativeElement
if (this.isInvalid && !isTargetErrorIcon) {
this.cdr.detectChanges();
this.openErrorTooltip();
this.grid.activeNodeChange.pipe(first()).subscribe(() => {
this.closeErrorTooltip();
33 changes: 30 additions & 3 deletions projects/igniteui-angular/src/lib/grids/common/crud.service.ts
Original file line number Diff line number Diff line change
@@ -91,18 +91,38 @@ export interface IgxAddRowParent {
export class IgxCell {
public primaryKey: any;
public state: any;
public pendingValue: any;

constructor(
public id,
public rowIndex: number,
public column,
public value: any,
public editValue: any,
public _editValue: any,
public rowData: any,
public grid: GridType) {
this.grid.validation.create(id.rowID, rowData);
}

public get editValue() {
const formControl = this.grid.validation.getFormControl(this.id.rowID, this.column.field);
if (formControl) {
return formControl.value;
}
}

public set editValue(value) {
const formControl = this.grid.validation.getFormControl(this.id.rowID, this.column.field);

if (this.grid.validationTrigger === 'change') {
// in case trigger is change, mark as touched.
formControl.setValue(value);
formControl.markAsTouched();
} else {
this.pendingValue = value;
}
}

public castToNumber(value: any): any {
if (this.column.dataType === 'number' && !this.column.inlineEditorTemplate) {
const v = parseFloat(value);
@@ -201,6 +221,13 @@ export class IgxCellCrudState {
return;
}

const formControl = this.grid.validation.getFormControl(this.cell.id.rowID, this.cell.column.field);
if (this.grid.validationTrigger === 'blur' && this.cell.pendingValue !== undefined) {
// in case trigger is blur, update value if there's a pending one and mark as touched.
formControl.setValue(this.cell.pendingValue);
formControl.markAsTouched();
}

if (this.grid.validationTrigger === 'blur') {
this.grid.tbody.nativeElement.focus({ preventScroll: true });
}
@@ -245,12 +272,12 @@ export class IgxCellCrudState {
const args = this.cell?.createDoneEditEventArgs(newValue, event);

this.cell.value = newValue;

this.grid.cellEditExit.emit(args);
this.endCellEdit();
return args;
}


/** Clears cell editing state */
public endCellEdit() {
this.cell = null;
@@ -647,11 +674,11 @@ export class IgxGridCRUDService extends IgxRowAddCrudState {
return args.cancel;
}
} else {
this.exitCellEdit(event);
if (!this.grid.rowEditable && this.cell) {
const value = this.grid.transactions.getAggregatedValue(this.cell.id.rowID, true) || this.cell.rowData;
this.grid.validation.update(this.cell.id.rowID, value);
}
this.exitCellEdit(event);
}

args = this.updateRow(commit, event);
Original file line number Diff line number Diff line change
@@ -4545,6 +4545,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
};

const cell = new IgxCell(id, index, col, rowData[col.field], value, rowData, this as any);
const formControl = this.validation.getFormControl(cell.id.rowID, cell.column.field);
formControl.setValue(value);
this.gridAPI.update_cell(cell);
this.cdr.detectChanges();
}
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ export class IgxGridValidationService {
const value = resolveNestedPath(data || {}, col.field);
const field = this.getFieldKey(col.field);
const control = new FormControl(value, { updateOn: this.grid.validationTrigger });
control.setValue(value);
control.addValidators(col.validators);
formGroup.addControl(field, control);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { FormGroup, Validators } from '@angular/forms';
import { FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxInputDirective, IgxTooltipTargetDirective, IgxTreeGridComponent, IgxTreeGridModule } from 'igniteui-angular';
@@ -9,6 +9,7 @@ import { configureTestSuite } from '../../test-utils/configure-suite';
import { GridFunctions, GridSelectionFunctions } from '../../test-utils/grid-functions.spec';
import {
ForbiddenValidatorDirective,
IgxGridCustomEditorsComponent,
IgxGridValidationTestBaseComponent,
IgxGridValidationTestCustomErrorComponent,
IgxTreeGridValidationTestComponent
@@ -25,10 +26,11 @@ describe('IgxGrid - Validation #grid', () => {
declarations: [
IgxGridValidationTestBaseComponent,
IgxGridValidationTestCustomErrorComponent,
IgxGridCustomEditorsComponent,
IgxTreeGridValidationTestComponent,
ForbiddenValidatorDirective
],
imports: [IgxGridModule, IgxTreeGridModule, NoopAnimationsModule]
imports: [IgxGridModule, IgxTreeGridModule, NoopAnimationsModule, ReactiveFormsModule]
});
}));

@@ -316,6 +318,82 @@ describe('IgxGrid - Validation #grid', () => {
});
});

describe('Custom Editor Templates - ', () => {
let fixture;

beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(IgxGridCustomEditorsComponent);
fixture.componentInstance.grid.batchEditing = true;
fixture.detectChanges();
}));

it('should trigger validation on change when using custom editor bound via formControl.', () => {
// template bound via formControl
const template = fixture.componentInstance.formControlTemplate;
const grid = fixture.componentInstance.grid as IgxGridComponent;
const col = grid.columns[1];
col.inlineEditorTemplate = template;
fixture.detectChanges();

let cell = grid.gridAPI.get_cell_by_visible_index(1, 1);
UIInteractions.simulateDoubleClickAndSelectEvent(cell.element);
const input = fixture.debugElement.query(By.css('input'));
UIInteractions.clickAndSendInputElementValue(input, 'bob');
fixture.detectChanges();

GridFunctions.verifyCellValid(cell, false);
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
});

it('should trigger validation on change when using custom editor bound via editValue.', () => {
// template bound via ngModel to editValue
const template = fixture.componentInstance.modelTemplate;
const grid = fixture.componentInstance.grid as IgxGridComponent;
const col = grid.columns[1];
col.inlineEditorTemplate = template;
fixture.detectChanges();

let cell = grid.gridAPI.get_cell_by_visible_index(1, 1);
UIInteractions.simulateDoubleClickAndSelectEvent(cell.element);
const input = fixture.debugElement.query(By.css('input'));
UIInteractions.clickAndSendInputElementValue(input, 'bob');
fixture.detectChanges();

GridFunctions.verifyCellValid(cell, false);
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
});

it('should trigger validation on blur when using custom editor bound via editValue.', () => {
// template bound via ngModel to editValue
const template = fixture.componentInstance.modelTemplate;
const grid = fixture.componentInstance.grid as IgxGridComponent;
const col = grid.columns[1];
col.inlineEditorTemplate = template;
grid.validationTrigger = 'blur';
fixture.detectChanges();

let cell = grid.gridAPI.get_cell_by_visible_index(1, 1);
UIInteractions.simulateDoubleClickAndSelectEvent(cell.element);
const input = fixture.debugElement.query(By.css('input'));
UIInteractions.clickAndSendInputElementValue(input, 'bob');
fixture.detectChanges();

// invalid value is entered, but no blur has happened yet.
// Hence validation state is still valid.
GridFunctions.verifyCellValid(cell, true);
expect(cell.errorTooltip.length).toBe(0);

// exit edit mode
grid.crudService.endEdit(true);
fixture.detectChanges();
GridFunctions.verifyCellValid(cell, false);
const erorrMessage = cell.errorTooltip.first.elementRef.nativeElement.children[0].textContent;
expect(erorrMessage).toEqual(' Entry should be at least 4 character(s) long ');
});
});

describe('Transactions integration - ', () => {
let fixture;

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input, ViewChild, Directive } from '@angular/core';
import { Component, Input, ViewChild, Directive, TemplateRef } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { IgxGridComponent, IgxTreeGridComponent } from 'igniteui-angular';
import { data } from '../../../../../src/app/shared/data';
@@ -82,6 +82,32 @@ export class IgxGridValidationTestCustomErrorComponent {
@ViewChild('grid', { read: IgxGridComponent, static: true }) public grid: IgxGridComponent;
}

@Component({
template: `
<igx-grid #grid primaryKey="ProductID" [data]="data" [rowEditable]="rowEditable"
[width]="'1200px'" [height]="'800px'">
<igx-column igxAppForbiddenName='bob' minlength="4" maxlength='8' required
*ngFor="let c of columns"
[editable]='true' [sortable]="true" [filterable]="true" [field]="c.field"
[header]="c.field" [width]="c.width" [resizable]='true' [dataType]="c.dataType">
</igx-column>
</igx-grid>
<ng-template #modelTemplate igxCellEditor let-cell="cell">
<input [(ngModel)]="cell.editValue"/>
</ng-template>
<ng-template #formControlTemplate igxCellEditor let-cell="cell" let-fc='formControl'>
<input [formControl]="fc"/>
</ng-template>
`
})
export class IgxGridCustomEditorsComponent extends IgxGridValidationTestCustomErrorComponent {
@ViewChild('modelTemplate', {read: TemplateRef })
public modelTemplate: TemplateRef<any>;

@ViewChild('formControlTemplate', {read: TemplateRef })
public formControlTemplate: TemplateRef<any>;
}

@Component({
template: `
<igx-tree-grid #treeGrid [data]="data" childDataKey="Employees" primaryKey="ID"
3 changes: 3 additions & 0 deletions src/app/grid-validation/grid-validation.sample.component.html
Original file line number Diff line number Diff line change
@@ -11,6 +11,9 @@ <h4>Grid without transactions</h4>
</igx-column>
<igx-column field='ProductID' [editable]='false'></igx-column>
<igx-column field='ProductName' appForbiddenName='bob' required [editable]='true'>
<ng-template igxCellEditor let-cell="cell" let-value let-fc='formControl'>
<input [(ngModel)]="cell.editValue"/>
</ng-template>
<ng-template igxCellValidationError let-cell='cell' let-defaultErr='defaultErrorTemplate'>
<ng-container *ngTemplateOutlet="defaultErr" >
</ng-container>