DEV Community

Cover image for N Level Form Array with Dynamically Validation in Angular
Sandip Malaviya for Samarpan Infotech

Posted on • Originally published at samarpaninfotech.com

N Level Form Array with Dynamically Validation in Angular

In this tutorial article, we will cover the form with multiple sub-form (nested form) along with each sub-form have custom validation in Angular.

Problem Statement

Create a form with N number of sub-forms, each with N number of listed items, and submit the entire form at once, with specific validation in each form/form array.

Use Case

Let’s say, you had to create a gateway for Family Information that included basic information as well as various Address Details, Income Details, Expense Details, Education Details, Sickness Details, and so on. Furthermore, each family has several family members, and each family member has various education, spending, and income statistics. All forms contain N details and distinct fields, as well as dynamic validation when data is entered.

Use case image

Prerequisites

  1. Prior knowledge of TypeScript
  2. Prior knowledge of JavaScript
  3. Visual studio code
  4. A development machine with Node 10+ & NPM 5.5.1+ installed

Create N Level FormArray with Reactive Form Validation in Angular: Step by Step Tutorial

Step 1: Create New Angular Project

  • Import the ReactiveFormsModule and FormsModule in app.module.ts Also, add it to the imports array of NgModule of the AppModule
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

Forms Module

Step 2: App.component.ts

  • Now, Create a simple form first in app.component.ts and import the below the line and add a new form something like this with validation
import { FormArray,FormBuilder,FormControl,FormGroup,Validators } from '@angular/forms';
Form Array image

Step 3: App.component.html

  • App.component.html should look like this with a validation message message
App component html code
  • Run the command: npm start and open the browser localhost:4200/ - it will look like this and validation should fire on the touch that textbox or press submit button
run the command image

Step 4: Form-Array

  • Let’s move toward the FormArray, and try to add the first array assume we have to add the “Education Details” list.
  • Add new member in form declaration part like this
educationdata: 
this.fb.array([])

form array code

Step 5: Declare FormArray Function Like This

educationdata(): FormArray {
    return this.myForm.get('educationdata') as FormArray;
  }

Step 6: Create A New Form Like This

neweducationdata(): FormGroup {
    return this.fb.group({
      schoolName: new FormControl(''),
      degree: new FormControl(''),
      fieldofstudy: new FormControl(''),
      startDt: new FormControl(''),
      endDt: new FormControl(''),
      grade: new FormControl(''),
      notes: new FormControl(''),
      attachmenturl: new FormControl(''),
    });
  }

Step 7: Add New Array Function

educationcon(index) {
    this.educationList = this.myForm.get('educationdata') as FormArray;
    const formGroup = this.educationList.controls[index] as FormGroup;
    return formGroup;
  }

Step 8: Remove New Array Function

removeeducationdata(i: number) {
    this.educationdata().removeAt(i);
  }

Step 9: Add Validation Management Like This

educationcon(index) {
 this.educationList = this.myForm.get('educationdata') as FormArray; const formGroup = this.educationList.controls[index] as FormGroup;
    return formGroup;
}
  • Ts code should look like this

ts code

  • The HTML code should be like this
<table
   class="table table-bordered"
   formArrayName="educationdata"
   >
   <tr>
      <th colspan="7">Add More Data:</th>
      <th width="150px">
         <button
            type="button"
            (click)="addeducationdata()"
            class="btn btn-primary"
            >
         Add More
         </button>
      </th>
   </tr>
   <tr
   *ngFor="let f of educationdata().controls; let i = index"
   [formGroupName]="i"
   >
   <td>
      School/College Name :
      <input
         type="text"
         formControlName="schoolName"
         class="form-control"
         />
   </td>
   <td>
      Degree:
      <select formControlName="degree" class="form-control">
         <option value="">Select Degree</option>
         <option value="SCHOOL">School Degree</option>
         <option value="COLLEGE">Some College</option>
         <option value="BACHELOR">Bachelor Degree</option>
         <option value="MASTER">Master Degree</option>
         <option value="PHD">PhD Degree</option>
      </select>
   </td>
   <td>
      Field Of Study:
      <input
         class="form-control"
         type="text"
         formControlName="fieldofstudy"
         />
   </td>
   <td>
      Start Date:
      <input
         class="form-control"
         type="date"
         formControlName="startDt"
         />
   </td>
   <td>
      End Date:
      <input
         class="form-control"
         type="date"
         formControlName="endDt"
         />
   </td>
   <td>
      Grade:
      <input
         class="form-control"
         type="text"
         formControlName="grade"
         />
   </td>
   <td>
      Notes:
      <textarea
         class="form-control"
         formControlName="notes"
         ></textarea>
   </td>
   <td>
      <button
         (click)="removeeducationdata(i)"
         class="btn btn-danger"
         >
      Remove
      </button>
   </td>
   </tr>
</table>
  • When you run the project the UI will look like this, I have used a tab (bootstrap tab), you can add N number of an array and remove any specific array.

project ui

Now Let’s Add Validation In The Nested Array

Step 1: Add A Display Message Like This

validation_edumessage = {
    schoolName: [{ type: 'required', message: 'School Name is required' }],
    degree: [{ type: 'required', message: 'Degree is required' }],
    startDt: [{ type: 'required', message: 'Start Date is required' }]};

Step 2: Add Validation In Education From The Group

neweducationdata(): FormGroup {
    return this.fb.group({
      schoolName: new FormControl('', [Validators.required]),
      degree: new FormControl('', [Validators.required]),
      fieldofstudy: new FormControl(''),
      startDt: new FormControl('', [Validators.required]),
      endDt: new FormControl(''),
      grade: new FormControl(''),
      notes: new FormControl('')}); }

Step 3: Add Validation In Form Html Like This

<input type="text" formControlName="schoolName"
   class="form-control" 
   [ngClass]="{'is-invalid':
    educationcon(i).controls['schoolName'].errors &&
    (educationcon(i).controls['schoolName'].dirty ||                        educationcon(i).controls['schoolName'].touched)}"/>

  <div *ngFor="let validation of validation_edumessage.schoolName"
   class="invalid-feedback">
   <div  *ngIf="educationcon(i).controls['schoolName'].hasError(validation.type) 
&& (educationcon(i).controls['schoolName'].dirty || educationcon(i).controls['schoolName'].touched)">
 </div> </div>
  • UI should look like this:

ui output

  • When you submit a form we will get all data like this (capture from console)

code from console

Over To You!

Looking for a Sample Source Code? Here you go: GITHUB.

That’s it for now. Today you have learned how to create N Level FormArray With Reactive Form Validation using Angular.

At last, If you’re dealing with large-scale applications or enterprise software, it is beneficial to take experts’ help. If you’re looking for an expert helping hand, contact Samarpan Infotech and hire Angular developers with having minimum of 5+ years of experience working on enterprise software.

Discussion (0)