Ionic 4|5 Checkbox List Required Validation using Reactive Forms

In this article, we will discuss How to validate multiple checkboxes in Ionic 4|5 application using Angular Reactive Forms.

Here we will have a list of the checkbox which can be selected or unselected using a single master checkbox and also individually.

We will add validation on checkbox list using Reactive form approach provided by Angular core API.

Let’s get started with the implementation.

 

Version Check

@ionic/cli 

   _             _
  (_) ___  _ __ (_) ___
  | |/ _ \| '_ \| |/ __|
  | | (_) | | | | | (__
  |_|\___/|_| |_|_|\___| CLI 6.4.1

Update to the latest version of Ionic CLI by running following NPM command:

$ npm install -g @ionic/cli</pre>
<h3></h3>
<h3>Create an Ionic Application</h3>
Using <code>@ionic/cli we will create a new Ionic application using Angular framework with a blank template:
$ ionic new ionic-checkbox-validation blank --type=angular</pre>
 
<h3>Configuration for Angular Forms</h3>
To use forms in Angular application, we need to import <code>FormsModule and ReactiveFormsModule in the page module file.

As we are going to implement in Home Page so open home.module.ts file import these modules as shown below:
// home.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { HomePage } from './home.page';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule,
    RouterModule.forChild([
      {
        path: '',
        component: HomePage
      }
    ])
  ],
  declarations: [HomePage]
})
export class HomePageModule { }

Home Page Template

Adding Form

In the Home page template HTML, we will add a form with [formBuilder] directive property. The form submit event will be handled by (ngSubmit) method on the form.

<form [formGroup]="ionicFormGroup" (ngSubmit)="submitForm()">
...
</form>

</pre>
 

<strong>Checkbox list</strong>

In the form element, define checkbox elements in <code>ion-list UI component directive. It will iterate over CHECK_LIST data object using *ngFor directive as shown below:
<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Ionic Multi Checkbox Validation
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">

  <form [formGroup]="ionicForm" (ngSubmit)="submitForm()">

    <ion-list>

      <ion-item *ngFor="let item of CHECK_LIST; let i=index">

        <ion-label>{{item.name}}</ion-label>
        <ion-checkbox slot="end" [value]="item.value" [checked]="item.checked"
          (ionChange)="onSelectionChange($event,i)">
        </ion-checkbox>

      </ion-item>

      <ion-item *ngIf="isFormSubmitted && ionicForm.controls['checkboxArrayList'].errors?.required">
        <label class="error-msg">
          Please select Hobby!
        </label>
      </ion-item>

      <ion-item class="center">
        <ion-button type="submit">Submit Form</ion-button>
      </ion-item>

    </ion-list>

    {{CHECK_LIST | json}}

  </form>


</ion-content></pre>
In the above template, we have also added a <code>label element to show an error message when no checkbox is selected. This message will only be shown after a user submits the form as we have added a variable isFormSubmitted on *ngIf condition.

Home Component Class

The list of checkboxes will be created dynamically by iterating over the CHECK_LIST object will look like this:
  CHECK_LIST = [
    { name: 'Photography', value: 'Photography', checked: true },
    { name: 'Blogging', value: 'Blogging' },
    { name: 'Cooking', value: 'Cooking' },
    { name: 'Singing', value: 'Singing' },
    { name: 'Dancing', value: 'Dancing' },
    { name: 'Pottery', value: 'Pottery' },
    { name: 'Knitting', value: 'Knitting' }
  ];</pre>
We can set the <code>checked property to true, if you want to set it checked by default.

To instantiate the form as Reactive we will define the ionicForm as FormGroup.
ionicForm: FormGroup;</pre>
In the constructor, we will define checkbox list control as FormArray as shown below:
<pre class="wp-block-prismatic-blocks"><code class="language-javascript">  constructor(private formBuilder: FormBuilder) {
    this.ionicForm = this.formBuilder.group({
      checkboxArrayList: this.formBuilder.array([], [Validators.required])
    });
  }</pre>
To update the <code>checkboxArrayList on page load, we will update it in the updateCheckControl() method which will also be called from checkbox change event in the onSelectionChange() method.
  updateCheckControl(cal, o) {
    if (o.checked) {
      cal.push(new FormControl(o.value));
    } else {
      cal.controls.forEach((item: FormControl, index) => {
        if (item.value == o.value) {
          cal.removeAt(index);
          return;
        }
      });
    }
  }

  onLoadCheckboxStatus() {
    const checkboxArrayList: FormArray = this.ionicForm.get('checkboxArrayList') as FormArray;
    this.CHECK_LIST.forEach(o => {
      this.updateCheckControl(checkboxArrayList, o);
    })
  }

  onSelectionChange(e, i) {
    const checkboxArrayList: FormArray = this.ionicForm.get('checkboxArrayList') as FormArray;
    this.CHECK_LIST[i].checked = e.target.checked;
    this.updateCheckControl(checkboxArrayList, e.target);

  }

After adding the above methods the final home.page.ts file will look like this:

// home.page.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  ionicForm: FormGroup;

  isFormSubmitted = false;

  CHECK_LIST = [
    { name: 'Photography', value: 'Photography', checked: true },
    { name: 'Blogging', value: 'Blogging' },
    { name: 'Cooking', value: 'Cooking' },
    { name: 'Singing', value: 'Singing' },
    { name: 'Dancing', value: 'Dancing' },
    { name: 'Pottery', value: 'Pottery' },
    { name: 'Knitting', value: 'Knitting' }
  ];

  constructor(private formBuilder: FormBuilder) {
    this.ionicForm = this.formBuilder.group({
      checkboxArrayList: this.formBuilder.array([], [Validators.required])
    });

    this.onLoadCheckboxStatus();
  }

  updateCheckControl(cal, o) {
    if (o.checked) {
      cal.push(new FormControl(o.value));
    } else {
      cal.controls.forEach((item: FormControl, index) => {
        if (item.value == o.value) {
          cal.removeAt(index);
          return;
        }
      });
    }
  }

  onLoadCheckboxStatus() {
    const checkboxArrayList: FormArray = this.ionicForm.get('checkboxArrayList') as FormArray;
    this.CHECK_LIST.forEach(o => {
      this.updateCheckControl(checkboxArrayList, o);
    })
  }

  onSelectionChange(e, i) {
    const checkboxArrayList: FormArray = this.ionicForm.get('checkboxArrayList') as FormArray;
    this.CHECK_LIST[i].checked = e.target.checked;
    this.updateCheckControl(checkboxArrayList, e.target);

  }

  submitForm() {
    this.isFormSubmitted = true;
    if (!this.ionicForm.valid) {
      console.log('Please provide all the required values!')
      return false;
    } else {
      console.log('Form Submitted', this.ionicForm.value)
    }
  }
}

 

In this tutorial, we implemented Reactive form validation on the checkbox list in Ionic 5 application. We added user Angular form core services to add validation on form. When no value is checked an error message is shown to the user. Thanks for reading!

 

 

 

 

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *