How do I validate that a mat-chip
has been added to the mat-chip-list
. I am using ReactiveForms. I have tried with the required
validator.
The value can be a list of names, so I need to make sure that there is atleast 1 name in my list of names before I can submit the form. If the list is empty then mat-error
should display the error message. Using the required
validator makes the form invalid, regardless of adding names to the list.
EDIT: Reactive Forms
I have tried to make a custom validator, and I am now using Reactive Forms instead of Template driven forms, but I cannot get it to work. I have edited the below code to reflect my changes and I have created this https://stackblitz.com/edit/angular-4d5vfj
HTML
<form [formGroup]="myForm">
<mat-form-field class="example-chip-list">
<mat-chip-list #chipList formArrayName="names">
<mat-chip *ngFor="let name of myForm.get('names').controls; let i=index;"
[formGroupName]="i"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(myForm, i)">
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input placeholder="Names"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event, asset)">
</mat-chip-list>
<mat-error>Atleast 1 name need to be added</mat-error>
</mat-form-field>
</form>
TS
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {Component} from '@angular/core';
import {FormGroup, FormControl, FormBuilder, FormArray} from '@angular/forms';
import {MatChipInputEvent} from '@angular/material';
@Component({
selector: 'chip-list-validation-example',
templateUrl: 'chip-list-validation-example.html',
styleUrls: ['chip-list-validation-example.css'],
})
export class ChipListValidationExample {
public myForm: FormGroup;
// name chips
visible = true;
selectable = true;
removable = true;
addOnBlur = true;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
// data
data = {
names: ['name1', 'name2']
}
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
names: this.fb.array(this.data.names, this.validateArrayNotEmpty)
});
}
initName(name: string): FormControl {
return this.fb.control(name);
}
validateArrayNotEmpty(c: FormControl) {
if (c.value && c.value.length === 0) {
return {
validateArrayNotEmpty: { valid: false }
};
}
return null;
}
add(event: MatChipInputEvent, form: FormGroup): void {
const input = event.input;
const value = event.value;
// Add name
if ((value || '').trim()) {
const control = <FormArray>form.get('names');
control.push(this.initName(value.trim()));
console.log(control);
}
// Reset the input value
if (input) {
input.value = '';
}
}
remove(form, index) {
console.log(form);
form.get('names').removeAt(index);
}
}
The problem is that the chipList's errorState
isn't set to true
when the chipList's FormArray
status is INVALID
.
I'm facing the same problem and don't know why this isn't working out of the box or how this can be achieved implicitly with the chipList's form being a FormArray
.
As a workaround you can listen to status changes from the FormArray
and set the chipList's errorState
manually:
@ViewChild('chipList') chipList: MatChipList;
ngOnInit() {
this.myForm.get('names').statusChanges.subscribe(
status => this.chipList.errorState = status === 'INVALID'
);
}
https://stackblitz.com/edit/angular-4d5vfj-gywxjz
To be able to get the validation working on a mat-chip-list
we have to bind both the mat-input
and mat-chip-list
with same FormControl
like below
Working Stackblitz link here
<form [formGroup]='group'>
<mat-form-field class="example-chip-list">
<mat-chip-list #chipList
required
formControlName="newFruit">
<mat-chip *ngFor="let fruit of fruits"
(removed)="remove(fruit)">
{{fruit.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input placeholder="New fruit..."
formControlName="newFruit"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)" required>
</mat-chip-list>
<!-- add mat-error -->
<mat-error *ngIf="group.controls.newFruit.hasError('required')">required!</mat-error>
</mat-form-field>
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With