Angular 2+ material mat-chip-list formArray validation

[亡魂溺海] 提交于 2020-01-13 02:41:49

问题


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);
  }
}

回答1:


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




回答2:


Unfortunately, it's not possible to use any of Angular's predefined validators because they are not designed to work with arrays. I manage to do it with the help of this article:

https://www.dev6.com/Angular_Material_Chips_with_Reactive_Forms_and_Custom_Validation



来源:https://stackoverflow.com/questions/53483323/angular-2-material-mat-chip-list-formarray-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!