Monday, April 29, 2024

Checkbox in Angular Form Example

In this post we’ll see how to use check boxes in Angular form. We’ll see examples of adding check boxes to both template-driven and reactive form in Angular.

Checkbox in Reactive form Angular example

In this Angular Reactive form example we’ll have a form with two input fields for name and date (with a date picker for picking date) and a group of check boxes to select favorite exercises.

Checkbox in Angular Form Example

Data model (member.model.ts)

Member class defines the data model reflected in the form, we’ll bind values from the form to an object of this Member class.

export class Member {
    name: string;
    membershipDate: Date;
    exercises: string[];
    constructor(name: string, membershipDate: Date, exercises:string[]) {
        this.name = name;
        this.membershipDate  = membershipDate;
        this.exercises = exercises;
    }
}

Component class (app.component.ts)

import { DatePipe } from '@angular/common';
import { Component, OnInit} from '@angular/core';
import { FormArray, FormControl, FormGroup} from '@angular/forms';
import { Member } from './member.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html', 
  providers: [DatePipe]
})
export class AppComponent implements OnInit {
  exercises: {name:string, id:number, selected: boolean}[]= [
    {name:'Running', id:1, selected: true}, 
    {name:'Skipping', id:2, selected: false},
    {name:'Cycling', id:3, selected: false},  
    {name:'Burpee', id:4, selected: false}
  ]
  currentDate = new Date();
  member = new Member('', new Date(), []);
  submitted = false;
  //selectedExecrcisesNames = [];
  selectedExecrcises = [];
  membershipForm!: FormGroup;
  constructor(private datePipe: DatePipe){ }
  ngOnInit() {
    this.membershipForm = new FormGroup({
      memberName: new FormControl(null),
      mdate: new FormControl(this.datePipe.transform(this.currentDate, 'yyyy-MM-dd')),
      exerciseSelection: this.createExercises(this.exercises)
    });
  }
  // Create form array
  createExercises(exerciseList: {name:string, id:number, selected: boolean}[]): FormArray{
    const arr = exerciseList.map(exercise => {
      return new FormControl(exercise.selected)
    });
    return new FormArray(arr);
  }
  // getter for exercises
  get formExercises(): FormArray{
    return this.membershipForm.get('exerciseSelection') as FormArray;
  }
  onSubmit(){
    this.submitted = true;
    this.member.name = this.membershipForm.value.memberName;
    this.member.membershipDate = this.membershipForm.value.mdate;
    this.member.exercises = this.getSelectedExecrcisesNames();
  }

  getSelectedExecrcisesNames():string[]  {
    // selectedExecrcises will have name of exrcises where selected is true
    // for execrises where selected is false empty string is returned.
    this.selectedExecrcises = this.membershipForm.value.exerciseSelection.map((selected:boolean, i:number) => {
      if(selected){        
        return this.exercises[i].name;
      }else {
        return '';
      }
    });
    // return selected exercises
    return this.selectedExecrcises.filter(e => e !== '');
  }
}

Important points to note here are-

  1. FormArray is used here to create an array of FormControls for check boxes elements.
  2. Apart from FormControl and FormGroup, FormArray has also to be imported.
  3. An array named exercises is created in the beginning with the names that has be added in check boxes. Method createExercises() takes this array as input and map it to create a FormArray object which contains FormControl instance for each check box entry.
  4. FormControl is initialized with the ‘Selected’ value, which is true for the first array entry. Which means by default first check box will be selected.
  5. When the form is submitted we want to assign selected exercise names to the member.exercises field. That’s what is done in getSelectedExecrcisesNames() method where first you map the values to selectedExecrcises array using the map function.
  6. map function gets the value and index as input. Value would be either true or false using that you either add the name of the selected exercise or an empty string.
  7. Then you use filter function to filter values that are empty string.

app.component.html

<div class="container">
  <h1>Membership Form</h1>
  <form [formGroup]="membershipForm" (ngSubmit)="onSubmit()">
    <div class="row mb-3">
      <label class="form-label" for="name">Name</label>
      <input type="text" class="form-control" id="name"
              formControlName="memberName">                        
    </div>
    <div class="row mb-3">
      <label class="form-label" for="mdate">Membership Date</label>
      <input type="date" class="form-control" id="mdate"
      formControlName="mdate">                        
    </div>
    <div class="row mb-3">
      <label class="form-label">Favorite cardio exercises</label>
        <div class="form-check" 
          *ngFor="let exercise of formExercises.controls; let i = index">
          <label class="form-check-label">
              <input type="checkbox" class="form-check-input" 
              [formControl]="$any(exercise)" />
              {{exercises[i].name}}
          </label>
        </div>
    </div>
    <button type="submit" class="btn btn-success">Submit</button>
  </form> 
  <hr>
  <div *ngIf="submitted">
    <div class="row">
      <div class="col-sm-10">
        <p>Name: {{member.name}}</p>
        <p>Membership Date: {{member.membershipDate | date:'dd/MM/yyyy'}}</p>
        <p>Selected Exercises: {{member.exercises}}</p>
      </div>
    </div>
  </div>  
