web-dev-qa-db-fra.com

Angular 2+ matériau mat-chip-list formArray validation

Comment puis-je valider qu'un mat-chip a été ajouté au mat-chip-list. J'utilise ReactiveForms. J'ai essayé avec le validateur required.

La valeur peut être une liste de noms, je dois donc m'assurer qu'il y a au moins 1 nom dans ma liste de noms avant de pouvoir soumettre le formulaire. Si la liste est vide, alors mat-error devrait afficher le message d'erreur. L'utilisation du validateur required rend le formulaire invalide, indépendamment de l'ajout de noms à la liste.

EDIT: Formes réactives

J'ai essayé de créer un validateur personnalisé et j'utilise maintenant des formulaires réactifs au lieu de formulaires basés sur des modèles, mais je ne peux pas le faire fonctionner. J'ai édité le code ci-dessous pour refléter mes changements et je l'ai créé 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);
  }
}
5
Asgher Qureshi

Le problème est que le chipList de errorState n'est pas défini sur true lorsque le statut de chipList de FormArray est INVALID .

Je suis confronté au même problème et je ne sais pas pourquoi cela ne fonctionne pas ou comment cela peut être obtenu implicitement avec le formulaire de chipList étant un FormArray.

Pour surmonter ce problème, vous pouvez écouter les changements d'état à partir du FormArray et définir manuellement le chipListerrorState:

@ViewChild('chipList') chipList: MatChipList;

ngOnInit() {
  this.myForm.get('names').statusChanges.subscribe(status => 
     this.chipList.errorState = status === 'INVALID' ? true : false);
}

https://stackblitz.com/edit/angular-4d5vfj-rembhd

1
fridoo