In this Angular 9 tutorial, we’ll create a Multi checkbox list using the Material UI library’s mat-checkbox
component. This checkbox list can be checked and unchecked by clicking a master checkbox which will also display indeterminate state.
Checking/ Unchecking a list of items with checkboxes is provided with a master checkbox to provide ease to users to control all list items. Angular Material Checkbox module MatCheckbox
proves very handy in creating such lists with a number of properties.
In Material Checkbox module there are three states with Checked and Unchecked which are common, but there is also a third state called Indeterminate which is a middle of these two. Indeterminate Checkbox state indicates that some of the list items are checked but not all. It is indicated with a hyphen (-) in the checkbox.
Here we will create a list of items with a master checkbox using which a user can check to uncheck all item lists. Also if a user checks some of the items but not all, the master checkbox will show Indeterminate state which is very easy to implement.
Let’s get started!
# Setup Angular CLI
We’ll create Angula project in the latest version. Make sure you have updated the Angular CLI tool by running below npm
command in the terminal
$ npm install -g @angular/cli
# Create an Angular Project
Execute below ng
command to create an Angular project in latest version 9.1.3. But this tutorial is compatible with previous version 7,6,5 and 4
$ ng new angular-material-checkboxlist
$ cd angular-material-checkboxlist
# Install Angular Material in project
After version 8, Angular Material package can be installed by executing the following ng
command. For configuration, it will ask a few questions related to the theme, browser animations etc
$ ng add @angular/material
Answer questions
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? Yes
We are done with Angular material installation and configurations. Now our Angular project is ready to use Material components.
# Import Material Modules
The Material UI library provides a wide variety of components, so we need to import the API module of the component we are going to use in the App module.
Add Checkbox and Other Modules
To use a Material component we need to import it into the app’s module. Here for our Checkbox list, we will import some required modules.
<strong>MatCheckboxModule</strong>
: Checkbox component module <strong><mat-checkbox></strong>
<strong>MatListModule</strong>
: List item component module <strong><mat-list></strong>
<strong>MatCardModule</strong>
: Card module, will wrap Checklist in a card <strong><mat-card></strong>
<strong>FormsModule</strong>
: For Form controls like checkbox we use [(ngModel)]
which needs FormsModuleimports
array as shown below:// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatListModule } from '@angular/material/list';
import { MatCardModule } from '@angular/material/card';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatCheckboxModule,
MatListModule,
MatCardModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
</pre>
<h4></h4>
<h3># Add Checkbox List in App Template</h3>
</div>
<div>In the <strong>app.component.html</strong> file add following template HTML</div>
<div></div>
<div>Here we have wrapped a list of checkboxes with a master checkbox component. This list is wrapped in a card component</div>
<div></div>
<div>
<pre><code class="language-markup"><div style="padding: 50px; width:400px;">
<mat-card>
<mat-card-title>Angular Material 8 Checkboxes</mat-card-title>
<mat-card-content>
<mat-list>
<mat-list-item>
<mat-checkbox
[(ngModel)]="master_checked"
[(indeterminate)]="master_indeterminate"
(change)="master_change()"
><b>Check/ Uncheck All</b></mat-checkbox>
</mat-list-item>
<mat-list-item *ngFor="let item of checkbox_list">
<mat-checkbox
[(ngModel)]="item.checked"
[disabled]="item.disabled"
[labelPosition]="item.labelPosition"
(change)="list_change()"
>{{ item.name }}</mat-checkbox>
</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
The <mat -list-item>
component with the <mat-checkbox>
checkbox control is iterating over items in <strong>checkbox_list</strong>
object using <strong>*ngFor</strong>
Angular directive
<strong>[disabled]</strong>
: Boolean value to set state enable/disabled.[checked]
:Â Boolean value to change checked state of a checkbox.[indeterminate]
:Â Boolean value, when set to true it will show Indeterminate state with hyphen like checked sign.<strong>[labelPosition]</strong>
: Label text around checkbox can be set to ‘after
‘ or ‘before
‘Indeterminate
state for a master check as its main significance is for main parent checkboxes for a list.# Define Checklist Object and Methods in Component Class
name
, checked
, disabled
, labelPosition
values. this.checkbox_list = [
{
name: "HTML/CSS",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "JavaScript/jQuery",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "CSS Preprocessing",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Version Control/Git",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Responsive Design",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Testing/Debugging",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Browser Developer Tools",
disabled: false,
checked: false,
labelPosition: "after"
},
]
(change)
event listener on Master and checkbox list checkboxes are having logic to change the state.master_change()
method on master checkbox is traversing over list items to check/ uncheck all items by checking its model state master_change() {
for (let value of Object.values(this.checkbox_list)) {
value.checked = this.master_checked;
}
}
list_change()
method on each checkbox change event is checking the following three conditions: list_change(){
let checked_count = 0;
//Get total checked items
for (let value of Object.values(this.checkbox_list)) {
if(value.checked)
checked_count++;
}
if(checked_count>0 && checked_count<this.checkbox_list.length){
// If some checkboxes are checked but not all; then set Indeterminate state of the master to true.
this.master_indeterminate = true;
}else if(checked_count == this.checkbox_list.length){
//If checked count is equal to total items; then check the master checkbox and also set Indeterminate state to false.
this.master_indeterminate = false;
this.master_checked = true;
}else{
//If none of the checkboxes in the list is checked then uncheck master also set Indeterminate to false.
this.master_indeterminate = false;
this.master_checked = false;
}
}
The complete component class (app.component.ts) will look like this
//app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
master_checked: boolean = false;
master_indeterminate: boolean = false;
checkbox_list = [];
constructor() {
this.checkbox_list = [
{
name: "HTML/CSS",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "JavaScript/jQuery",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "CSS Preprocessing",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Version Control/Git",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Responsive Design",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Testing/Debugging",
disabled: false,
checked: false,
labelPosition: "after"
}, {
name: "Browser Developer Tools",
disabled: false,
checked: false,
labelPosition: "after"
},
]
}
master_change() {
for (let value of Object.values(this.checkbox_list)) {
value.checked = this.master_checked;
}
}
list_change(){
let checked_count = 0;
//Get total checked items
for (let value of Object.values(this.checkbox_list)) {
if(value.checked)
checked_count++;
}
if(checked_count>0 && checked_count<this.checkbox_list.length){
// If some checkboxes are checked but not all; then set Indeterminate state of the master to true.
this.master_indeterminate = true;
}else if(checked_count == this.checkbox_list.length){
//If checked count is equal to total items; then check the master checkbox and also set Indeterminate state to false.
this.master_indeterminate = false;
this.master_checked = true;
}else{
//If none of the checkboxes in the list is checked then uncheck master also set Indeterminate to false.
this.master_indeterminate = false;
this.master_checked = false;
}
}
}
Conclusion: Indeterminate state adds a good user experience to checkbox list which indicates the overall state of checked items. Angular material components are very easy to implement and use with a number of optional parameters available.
Leave a Reply