</div>

Important points to note here are-

  1. form-check, form-check-label and form-check-input are Bootstrap classes added for check box styling.
  2. Iterate through the FormArray of FormControls created in the Component class to create check boxes entries.
    <div class="form-check" 
     *ngFor="let exercise of formExercises.controls; let i = index">
       
    where formExercises() is a getter method in the component class.
  3. Selector used here is input[type=checkbox][formControl] where formControl is bound to exercise object you get in each iteration. The exercise object is cast to any type to avoid error for AbstractControl and FormControl conversion.

Checkbox in Template-driven form Angular example

Data model remains the same as used in the Reactive form example above.

Template (app.component.html)

<div class="container">
  <h1>Membership Form</h1>
  <form (ngSubmit)="onSubmit()" #membershipForm="ngForm">
    <div class="row mb-3">
      <label class="form-label" for="name">Name</label>
      <input type="text" class="form-control" 
        id="name"
        ngModel name="name">                        
    </div>
    <div class="row mb-3">
      <label class="form-label" for="mdate">Membership Date</label>
      <input type="date" class="form-control" id="mdate"
        [ngModel]="currentDate | date:'yyyy-MM-dd'"  name="mdate">                        
    </div>
    <div class="row mb-3">
      <label class="form-label">Favorite cardio exercises</label>
      <div class="form-check" 
          *ngFor="let exercise of exercises; let i = index">
        <label class="form-check-label">
          <input type="checkbox" class="form-check-input"
          [ngModel]="exercise.selected" name="{{exercise.id}}">
          {{exercise.name}}
      </label>
      </div>
    </div>
    <button type="submit" class="btn btn-success">Submit</button>
  </form> 
  <hr>
  <div *ngIf="submitted">
    <div class="row">
      <div class="col-sm-10">
        <p>Name: {{member.name}}</p>
        <p>Membership Date: {{member.membershipDate | date:'dd/MM/yyyy'}}</p>
        <p>Selected Exercises: {{member.exercises}}</p>
      </div>
    </div>
  </div>  
</div>

Important points to note here are-

  1. For check box options are added using ngFor which iterates over an array called exercises defined in the Component class.
  2. form-check, form-check-label and form-check-input are Bootstrap classes added for check box styling.
  3. ngModel is placed to indicate that this element is a form control.
  4. If you want one of the check box to be selected by default then you can use one way binding with ngModel.
    <input type="checkbox" class="form-check-input"
                  [ngModel]="exercise.selected" name="{{exercise.id}}">
    
  5. {{exercise.name}} displays the associated label with each check box.
  6. name="{{exercise.id}}" is the name given to each check box entry. When the form is submitted the values for check boxes will go in the (name: value) format, for example {1:true, 2:””, 3:””, 4:true}

Component (app.component.ts)

import { Component, ViewChild } from '@angular/core';
import { NgForm, NgModel } from '@angular/forms';
import { Member } from './member.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  @ViewChild('membershipForm') memberForm!: NgForm;
  exercises: any = [
    {name:'Running', id:1, selected: true}, 
    {name:'Skipping', id:2, selected: false},
    {name:'Cycling', id:3, selected: false},  
    {name:'Burpee', id:4, selected: false}
  ]
  currentDate = new Date();
  member = new Member('', new Date(), []);
  submitted = false;

  onSubmit(){
    this.submitted = true;
    this.member.name = this.memberForm.value.name;
    this.member.membershipDate = this.memberForm.value.mdate;
    this.member.exercises = this.getSelectedExecrcisesNames();
    //console.log(this.memberForm.value);
  }

  getSelectedExecrcisesNames():string[]  {
    let selectedExecrcisesNames = [];
    for(let e of this.exercises){
      // for selected check boxes value would be true
      if(this.memberForm.value[e.id]){
        selectedExecrcisesNames.push(e.name);
      }
    }
    return selectedExecrcisesNames;
  }
}

Important points to note here are-

  1. An array named exercises is created in the beginning which is used in the template to iterate and create check boxes entries.
  2. When the form is submitted we want to assign selected exercise names to the member.exercises field. That logic is written in the getSelectedExecrcisesNames() method where we go through the value of each check box entry- this.memberForm.value[e.id] which will be true if selected. Values that are selected are added to the array named selectedExecrcisesNames.

That's all for this topic Checkbox in Angular Form Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Radio Button in Angular Form Example
  2. FormGroup in Angular With Examples
  3. Angular Reactive Form Validation Example
  4. Angular Template-Driven Form Validation Example
  5. Service in Angular With Examples

You may also like-

  1. Angular Access Control CanActivate Route Guard Example
  2. Angular Disable Button Example
  3. Angular Custom Event Binding Using @Output Decorator
  4. Angular Project Structure With File Description
  5. Java Stream API Tutorial
  6. Method Overriding in Java
  7. Queue Implementation in Java Using Linked List
  8. Spring Boot Microservice - Load-Balancing With Spring Cloud LoadBalancer

No comments:

Post a Comment