Friday, October 15, 2021

Adding dynamic controls using reactive forms in angular

Adding dynamic controls using reactive forms




In the above example we are capturing user name , email and his/her hobbies. User can add more than one hobby. So we add hobby control dynamically.

Step 1 : app-component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" [formGroup]="form" autocomplete="off">
        <div id="user-data" formGroupName="userData">
          <div class="form-group">
            <label for="username" class="text-warning">User Name</label>
            <input type="username" placeholder="User Name" name="username" formControlName="username"
              class="form-control" />
            <span class="text-danger"
              *ngIf="!(form.get('userData.username')?.valid) && form.get('userData.username')?.touched">Please enter
              user name</span>
          </div>
          <div class="form-group">
            <label for="email" class="text-warning">Email</label>
            <input type="text" placeholder="Email" name="email" class="form-control" formControlName="email" />
            <span class="text-danger"
              *ngIf="!(form.get('userData.email')?.valid) && form.get('userData.email')?.touched">Please enter valid
              email</span>
          </div>
        </div>
        <h4 *ngIf="hobbies.length < 2; else t" class="text-warning">Your Hobby</h4>
        <ng-template #t>
          <h4 class="text-warning">Your Hobbies</h4>
        </ng-template>

        <div class="form-group" formArrayName="hobbies">
          <button type="button" class="btn btn-success" (click)="onAddingHobby()">Add Hobby</button>
          <div id="dynamicControls" class="form-group" *ngFor="let hobby of hobbies.controls; let i = index">
            <span class="col-xs-5">
              <input type="text" [placeholder]="'Hobby ' + (i + 1)" [formControlName]="i" class="form-control"></span>
            <span><button id="removeControl" type="button" class="btn btn-danger" (click)="onRemovingHobby(i)">X
              </button></span>
          </div>
        </div>
        <button type="submit" [disabled]="!this.form.valid" class="btn btn-primary">Submit</button>
      </form>
    </div>
  </div>
</div>

Step 2 : app-component.ts

import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  excludedUserName: string[] = ['Test', 'test'];
  form!: FormGroup;
  ngOnInit(): void {
    this.form = new FormGroup({
      'userData': new FormGroup({
        'email': new FormControl(null, [Validators.required, Validators.email]),
        'username': new FormControl(null, [Validators.required,
                                this.excludedUserNames.bind(this)]),
      }),

      'hobbies': new FormArray([])
    });
  }
  onSubmit() {
    console.log(this.form);
  }

  onAddingHobby() {
    const control = new FormControl(null, Validators.required);
    this.hobbies.push(control);
  }
  onRemovingHobby(i: number) {
    this.hobbies.removeAt(i);
  }

  excludedUserNames(fromControl: FormControl): { [s: string]: boolean } | null {
    if (this.excludedUserName.indexOf(fromControl.value) !== -1) {
      return { 'excludedUserName': true };
    }
    return null;
  }

  get hobbies() {
    return this.form.get('hobbies') as FormArray;
  }
}

No comments:

Post a Comment