Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Required input in form mat-chip-list in Angular 2+

I create a basic form with angular 6. There are some inputs and I use "required" in order to display an error message and disabled the submit button.

Here it is:

<form (ngSubmit)="submit()" #myForm="ngForm">
  <div id="iterationField" class="col-sm-5">
    <h6>Iterations to calculate performance</h6>
    <mat-form-field>
      <input matInput type="number" id="iter" required [(ngModel)]="iteration" name="iter" #iter="ngModel" min="1">
    </mat-form-field>
    <div *ngIf="iter.invalid && (iter.dirty || iter.touched)" class="alert alert-danger">
      Iteration is required
    </div>
  </div>

  <button type="submit" color="primary" [disabled]="!myForm.form.valid">Submit</button>
</form>

This works properly. Now what I am trying to do is to add the angular material chip-list. Following the documentation and the example I have this:

        <div id="costField">
          <mat-form-field class="full-width">
            <mat-chip-list #chipCostList>
              <mat-chip *ngFor="let item of svr.cost" [selectable]="selectable" [removable]="removable" (removed)="remove(item, 'cost')">
                {{item}}
                <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
              </mat-chip>
              <input placeholder="Cost" [matChipInputFor]="chipCostList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
                (matChipInputTokenEnd)="add($event, 'cost')" [(ngModel)]="costValue" #cost="ngModel" name="cost" required>
            </mat-chip-list>
          </mat-form-field>
          <div *ngIf="cost.invalid && (cost.dirty || cost.touched)" class="alert alert-danger">
            Cost is required
          </div>
        </div>

However, this doesn't work. I have no error message. I tried to add required in the mat-chip-list element but it doesn't work neither. I reproduced a similar example on Stackblitz.

The chips and the input are not linked. I mean the input doesn't recognise the chips. So if you just click on the fruit input and then click next to it. The error message will appear whereas there are some chips already inside.

How can I make it work ?

like image 853
PierBJX Avatar asked Oct 18 '25 04:10

PierBJX


1 Answers

I know this question is old, but I came across it while facing this issue myself, so figured I'd share the solution that I found as well.

When using mat-chip-list (or mat-chip-grid in newer Angular) with input, the required has to go on the mat-chip-list instead of the input. So for your code:

<div id="costField">
  <mat-form-field class="full-width">
    <mat-chip-list #chipCostList required> <!-- <---------- -->
      <mat-chip *ngFor="let item of svr.cost" [selectable]="selectable" [removable]="removable" (removed)="remove(item, 'cost')">
        {{item}}
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>
      <input placeholder="Cost" [matChipInputFor]="chipCostList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
        (matChipInputTokenEnd)="add($event, 'cost')" [(ngModel)]="costValue" #cost="ngModel" name="cost">
    </mat-chip-list>
  </mat-form-field>
  <div *ngIf="cost.invalid && (cost.dirty || cost.touched)" class="alert alert-danger">
    Cost is required
  </div>
</div>

If you are using the chip list input inside a form group, the form control will also go on the mat-chip-list/mat-chip-grid element, and in the callback you give to matChipInputTokenEnd you need to set the form control value e.g.

<div id="costField">
  <mat-form-field class="full-width">
    <mat-chip-list #chipCostList required [formControl]="formGroup.controls['cost']>
      <mat-chip *ngFor="let item of svr.cost" [selectable]="selectable" [removable]="removable" (removed)="remove(item, 'cost')">
        {{item}}
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>
      <input placeholder="Cost" [matChipInputFor]="chipCostList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="addOnBlur"
        (matChipInputTokenEnd)="add($event, 'cost')" [(ngModel)]="costValue" #cost="ngModel" name="cost">
    </mat-chip-list>
  </mat-form-field>
  <div *ngIf="cost.invalid && (cost.dirty || cost.touched)" class="alert alert-danger">
    Cost is required
  </div>
</div>
add(event: MatChipInputEvent, name: string): void {
  ...
  this.formGroup.controls['cost'].setValue(event.option.value);
}

(If you don't set the value of the form control in the callback, the form sees the input as invalid even when you select something).

Where I got the answer: https://github.com/angular/components/issues/10992

like image 60
interrupt_driven Avatar answered Oct 20 '25 19:10

interrupt_driven



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!