How to dynamically add FormControl to FormArray on button click in Angular?

后端 未结 1 1177
南方客
南方客 2020-12-11 21:54

How can I add a formcontrol(option) dynamically in formarray? I want to dynamically add questions to a formarray. Upon clicking a butt

相关标签:
1条回答
  • 2020-12-11 22:06

    This example dynamically adds email fields to a reactive form. This would be used to enable users to add multiple email addresses (e.g. Home and Work).

    This demo has the following dependencies: Angular 8, Angular Material, Bootstrap 4

    End Result (Stackblitz Demo)

    Step 1: Define the form model

    constructor(private formBuilder: FormBuilder) { }
    
    ngOnInit() {
      this.emailForm = this.formBuilder.group({
        emails: this.formBuilder.array([this.createEmailFormGroup()])
      });
    }
    

    Step 2: Define a method to dynamically construct new FormGroup

    private createEmailFormGroup(): FormGroup {
      return new FormGroup({
        'emailAddress': new FormControl('', Validators.email),
        'emailLabel': new FormControl('')
      })
    }
    

    Step 3: Define a method to dynamically add new FormGroup to the FormArray

    public addEmailFormGroup() {
      const emails = this.emailForm.get('emails') as FormArray
      emails.push(this.createEmailFormGroup())
    }
    

    Step 4 (Optional): Define method to delete FormGroup

    public removeOrClearEmail(i: number) {
      const emails = this.emailForm.get('emails') as FormArray
      if (emails.length > 1) {
        emails.removeAt(i)
      } else {
        emails.reset()
      }
    }
    

    Step 5: Create the HTML form template

    <form [formGroup]="emailForm">
      <div formArrayName="emails">
        <div class="row" *ngFor="let email of emailForm.get('emails').controls; let i = index"
            [formGroupName]="i">
    

    Note that within the formArrayName element, the dynamic email FormGroups are named based on the array index.

    Final Form

    <mat-toolbar color="primary">
        Angular Form Demo - Dynamically add form controls
    </mat-toolbar>
    
    <form class="basic-container" [formGroup]="emailForm">
      <div formArrayName="emails">
        <div class="row" *ngFor="let email of emailForm.get('emails').controls; let i = index"
            [formGroupName]="i">
    
          <div class="col-1">
            <mat-icon class="mt-3">email</mat-icon>
          </div>
    
          <mat-form-field class="col-4">
            <input matInput formControlName="emailAddress" placeholder="Email" autocomplete="email">
            <mat-error *ngFor="let validation of validationMsgs.emailAddress">
              <div *ngIf="email.get('emailAddress').hasError(validation.type)">
                {{validation.message}}
              </div>
            </mat-error>
          </mat-form-field>
    
          <mat-form-field class="col-4">
            <mat-label>Label</mat-label>
            <mat-select formControlName="emailLabel">
              <mat-option *ngFor="let label of emailLabels" [value]="label">
                {{label}}
              </mat-option>
            </mat-select>
          </mat-form-field>
    
          <div class="col-3">
            <button class="float-left" mat-icon-button color="primary" aria-label="Remove/clear"
                (click)="removeOrClearEmail(i)" matTooltip="Remove">
              <mat-icon>highlight_off</mat-icon>
            </button>
            <button class="float-left" mat-icon-button color="primary" aria-label="Add"
                (click)="addEmailFormGroup()" matTooltip="Add">
              <mat-icon>add_circle_outline</mat-icon>
            </button>
          </div>
        </div>
      </div>
    </form>
    

    Final Component

    import {Component} from '@angular/core';
    import {FormBuilder, FormArray, FormControl, FormGroup, Validators} from '@angular/forms';
    
    @Component({
      selector: 'form-app',
      templateUrl: 'app.component.html'
    })
    export class AppComponent {
      public emailForm: FormGroup;
      public emailLabels = ['Home', 'Work', 'Other'];
      public validationMsgs = {
        'emailAddress': [{ type: 'email', message: 'Enter a valid email' }]
      }
    
      constructor(private formBuilder: FormBuilder) { }
    
      ngOnInit() {
        this.emailForm = this.formBuilder.group({
          emails: this.formBuilder.array([this.createEmailFormGroup()])
        });
      }
    
      public addEmailFormGroup() {
        const emails = this.emailForm.get('emails') as FormArray
        emails.push(this.createEmailFormGroup())
      }
    
      public removeOrClearEmail(i: number) {
        const emails = this.emailForm.get('emails') as FormArray
        if (emails.length > 1) {
          emails.removeAt(i)
        } else {
          emails.reset()
        }
      }
    
      private createEmailFormGroup(): FormGroup {
        return new FormGroup({
          'emailAddress': new FormControl('', Validators.email),
          'emailLabel': new FormControl('')
        })
      }
    }
    
    0 讨论(0)
提交回复
热议问题