How to Add/Push and Remove Form fields dynamically with validation to FormArray with Reactive Forms in Angular

Add/Push and Remove Form fields dynamically with validation to FormArray with Reactive Forms in Angular


This article explains how we can add and remove inputbox dynamically to and from FormArray with required validation


Step 1 :-
First we will create a project using below command :-
ng new myApp


Step 2 :-
Now we will add bootstrap cdn in our project so open "Index.html" file and follow below code
Index.html :-
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>HelloWorld</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
</head>
<body>
  <app-root></app-root>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</body>
</html>



Step 3 :-
Now we will create a HTML form template in "app.component.html", in this form we will add hobby form control dynamically, see below code.
app.component.html :-
<div class="container formContainerClass">
  <form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
    <div class="form-group row">
        <label for="username" class="col-sm-2 col-form-label">Username</label>
        <div class="col-sm-10">
          <input type="text" id="username" formControlName="username"
                [ngClass]="{'classSubmitted':submitted}"
                class="form-control">
          <div *ngIf="submitted || signupForm.get('username').touched">
            <span *ngIf="!signupForm.get('username').valid" class="errMsg">Please enter a valid Username</span>
          </div>
        </div>
    </div>
    <div class="form-group row">
        <label for="email" class="col-sm-2 col-form-label">Email</label>
        <div class="col-sm-10">
          <input type="text" id="email" formControlName="email"
                  [ngClass]="{'classSubmitted':submitted}"
                  class="form-control">
          <div *ngIf="submitted || signupForm.get('email').touched">
            <span *ngIf="!signupForm.get('email').valid" class="errMsg">Please enter valid Email</span>
          </div>
        </div>
    </div>
    <div class="form-group row" formArrayName="hobbies">
      <label for="hobby" class="col-sm-2 col-form-label">Hobby</label>
      <div class="col-sm-10">
        <button class="btn btn-default" type="button" (click)="onAddHobby()">Add Hobby</button>
      </div>
      <div *ngFor="let hobbyControl of signupForm.get('hobbies').controls; let i=index"
            [formGroupName]="i"  class="col-sm-12">
            <div class="col-sm-2"></div>
            <div class="col-sm-8">
              <input type="text" class="form-control" formControlName="hobby" 
                [ngClass]="{'classSubmitted':hobbySubmit}"/>
              <span *ngIf="hobbyControl.get('hobby').errors?.required" 
                    class="errMsg">Please put hobby</span>
            </div>
            <div class="col-sm-2">
              <button type="button" class="btn btn-danger" (click)="onDeleteHobby(i)">X</button>
            </div>
      </div>
    </div>
    <div class="form-group row">
        <div class="col-sm-10 offset-sm-2">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>
  </form>
</div>

app.component.ts :-
import { ComponentOnInit } from '@angular/core';
import { FormGroupFormControlValidators,FormArray } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  submitted = false;
  hobbySubmit = false;
  constructor() { }
  genders = ['male','female'];
  signupForm : FormGroup;
  ngOnInit(){
    this.signupForm = new FormGroup({
        'username': new FormControl(null,Validators.required),
        'email':new FormControl(null,[Validators.required,Validators.email]),
        'gender':new FormControl('male'),
        'hobbies':new FormArray([])
    });
  }
  onSubmit(){
    this.submitted = true;
    if(!this.signupForm.valid){
      return;
    }
    alert("Form submitted !!");
    console.log(this.signupForm);
  }
  onAddHobby(){
    this.hobbySubmit = true;
    const control = new FormControl('',Validators.required);
    (<FormArray>this.signupForm.get('hobbies')).push(
      new FormGroup({
        'hobby':control
      })
    );
  }
  onDeleteHobby(index:number){
    (<FormArray>this.signupForm.get('hobbies')).removeAt(index);
  }
}


Step 4 :-
Now we will add some styling for our form so open "style.css" file
style.css :-
input.classSubmitted.ng-invalid
{
  border:1px solid #f00;
}
.errMsg{
    color#f00;
}
.formContainerClass{
  background-colorantiquewhite;
  padding-top10px;
}


Step 5 :-
See my form example

Comments

Popular posts from this blog

Call CRUD(GET, POST, PUT, DELETE) API using WebClient in c#

Asp.Net MVC 5 authentication and authorization using claims principal