I am using Angular 11 and 2020-Dec IG build.
My grid has a column of Name (string) and a column of Type (dropdown of static string-type choices). The validation of Name is based on Type and a regex that looks like this: /^PLAN\_[0-9]{4}\_[0-9]{2}[a-zA-Z0-9\_]{0,39}$/
"PLAN" is one of many prefixes that align with specific types and are not interchangeable.
What I need is a dynamically appearing warning about the Name not properly validating and prevention of submission by either click or enter keypress. I intend to have a warning snackbar floating in the upper right corner of the grid (zindex = 999), a warning span in the igxRowEditText area, and the "done" button in the igxRowEditActions area disabled until the Name matches the correct format.
I am finding that (onCellEdit) is not working for me, neither is (keypress) or (input) on my template for the column.
HTML template for Name and igxRowEditText:
<ng-template igxRowEditText> <span class="error" *ngIf="badName">{{badNameWarning}}</span> </ng-template> <igx-column [pinned]="true" field="name" header="Scenario Name" [dataType]="'string'" [resizable]="true" width="246px" [sortable]="true"> <ng-template igxCellEditor let-cell="cell"> <igx-input-group> <input igxInput [igxFocus]="true" name="ScenarioName" [(ngModel)]="cell.editValue" (keypress)="validateName(cell.editValue, cell.scenarioType)"> </igx-input-group> </ng-template> </igx-column>
Handling in my Component:
//validation badName:boolean = false; badNameWarning:string = ''; validateName(scenName:string, type:string) { let prefix:string = ''; this.badName = false; if (type == 'Commit' && !/^PLAN\_[0-9]{4}\_[0-9]{2}[a-zA-Z0-9\_]{0,39}$/.test(scenName)) { this.badName = true, prefix = 'PLAN'; } ...else if (type == ...types this.badNameWarning = `${type} Name should be: ${prefix}_YYYY_WW(optional [a-z,A-Z,0-9,-,_] to 50 total)`; };
Your latest sample prevents updating the other column when the value in the one you're editing doesn't match validation. This is not what I wanted. I will have to reassign values to the Combo to ensure the data that hasn't changed is still persisted.
let type:string = this.types.indexOf(event[0]) > -1 ? event[0] : cell.rowData.scenarioType, …
I cannot tell what has changed to affect retaining the value.
Here is what I currently have for my column with a dropdown (not retaining value upon dropdown):
<igx-column field="scenarioType" header="Type" [dataType]="'string'" [resizable]="true" width="83px" [sortable]="true"> <ng-template igxCell let-cell="cell">{{cell.value}}</ng-template> <ng-template igxCellEditor let-cell="cell" let-value> <igx-combo [(ngModel)]="cell.editValue" (ngModelChange)="modelChange($event, cell)" [data]="types" width="220px" [igxFocus]="true" (onSelectionChange)="singleSelection($event)" [overlaySettings]="customOverlaySettings"></igx-combo> </ng-template> </igx-column>
A further frustration I've overcome is the use of @ViewChild with *ngIf in the grid. I figured out for myself that you need @ViewChildren when your component reference is gated by a conditional, which mine is due to asynchronously loading the list of Scenarios.
Here is what I have in the component.ts for this:
@ViewChildren('scenarioList', { read: IgxGridComponent }) public scenarioList: IgxGridComponent; customOverlaySettings:OverlaySettings; types:string[] = []; ngOnInit(): void { this.getScenarios(); this.getScenarioTypes(); //sets values to types:string[] this.getHorizons(); this.getWorkweeks(); } ngAfterViewInit() { this.customOverlaySettings = { outlet: this.scenarioList.outlet }; } modelChange(event:any, cell:IgxGridCellComponent) { if (this.inputSubscription) { this.inputSubscription.unsubscribe(); } let type:string = this.types.indexOf(event[0]) > -1 ? event[0] : cell.rowData.scenarioType, prefix:string = ''; this.inputSubscription = of(event).pipe(delay(500), distinctUntilChanged()) .subscribe(eventVal => { if (type == 'Commit' && !/^PLAN\_[0-9]{4}\_[0-9]{2}[a-zA-Z0-9\_\-]{0,38}$/.test(eventVal)) { this.badName = true; prefix = 'PLAN'; } else if (type == 'Scenario' && !/^BETA\_[0-9]{4}\_[0-9]{2}[a-zA-Z0-9\_\-]{0,38}$/.test(eventVal)) { this.badName = true; prefix = 'BETA'; } else if (type == 'LRP' && !/^LRP\_[0-9]{4}\_[0-9]{2}[a-zA-Z0-9\_\-]{0,39}$/.test(eventVal)) { this.badName = true; prefix = 'LRP'; } else { this.badName = false; } this.badNameWarning = prefix !== '' ? `${type} Name should be: ${prefix}_YYYY_WW(optional [a-z,A-Z,0-9,-,_] to 50 total)` : ''; }); }; singleSelection(event: IComboSelectionChangeEventArgs) { if (event.added.length) { event.newSelection = event.added; } };
I only filled out for the first 3 scenario types, but I assume it makes sense for the whole group. Validation is applied whether the Scenario Name or Type is changed. That portion is working like a charm and I am saving the Toast/ToolTip for save responses on the attributes of Scenario.
Regardless, the dropdown doesn't persist the populated scenario type when opened: no value is currently selected.
Hello Chris,
I am glad that the suggestion about the compilerOptions helps.
To address your question about the IgxCombo, I have modified the previous sample to correct this behavior. For additional information regarding the IgxCombo, please refer to its dedicated page in our documentation.
Since your initial question was not about the IgxCombo, I am not familiar with your requirements and created the “Category” column in the sample’s grid just for demo purposes. For example, under the assumption that only single item can be selected at a time, the approach shown here is applied. The most important aspect (that was causing the initially described behavior) is that the IgxCombo’s value has to be bound to a list (e.g. array). Even if your column’s value is a single string, please, make sure to have it contained within an array. Another sample, showing multiple selection for a combo, contained within an IgxGrid can be found in the Grid cell editing topic here.
By the way, have you had the chance to implement the cell validation? Please, keep me posted on your progress.
Best regards,Bozhidara PachilovaAssociate Software Developer