Checkbox Selection in Angular TreeGrid

29 Sep 202619 minutes to read

Checkbox Selection provides an option to select multiple TreeGrid records with help of checkbox in each row.

To render a checkbox in each TreeGrid row, add a column with type set to CheckBox using the column type property.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit,ViewChild } from '@angular/core';
import { sampleData } from './datasource';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],

providers: [PageService,
                SortService,
                FilterService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='2' childMapping='subtasks'
    height='315px' >
        <e-columns>
                <e-column type='checkbox' width='50'></e-column>
                <e-column field='taskID' headerText='Task ID' textAlign='Right' width=90></e-column>
                <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' width=90></e-column>
                <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
        </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];

    ngOnInit(): void {
        this.data = sampleData;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

By default, selection is allowed via clicking either a row or its checkbox. To restrict selection to only the checkbox, set the selectionSettings.checkboxOnly property to true.
To persist selection across operations, set selectionSettings.persistSelection to true. For persisted selection, at least one column must be defined as a primary key using the columns.isPrimaryKey property.

Checkbox selection mode

Checkbox selection supports two modes, which can be set using selectionSettings.checkboxMode:

  • Default: Multiple rows can be selected by clicking their checkboxes or rows sequentially.

  • ResetOnRowClick: Clicking a row resets previous selections. To select multiple rows, press and hold the CTRL key while clicking desired rows. To select a range, press and hold the SHIFT key and click the rows.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit,ViewChild } from '@angular/core';
import { sampleData } from './datasource';
import { SelectionSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],

