Wednesday, January 8, 2020

Angular 8|9 Checkbox Tutorial with Multi Checkbox Validation

Setting Up Angular 9 Form

To work with this tutorial, first, we need to import and register ReactiveFormsModule and FormsModule service in the main app module to enable the form service. Open app.module.ts file and add the following code inside of it.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Creating Checkbox
Let us use the FormBuilder method to build the form, define [formGroup]="" directive and (ngSubmit)="" click event with HTML form tag.
<form [formGroup]="form" (ngSubmit)="submitForm()" novalidate>
    <!-- Form elements goes here -->
    <input type="submit" value="Submit">
</form>
Configure Reactive Forms to work with Checkboxes in Angular 9. Import the following form services.
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';
FormBuilder: The FormBuilder creates instances of a FormControl, FormGroup, or FormArray. It helps in creating complicated forms in Angular.
Angular 8|9 Checkbox Tutorial with Multi Checkbox Validation

FormGroup: Creates the form object in Reactive Forms, and It contains FormControl and FormArray properties.
FormArray: FormArray is the same as FormGroup and holds the FormControl in an array form.
FormControl: It refers to a specific input field which contains the user entered value and defined inside the FormGroup..
Validators: It offers a set of pre-defined validators to validate a form in Angular and can be used by form controls.
We will show the checkboxes values dynamically in our Angular app, assign the fruits list in an array.

Data: Array<any> = [
  { name: 'Pear', value: 'pear' },
  { name: 'Plum', value: 'plum' },
  { name: 'Kiwi', value: 'kiwi' },
  { name: 'Apple', value: 'apple' },
  { name: 'Lime', value: 'lime' }
];
To initiate the Reactive Form in Angular, assign the FormGroup to a form variable.
Inject the FormBuilder API in the constructor and create the main form object and bind it to FormBuilder.
The checkArray is the form control that is created using FormArray API, and It will hold the multiple checkboxes values in an array form.
constructor(private fb: FormBuilder) {
  this.form = this.fb.group({
    checkArray: this.fb.array([])
  })
}
Handling Multiple Checkboxes
Now, we will create a simple functionality to handle multiple checkboxes using Angular Reactive Forms.
onCheckboxChange(e) {
  const checkArray: FormArray = this.form.get('checkArray') as FormArray;
  if (e.target.checked) {
    checkArray.push(new FormControl(e.target.value));
  } else {
    let i: number = 0;
    checkArray.controls.forEach((item: FormControl) => {
      if (item.value == e.target.value) {
        checkArray.removeAt(i);
        return;
      }
      i++;
    });
  }
}
To select all and unselect all value from a checkbox list, we used the following approach.
The onCheckboxChange() method takes one argument, and this value referred to the checkbox value when a user clicked on it.
To set the array for multiple checkboxes, we stated a checkArray variable with FormArray service, get the form control using the getter method.

Check if condition the condition is true, basically we are verifying if the user selected a checkbox, then we will push the checked item’s value in the checkArray form control using the JavaScript’s pus array method.

To remove the value from the checkArray form control, we are using the forEach method to get the FormControl array and checking if the selected value is matched with the checkbox value. Then, we are removing the checkbox value using JavaScript’s removeAt() method.
<form [formGroup]="form" (ngSubmit)="submitForm()" novalidate>
  <div *ngFor="let data of Data; let i=index">
    <label>
      <input type="checkbox" [value]="data.value" (change)="onCheckboxChange($event)" />
      {{data.name}}
    </label>
  </div>
  <input type="submit" value="Submit">
</form>
To display the checkboxes use the *ngFor loop. To select and unselect value from checkbox list use the onCheckboxChange($event) event with change event handler.

Angular Checkbox Validation

In this step, we will validate Angular Checkbox using Validators Angular Form service. Our validation is simple. We will show an error message to the users initially and convey the message to tick on at-least one checkbox from the checkboxes list.
We have already imported the Validators service, add it to the checkArray form control, as given below.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';
import { ValueTransformer } from '@angular/compiler/src/util';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;
  Data: Array<any> = [
    { name: 'Pear', value: 'pear' },
    { name: 'Plum', value: 'plum' },
    { name: 'Kiwi', value: 'kiwi' },
    { name: 'Apple', value: 'apple' },
    { name: 'Lime', value: 'lime' }
  ];
  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      checkArray: this.fb.array([], [Validators.required])
    })
  }
  onCheckboxChange(e) {
    const checkArray: FormArray = this.form.get('checkArray') as FormArray;
    if (e.target.checked) {
      checkArray.push(new FormControl(e.target.value));
    } else {
      let i: number = 0;
      checkArray.controls.forEach((item: FormControl) => {
        if (item.value == e.target.value) {
          checkArray.removeAt(i);
          return;
        }
        i++;
      });
    }
  }
  submitForm() {
    console.log(this.form.value)
  }
}
Display the error message with the help of *ngIf condition in the Angular HTML template, here we are checking if the form control has the required parameter. If it is true then show the error else hide the error.
<form [formGroup]="form" (ngSubmit)="submitForm()" novalidate>
  <div *ngFor="let data of Data; let i=index">
    <label>
      <input type="checkbox" [value]="data.value" (change)="onCheckboxChange($event)" />
      {{data.name}}
    </label>
  </div>
  <p class="error" *ngIf="this.form.controls['checkArray'].errors?.required">
    Checkbox is required, select atleast one value.
  </p>
  <input type="submit" value="Submit">
</form>