Angular FormArrayで動的に変化するフォーム

こんにちは。レモンティーです。

以前、フォームについての記事を書きました。
www.sawalemontea.com

今回はFormArrayを使って動的に変化するフォームをつくります。
AngularMaterialでMatErrorのバリデーションも付けます。

Angular Docs

Angular Material



使い方はFormBuilderでFormGroupにFormArrayを入れておいて
項目を増減したい時にそのFormArrayに子FormGroupを
pushしたりremoveAtする感じです。


以下、複数のリンクを入力するフォームを例に見ていきます。


FormBuilderでFormArrayを入れておく
(ついでにgetで後々呼びやすくしておきます。)

  exampleForm:FormGroup;

  constructor(private fb:FormBuilder) { 
    this.exampleForm = this.fb.group({
      links:this.fb.array([]),
    });
  }

  get f() {return this.exampleForm.controls;}
  get linksArray():FormArray {return this.f.links as FormArray;}


項目を増やす

  addLinks(){
    this.linksArray.push(
      this.fb.group({
        linkName:["",[Validators.required]],
        linkUrl:["",[Validators.required]]
      })
    );
  }

項目を減らす

  removeLink(index:number){
    this.linksArray.removeAt(index);
  }

値の参照

  onSave(){
    for(let group of this.linksArray.controls){
      console.log(group.get("linkName").value);
      console.log(group.get("linkUrl").value);
    }
  }


テンプレート側は次のようになります

<form [formGroup]="exampleForm">

  <div formArrayName="links">
    <div *ngFor="let linksGroup of linksArray.controls; let i = index" [formGroupName]="i">
      <mat-form-field>
        <input matInput formControlName="linkName" placeholder="link name">
        <mat-error *ngIf="linksGroup.controls.linkName.invalid">{{getErrorMessage(linksGroup.controls.linkName)}}</mat-error>
      </mat-form-field>
      <mat-form-field>
        <input matInput formControlName="linkUrl" placeholder="link url">
        <mat-error *ngIf="linksGroup.controls.linkUrl.invalid">{{getErrorMessage(linksGroup.controls.linkUrl)}</mat-error>
      </mat-form-field>
      <button mat-button (click)="removeLink(i)">Delete</button>
    </div>
  </div>

  <button mat-flat-button color="primary" (click)="addLinks()" type="button">Add Links</button>
  <button mat-flat-button color="primary" (click)="onSave()" type="button" [disabled]="exampleForm.invalid">Save</button>

</form>

getErrorMessage()は前回のものと同じです。


これで項目を自由に増減できるフォームができます。
AngularMaterialでバリデーションも効いていますね。


今回はこれでおしまいです。
www.sawalemontea.com