providers: [PageService,
                SortService,
                FilterService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='2' childMapping='subtasks'
    height='315px' [selectionSettings]='selectionOptions' >
        <e-columns>
                <e-column type='checkbox' width='50'></e-column>
                <e-column field='taskID' headerText='Task ID' textAlign='Right' width=90></e-column>
                <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' width=90></e-column>
                <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
        </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public selectionOptions?: SelectionSettingsModel;

    ngOnInit(): void {
        this.data = sampleData;
        this.selectionOptions = { checkboxMode: 'ResetOnRowClick'};
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Checkbox Selection is intended for row selection only and is not compatible with cell selection mode.

Conditional row selection

The TreeGrid supports conditional row selection through the isRowSelectable callback. This allows selection to be controlled by custom business logic, ensuring that only rows meeting specific conditions can be selected. The callback receives each row’s data and returns “true” to allow selection or “false” to prevent it.

Local data: The callback runs once when the TreeGrid initializes and evaluates all records because the full dataset is already available on the client.

Remote data: The callback runs only for the rows displayed on the current page when the TreeGrid first loads. It runs again whenever the TreeGrid fetches new data such as during paging, filtering, or sorting to re-evaluate the newly visible rows.

In the following sample, selection is disabled for rows where the “Progress” column has the value “Completed”.

import { NgModule} from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule,VirtualScrollService } from '@syncfusion/ej2-angular-treegrid'

import { Component, OnInit, ViewChild } from '@angular/core';
import { taskData } from './datasource';
import { TreeGridComponent, SelectionSettingsModel } from '@syncfusion/ej2-angular-treegrid'
@Component({
    imports: [
        TreeGridModule,
    ],
    providers: [VirtualScrollService],
    standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #Treegrid [dataSource]='data' [treeColumnIndex]='1' [enableVirtualization]=true height='600'  idMapping='TaskID' parentIdMapping='ParentID' 
                [selectionSettings]='selectionSettings' [isRowSelectable]='isRowSelectable'>
                    <e-columns>
                        <e-column type="checkbox" width=90></e-column>
                        <e-column field='Task'  headerText='Task'  width=300></e-column>
                        <e-column field='TaskID' isPrimaryKey="true" visible="false"></e-column>
                        <e-column field='AssignedTo'  headerText='Assigned To'  width=140></e-column>
                        <e-column field='StartDate' headerText='Start' format='yMd' width=180></e-column>
                        <e-column field='DueDate' headerText='Due' format='yMd' width=180></e-column>
                        <e-column field='Priority' headerText='Priority' width=90></e-column>
                        <e-column field='Progress' headerText='Progress' width=110></e-column>
                    </e-columns>
               </ejs-treegrid>`
})
export class AppComponent implements OnInit {
    public data: Object[] = [];
    public selectionSettings?: SelectionSettingsModel;
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;
    ngOnInit(): void {
        this.data = taskData;
        this.selectionSettings = { persistSelection: true };
    }
    isRowSelectable(data: any,columns:any): boolean {
        return data.Progress !== 'Completed';
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Hierarchy checkbox selection

The hierarchy checkbox enables cascading selection of parent and child rows in Tree Grid. When a parent row checkbox is selected, all its child records are automatically selected, and the parent state updates based on children selection. To enable hierarchy checkbox selection, set the showCheckbox property to true in a column and configure the hierarchyCheckboxMode property. By default, hierarchy checkbox mode is set to self.

The available modes are displayed in the following table.

Item Description
self Only the targeted row is selected; children and parent are not affected.
hierarchy Selection cascades to all descendants and adjusts the parent state accordingly.
filteredHierarchy Behaves like hierarchy, but applies the cascade only to records matching the current filter or search criteria.
import { NgModule} from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'

import { Component, OnInit, ViewChild } from '@angular/core';
import {
    FilterService,
    ToolbarItems,
    ToolbarService,
    EditService ,
    TreeGridAllModule
} from '@syncfusion/ej2-angular-treegrid';

import { QueryCellInfoEventArgs, GridAllModule } from '@syncfusion/ej2-angular-grids';

import {
    ChangeEventArgs,
    FieldSettingsModel,
    DropDownListModule,
} from '@syncfusion/ej2-angular-dropdowns';

import { showCheckBoxData } from './datasource';
type HierarchyCheckboxMode =
    | 'self'
    | 'hierarchy'
    | 'filteredHierarchy';

interface HierarchyModeItem {
    id: string;
    name: string;
}

interface TaskData {
    taskID: number;
    taskName: string;
    assignee: string;
    designation: string;
    priority: string;
    status: string;
    progress: string;
    expanded?: boolean;
    subTasks?: TaskData[];
}

@Component({
    imports: [
        TreeGridModule,
    ],
    providers: [
        FilterService,
        ToolbarService,
       EditService
    ],
    standalone: true,
    styleUrls: ['app.style.css'],
    selector: 'app-container',
    template: `
   <div class="control-section">
    <div class="content-wrapper">
        <div class="checkboxprop">
            <div class="checkboxmode">
                <span>Hierarchy Checkbox Mode</span>
                <div class="checkboxmode">
                    <ejs-dropdownlist id="hierarchyModes" tabindex="1" width="180px" [dataSource]="hierarchyModeData"
                        [fields]="hierarchyModeFields" value="Self" (change)="hierarchyModeChange($event)">
                    </ejs-dropdownlist>
                </div>
            </div>
        </div>
        <ejs-treegrid #treegrid id="TreeGrid" aria-label="Tree Grid" [dataSource]="data" childMapping="subTasks"
            [treeColumnIndex]="1" [toolbar]="toolbarOptions" [allowFiltering]="true" [height]="380" [editSettings]='editSettings'
            [hierarchyCheckboxMode]="hierarchyCheckboxMode">
            <e-columns>
                <e-column field="taskID" [visible]="false" [isPrimaryKey]="true">
                </e-column>
                <e-column field="taskName" headerText="Task Name" width="270" [showCheckbox]="true">
                </e-column>
                <e-column field="assignee" headerText="Employee" width="180">
                </e-column>
                <e-column field="designation" headerText="Designation" width="220">
                </e-column>
                <e-column field="priority" headerText="Priority" width="140">
                </e-column>
                <e-column field="status" headerText="Status" width="120">
                <ng-template #template let-data>
                <span
                [class]="'status-badge ' + getStatusClass(data.status)">
                
                </span>
                </ng-template>
                </e-column>
                <e-column field="progress" headerText="Progress" width="120" textAlign="Right">
                </e-column>
            </e-columns>
        </ejs-treegrid>
    </div>
</div>`
})
export class AppComponent implements OnInit {
    public data: TaskData[] =
        showCheckBoxData as TaskData[];

    public toolbarOptions: ToolbarItems[] = [
        'Search', 'Delete'
    ];
    public editSettings: Object = {allowDeleting: true};
    public hierarchyCheckboxMode:
        HierarchyCheckboxMode = 'self';

    public hierarchyModeData: HierarchyModeItem[] = [
        {
            id: 'Self',
            name: 'Self'
        },
        {
            id: 'Hierarchy',
            name: 'Hierarchy'
        },
        {
            id: 'FilteredHierarchy',
            name: 'Filtered Hierarchy'
        }
    ];

    public hierarchyModeFields: FieldSettingsModel = {
        text: 'name',
        value: 'id'
    };

    public hierarchyModeChange(
        args: ChangeEventArgs
    ): void {
        if (args.value === 'Hierarchy') {
            this.hierarchyCheckboxMode = 'hierarchy';
        } else if (
            args.value === 'FilteredHierarchy'
        ) {
            this.hierarchyCheckboxMode =
                'filteredHierarchy';
        } else {
            this.hierarchyCheckboxMode = 'self';
        }
    }
    public getStatusClass(status: string): string {
        return status.toLowerCase().replace(/\s+/g, '-');
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent).catch((err) => console.error(err));