Filtering in Angular TreeGrid component

9 Apr 202424 minutes to read

Filtering is a powerful feature in the Syncfusion TreeGrid component that enables you to selectively view data based on specific criteria. It allows you to narrow down large datasets and focus on the information you need, thereby enhancing data analysis and decision-making.

To use filter, inject FilterService in the provider section of AppModule.

To enable filtering in the tree grid, you need to set the allowFiltering property of the tree grid to true. Once filtering is enabled, you can configure various filtering options through the filterSettings property of the tree grid. This property allows you to define the behavior and appearance of the filter.

In the TreeGrid component, filtering actions are executed based on the filterSettings.hierarchyMode to preserve the hierarchical structure of the data.

When filtering is implemented in a tree grid containing hierarchical data, the filter hierarchy mode dictates how the filtering action propagates throughout the hierarchical structure. This ensures that the filtering operation considers the parent-child relationships within the data.

For further information about the filter hierarchy mode, refer to this section.

You can check this video to learn about filtering feature in Angular Tree Grid.

Here is an example that demonstrates the default filtering feature of the tree grid:

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 { 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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Filter hierarchy modes

The TreeGrid component offers support for a variety of filtering modes through the filterSettings.hierarchyMode property. By utilizing these filter hierarchy modes, the tree grid offers flexibility in displaying filtered records based on their parent-child relationships, allowing customization of the filtering behavior according to specific requirements.

The following are the types of filter modes available in the Tree Grid:

  • Parent :
    * This is the default filter hierarchy mode in tree grid.
    * Filtered records are displayed along with their parent records.
    * If a filtered record has no parent record, only the filtered record is displayed.

  • Child :
    * Filtered records are displayed along with their child records.
    * If a filtered record has no child record, only the filtered record is displayed.

  • Both :
    * Filtered records are displayed along with both their parent and child records.
    * If a filtered record has neither parent nor child records, only the filtered record is displayed.

  • None :
    * Only the filtered records are displayed.

The following demo illustrates filtering records with different hierarchy modes.

import { Component, OnInit,ViewChild } from '@angular/core';
import { sampleData } from './datasource';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns';
import { TreeGridComponent  } from '@syncfusion/ej2-angular-treegrid';

@Component({
    selector: 'app-container',
    template: `<div style="padding-top: 7px; display: inline-block">Hierarchy Mode    
               <ejs-dropdownlist (change)='onChange($event)' [dataSource]='dropData' value='Parent' [fields]='fields'></ejs-dropdownlist>
               </div>
                
               <ejs-treegrid #treegrid [dataSource]='data' height='210' [treeColumnIndex]='1' [allowFiltering]='true'  childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 dropData?: Object[];
    public fields?: Object;
     @ViewChild('treegrid')
    public treeGridObj?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.dropData = [
        { id: 'Parent', mode: 'Parent' },
        { id: 'Child', mode: 'Child' },
        { id: 'Both', mode: 'Both' },
        { id: 'None', mode: 'None' },
    ];
    this.fields = { text: 'mode', value: 'id' };
    }
        onChange(e: ChangeEventArgs): any {
        let mode: any = <string>e.value;
        (this.treeGridObj as TreeGridComponent).filterSettings.hierarchyMode = mode;
        this.treeGridObj?.clearFiltering();
    }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Initial filter

To apply an initial filter, you need to specify the filter criteria using the predicate object in filterSettings.columns. The predicate object represents the filtering condition and contains properties such as field, operator, and value.

Here is an example of how to configure the initial filter using the predicate object:

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' height='275' [treeColumnIndex]='1'  [allowFiltering]='true' [filterSettings]="filterSettings" childMapping='subtasks' >
                    <e-columns>
                        <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 filterSettings?: Object;

    ngOnInit(): void {
        this.data = sampleData;
        this.filterSettings={
        columns: [{ field: 'taskName', matchCase: false, operator: 'startswith', predicate: 'and', value: 'plan' },
                  { field: 'duration', matchCase: false, operator: 'equal', predicate: 'and', value: 5 }]
    };
    }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Initial filter with multiple values for same column

In the TreeGrid component, you can establish an initial filter containing multiple values for a particular column, which helps you to preset filter conditions for a specific column using multiple values. This functionality allows you to display a filtered records in the tree grid right after the tree grid is initially loaded.

To apply the filter with multiple values for same column at initial rendering, set the filter predicate object in filterSettings.columns.

The following example demonstrates, how to perform an initial filter with multiple values for same taskName column using filterSettings.columns and predicate.

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

@Component({
  selector: 'app-container',
  template: `<ejs-treegrid [dataSource]='data' height='275' [treeColumnIndex]='1'  [allowFiltering]='true' [filterSettings]="filterSettings" childMapping='subtasks' >
                <e-columns>
                    <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 filterSettings?: Object;

  ngOnInit(): void {
    this.data = sampleData;
    this.filterSettings = {
      type: 'Excel',
      columns: [
        {
          field: 'taskName',
          matchCase: false,
          operator: 'startswith',
          predicate: 'or',
          value: 'plan',
        },
        {
          field: 'taskName',
          matchCase: false,
          operator: 'startswith',
          predicate: 'or',
          value: 'design',
        },
      ],
    };
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Initial filter with multiple values for different columns

By applying an initial filter with multiple values for different columns in the Tree Grid, you have the flexibility to set predefined filter settings for each column. This results in a filtered records of the tree grid right after the tree grid is initially loaded.

To apply the filter with multiple values for different column at initial rendering, set the filter predicate object in filterSettings.columns.

The following example demonstrates how to perform an initial filter with multiple values for different Task ID and Task Name columns using filterSettings.columns and predicate.

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

@Component({
  selector: 'app-container',
  template: `<ejs-treegrid [dataSource]='data' height='275' [treeColumnIndex]='1'  [allowFiltering]='true' [filterSettings]="filterSettings" childMapping='subtasks' >
                <e-columns>
                    <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 filterSettings?: Object;

  ngOnInit(): void {
    this.data = sampleData;
    this.filterSettings = {
      type: 'Excel',
      columns: [
        {
          field: 'taskName',
          matchCase: false,
          operator: 'startswith',
          predicate: 'or',
          value: 'plan',
        },
        {
          field: 'taskName',
          matchCase: false,
          operator: 'startswith',
          predicate: 'or',
          value: 'design',
        },
        {
          field: 'taskID',
          matchCase: false,
          operator: 'lessThan',
          predicate: 'and',
          value: 5,
        },
        {
          field: 'taskID',
          matchCase: false,
          operator: 'equal',
          predicate: 'or',
          value: 2,
        },
      ],
    };
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Filter operators

The Syncfusion TreeGrid component provides various filter operators that can be used to define filter conditions for columns. The filter operator for a column can be defined using the operator property in the filterSettings.columns object.

The available operators and its supported data types are,

Operator  Description  Supported Types
startsWith  Checks whether a value begins with the specified value.  String
endsWith  Checks whether a value ends with specified value.  String
contains  Checks whether a value contains with specified value.  String
doesnotstartwith Checks whether the value does not begin with the specified value. String
doesnotendwith Checks whether the value does not end with the specified value. String
doesnotcontain Checks whether the value does not contain the specified value. String
equal  Checks whether a value equal to specified value.  String | Number | Boolean | Date
notEqual  Checks whether a value not equal to specified value.  String | Number | Boolean | Date
greaterThan  Checks whether a value is greater than with specified value.  Number | Date
greaterThanOrEqual Checks whether a value is greater than or equal to specified value.  Number | Date
lessThan  Checks whether a value is less than with specified value.  Number | Date
lessThanOrEqual  Checks whether a value is less than or equal to specified value.  Number | Date
isnull Returns the values that are null. String | Number | Date
isnotnull Returns the values that are not null. String | Number | Date
isempty Returns the values that are empty. String
isnotempty Returns the values that are not empty. String
between Filter the values based on the range between the start and end specified values. Number | Date

Change default filter operator for particular column

The TreeGrid component provides the flexibility to change the default filter operator for a particular column. By default, the filter operator for string-type columns is startsWith, for numerical-type columns is equal, and for boolean-type columns is also equal. However, you may need to customize the filter operator to better match the nature of the data in a specific column. This can be achieved using the operators property within the filterSettings configuration.

Here’s an example that demonstrates how to change the default filter operator column :

import { Component, OnInit, ViewChild } from '@angular/core';
import {
  sampleData,
  stringOperatorsData,
  numericOperatorsData,
} from './datasource';
import {
  DropDownListComponent,
  ChangeEventArgs,
} from '@syncfusion/ej2-angular-dropdowns';
import { Column, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';

@Component({
  selector: 'app-container',
  template: `
        <div id='content' class='container'>
            <div class='input-container'>
                <label for='fields' class='label'>Select Column</label>
                <ejs-dropdownlist #field id='fields' [dataSource]='fieldData' (change)='onFieldChange($event)'
                 placeholder='Eg: Task ID'></ejs-dropdownlist>
            </div>
            <div class='input-container'>
                <label for='operator' class='label'>Select Operator</label>
                <ejs-dropdownlist #operator id='operator' [dataSource]='availableOperators' (change)='onOperatorChange($event)'
                 placeholder='Eg: Equal' [enabled]='false'></ejs-dropdownlist>
            </div>
        </div>
  
            <ejs-treegrid #treegrid [dataSource]='data' height='275' [treeColumnIndex]='1'  [allowFiltering]='true'  (dataBound)='dataBound()' childMapping='subtasks' >
                <e-columns>
                    <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 filterSettings?: Object;
  public fieldData?: string[];
  public availableOperators: object[] | string | undefined;
  public column: Column | undefined;
  @ViewChild('treegrid') public treegrid?: TreeGridComponent;
  @ViewChild('operator') public operatorDropdown?: DropDownListComponent;
  dataBound() {
    this.fieldData = (this.treegrid as TreeGridComponent).getColumnFieldNames();
  }
  onFieldChange(args: ChangeEventArgs): void {
    this.availableOperators = [];
    (this.operatorDropdown as DropDownListComponent).enabled = true;
    this.column = (this.treegrid as TreeGridComponent).getColumnByField(
      args.value as string
    );
    if (this.column) {
      this.availableOperators =
        this.column.type === 'string'
          ? stringOperatorsData
          : numericOperatorsData;
    }
  }
  onOperatorChange(args: ChangeEventArgs): void {
   
    var filter_column=((this.treegrid as TreeGridComponent).grid.columns as any).filter(
      (x: any) => x.field == (this.column as Column).field
    );
    filter_column[0].filter = { operator: args.value as string };
    
  }
  ngOnInit(): void {
    this.data = sampleData;
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
/**
 * TreeGrid DataSource
 */

export let stringOperatorsData: Object[] = [
    'startsWith',
    'endsWith',
    'contains',
    'isnotempty',
    'isempty',
    'isnotnull',
    'isnull',
    'notEqual',
    'equal',
    'doesnotcontain',
    'doesnotendwith',
    'doesnotstartwith',
  ];
  export let numericOperatorsData: Object[] = [
    'equal',
    'notEqual',
    'greaterThan',
    'greaterThanOrEqual',
    'lessThan',
    'lessThanOrEqual',
    'isnull',
    'isnotnull',
  ];
export let sampleData: Object[] =  [
    {
        taskID: 1,
        taskName: 'Planning',
        startDate: new Date('02/03/2017'),
        endDate: new Date('02/07/2017'),
        progress: 100,
        duration: 5,
        priority: 'Normal',
        approved: false,
        subtasks: [
            { taskID: 2, taskName: 'Plan timeline', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Normal', approved: false },
            { taskID: 3, taskName: 'Plan budget', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Low', approved: true },
            { taskID: 4, taskName: 'Allocate resources', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Critical', approved: false },
            { taskID: 5, taskName: 'Planning complete', startDate: new Date('02/07/2017'),
                endDate: new Date('02/07/2017'), duration: 0, progress: 0, priority: 'Low', approved: true }
        ]
    },
    {
        taskID: 6,
        taskName: 'Design',
        startDate: new Date('02/10/2017'),
        endDate: new Date('02/14/2017'),
        duration: 3,
        progress: 86,
        priority: 'High',
        approved: false,
        subtasks: [
            { taskID: 7, taskName: 'Software Specification', startDate: new Date('02/10/2017'),
                endDate: new Date('02/12/2017'), duration: 3, progress: 60, priority: 'Normal', approved: false },
            { taskID: 8, taskName: 'Develop prototype', startDate: new Date('02/10/2017'),
                endDate: new Date('02/12/2017'), duration: 3, progress: 100, priority: 'Critical', approved: false },
            { taskID: 9, taskName: 'Get approval from customer', startDate: new Date('02/13/2017'),
                endDate: new Date('02/14/2017'), duration: 2, progress: 100, priority: 'Low', approved: true },
            { taskID: 10, taskName: 'Design Documentation', startDate: new Date('02/13/2017'),
                endDate: new Date('02/14/2017'), duration: 2, progress: 100, priority: 'High', approved: true },
            { taskID: 11, taskName: 'Design complete', startDate: new Date('02/14/2017'),
                endDate: new Date('02/14/2017'), duration: 0, progress: 0, priority: 'Normal', approved: true }
        ]
    },
    {
        taskID: 12,
        taskName: 'Implementation Phase',
        startDate: new Date('02/17/2017'),
        endDate: new Date('02/27/2017'),
        priority: 'Normal',
        approved: false,
        duration: 11,
        progress: 66,
        subtasks: [
            {
                taskID: 13,
                taskName: 'Phase 1',
                startDate: new Date('02/17/2017'),
                endDate: new Date('02/27/2017'),
                priority: 'High',
                approved: false,
                progress: 50,
                duration: 11,
                subtasks: [{
                    taskID: 14,
                    taskName: 'Implementation Module 1',
                    startDate: new Date('02/17/2017'),
                    endDate: new Date('02/27/2017'),
                    priority: 'Normal',
                    duration: 11,
                    progress: 10,
                    approved: false,
                    subtasks: [
                        { taskID: 15, taskName: 'Development Task 1', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/19/2017'), duration: 3, progress: '50', priority: 'High', approved: false },
                        { taskID: 16, taskName: 'Development Task 2', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/19/2017'), duration: 3, progress: '50', priority: 'Low', approved: true },
                        { taskID: 17, taskName: 'Testing', startDate: new Date('02/20/2017'),
                            endDate: new Date('02/21/2017'), duration: 2, progress: '0', priority: 'Normal', approved: true },
                        { taskID: 18, taskName: 'Bug fix', startDate: new Date('02/24/2017'),
                            endDate: new Date('02/25/2017'), duration: 2, progress: '0', priority: 'Critical', approved: false },
                        { taskID: 19, taskName: 'Customer review meeting', startDate: new Date('02/26/2017'),
                            endDate: new Date('02/27/2017'), duration: 2, progress: '0', priority: 'High', approved: false },
                        { taskID: 20, taskName: 'Phase 1 complete', startDate: new Date('02/27/2017'),
                            endDate: new Date('02/27/2017'), duration: 0, progress: '50', priority: 'Low', approved: true }

                    ]
                }]
            },
            {
                taskID: 21,
                taskName: 'Phase 2',
                startDate: new Date('02/17/2017'),
                endDate: new Date('02/28/2017'),
                priority: 'High',
                approved: false,
                duration: 12,
                progress: 60,
                subtasks: [{
                    taskID: 22,
                    taskName: 'Implementation Module 2',
                    startDate: new Date('02/17/2017'),
                    endDate: new Date('02/28/2017'),
                    priority: 'Critical',
                    approved: false,
                    duration: 12,
                    progress: 90,
                    subtasks: [
                        { taskID: 23, taskName: 'Development Task 1', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/20/2017'), duration: 4, progress: '50', priority: 'Normal', approved: true },
                        { taskID: 24, taskName: 'Development Task 2', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/20/2017'), duration: 4, progress: '50', priority: 'Critical', approved: true },
                        { taskID: 25, taskName: 'Testing', startDate: new Date('02/21/2017'),
                            endDate: new Date('02/24/2017'), duration: 2, progress: '0', priority: 'High', approved: false },
                        { taskID: 26, taskName: 'Bug fix', startDate: new Date('02/25/2017'),
                            endDate: new Date('02/26/2017'), duration: 2, progress: '0', priority: 'Low', approved: false },
                        { taskID: 27, taskName: 'Customer review meeting', startDate: new Date('02/27/2017'),
                            endDate: new Date('02/28/2017'), duration: 2, progress: '0', priority: 'Critical', approved: true },
                        { taskID: 28, taskName: 'Phase 2 complete', startDate: new Date('02/28/2017'),
                            endDate: new Date('02/28/2017'), duration: 0, progress: '50', priority: 'Normal', approved: false }

                    ]
                }]
            },

            {
                taskID: 29,
                taskName: 'Phase 3',
                startDate: new Date('02/17/2017'),
                endDate: new Date('02/27/2017'),
                priority: 'Normal',
                approved: false,
                duration: 11,
                progress: 30,
                subtasks: [{
                    taskID: 30,
                    taskName: 'Implementation Module 3',
                    startDate: new Date('02/17/2017'),
                    endDate: new Date('02/27/2017'),
                    priority: 'High',
                    approved: false,
                    duration: 11,
                    progress: 60,
                    subtasks: [
                        { taskID: 31, taskName: 'Development Task 1', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/19/2017'), duration: 3, progress: '50', priority: 'Low', approved: true },
                        { taskID: 32, taskName: 'Development Task 2', startDate: new Date('02/17/2017'),
                            endDate: new Date('02/19/2017'), duration: 3, progress: '50', priority: 'Normal', approved: false },
                        { taskID: 33, taskName: 'Testing', startDate: new Date('02/20/2017'),
                            endDate: new Date('02/21/2017'), duration: 2, progress: '0', priority: 'Critical', approved: true },
                        { taskID: 34, taskName: 'Bug fix', startDate: new Date('02/24/2017'),
                            endDate: new Date('02/25/2017'), duration: 2, progress: '0', priority: 'High', approved: false },
                        { taskID: 35, taskName: 'Customer review meeting', startDate: new Date('02/26/2017'),
                            endDate: new Date('02/27/2017'), duration: 2, progress: '0', priority: 'Normal', approved: true },
                        { taskID: 36, taskName: 'Phase 3 complete', startDate: new Date('02/27/2017'),
                            endDate: new Date('02/27/2017'), duration: 0, progress: '50', priority: 'Critical', approved: false },
                    ]
                }]
            }
        ]
    }
];
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Prevent filtering for particular column

In the Tree Grid, you can prevent filtering for a specific column by utilizing the allowFiltering property of the column object and setting it to false. This feature is useful when you want to disable filtering options for a particular column.

Here’s an example that demonstrates how to remove the filter bar for the taskName column in the tree grid:

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' childMapping='subtasks' >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' textAlign='Right' width=90></e-column>
                        <e-column field='taskName' headerText='Task Name' [allowFiltering]=false textAlign='Left' width=180></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' type='date' 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 { 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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Handling filtering at server end based on hierarchy modes

In the TreeGrid component, you can execute filtering actions using the remote data binding feature. This guide provides step-by-step instructions on how to carry out filtering actions with remote data binding, focusing on server-side handling based on hierarchy modes.

When implementing filtering with remote data in the tree grid, it’s essential to manage the server-side logic for handling the filtered records according to the filter hierarchy mode.

For further information about the filter hierarchy mode, refer to this section.

In the following code example, different filter hierarchy modes are handled on the server side. Within the dropdown, the hierarchy mode can be changed. Using the addParams method, the hierarchy mode is passed to the server side. Based on the hierarchy mode, the records are filtered using the PerformFiltering method.

import { Component, ViewChild } from '@angular/core';
import { DataManager, Query, UrlAdaptor } from '@syncfusion/ej2-data';
import { TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns';
@Component({
  selector: 'app-root',
  template: `<div style="padding-top: 7px; display: inline-block">Hierarchy Mode
               <ejs-dropdownlist (change)='onChange($event)'  [dataSource]='dropData' value='Parent' [fields]='fields'></ejs-dropdownlist>
             </div>

             <ejs-treegrid #treegrid [dataSource]='data' [allowPaging]=true [allowFiltering]=true  [treeColumnIndex]='1' height='400' idMapping='TaskID' parentIdMapping='ParentValue' hasChildMapping='isParent' >
                <e-columns>
                  <e-column field='TaskID' headerText='Task ID' width='90' textAlign='Right'></e-column>
                  <e-column field='TaskName' headerText='Task Name' width='180'></e-column>
                  <e-column field='Duration' headerText='Duration' width='80' textAlign='Right'></e-column>
                  </e-columns>
              </ejs-treegrid>
 `,

})
export class AppComponent {
  @ViewChild('treegrid')
  public treeGridObj?: TreeGridComponent;

  public dropData?: Object[] = [
    { id: 'Parent', mode: 'Parent' },
    { id: 'Child', mode: 'Child' },
    { id: 'Both', mode: 'Both' },
    { id: 'None', mode: 'None' },
  ];
  public fields?: Object = { text: 'mode', value: 'id' };

  public data: DataManager = new DataManager({
    adaptor: new UrlAdaptor,
    url: "Home/Datasource",
  });
  onChange(e: ChangeEventArgs): any {
   let mode: any = <string>e.value;
        (this.treeGridObj as TreeGridComponent).filterSettings.hierarchyMode = mode;

        var param = (this.treeGridObj as TreeGridComponent).query.params;
        var filterParam_inx = param.findIndex(x => x.key == 'filter_mode');

        (this.treeGridObj as TreeGridComponent).query.params = param.splice(filterParam_inx);
   
        (this.treeGridObj as TreeGridComponent).query.addParams("filter_mode", mode);
        this.treeGridObj?.clearFiltering();
  }
}

Here’s a code snippet demonstrating server-side handling of filtering action:

 public class ExtDataManagerRequest : DataManagerRequest
 {
     public string filter_mode { get; set; } = "Parent";

 }
 public ActionResult DataSource(ExtDataManagerRequest dm)
 {
     List<TreeData> data = new List<TreeData>();
     data = TreeData.GetTree();
     DataOperations operation = new DataOperations();
     IEnumerable<TreeData> DataSource = data;
     
     if (!(dm.Where != null && dm.Where.Count > 1))
     {
         DataSource = operation.PerformFiltering(DataSource, dm.Where, "and");

     }
    
     if (dm.Search != null && dm.Search.Count > 0) // Searching
     {
         DataSource = operation.PerformSearching(DataSource, dm.Search);
     }
     if (dm.Sorted != null && dm.Sorted.Count > 0 && dm.Sorted[0].Name != null) // Sorting
     {
         DataSource = operation.PerformSorting(DataSource, dm.Sorted);
     }
     if (dm.Where != null && dm.Where.Count > 1) //filtering
     {
         if (dm.filter_mode == "Parent") {
             //Filter the current filter object
             DataSource = operation.PerformFiltering(DataSource, dm.Where[1].predicates, "and");

             //If the filtered data does not contain parent records, create a filter query to filter the parent records of the filtered data.
             var parentPredicates = new List<WhereFilter>();
             //generate predicate of the equivalent parent record of filtered child record
             var parentDataPredicate = new WhereFilter() { Field = "TaskID", value = DataSource.ToList<TreeData>().First().ParentValue, Operator = "equal" };  
             parentPredicates.Add(parentDataPredicate);
             
             var parentData = operation.PerformFiltering(TreeData.tree, parentPredicates, "and");
            
             // concate the parent and filtered records
             DataSource = (DataSource.Cast<TreeData>()).Concat((IEnumerable<TreeData>)parentData);  

         }

         else if (dm.filter_mode == "Child" || dm.filter_mode == "Both") {
             //Filter the current filter object
             DataSource = operation.PerformFiltering(DataSource, dm.Where[1].predicates, "and");  //filter the child records by passing the query
             
             var parentPredicates = new List<WhereFilter>();
             //generate predicate of the equivalent parent record of filtered child record
             var parentDataPredicate = new WhereFilter() { Field = "TaskID", value = DataSource.ToList<TreeData>().First().ParentValue, Operator = "equal" };                       parentPredicates.Add(parentDataPredicate);
             
             var parentData = operation.PerformFiltering(TreeData.tree, parentPredicates, "and");
             
             var childData = operation.PerformFiltering(parentData, dm.Where[1].predicates, "and");
            
             if (parentData.ToList().Count() > 0 && dm.filter_mode == "Both")
             {// concate the parent and filtered records
                 DataSource = (DataSource.Cast<TreeData>()).Concat((IEnumerable<TreeData>)parentData);   
             }
             else if (parentData.ToList().Count() > 0 && dm.filter_mode == "Child")
             {// concate the parent and child filtered records

                 DataSource = (DataSource.Cast<TreeData>()).Concat((IEnumerable<TreeData>)childData);                       }
             else if (parentData.ToList().Count() == 0)
             {
                 var childparentPredicates = new List<WhereFilter>();
                 //generate predicate of the  parent record from filtered record
                 var childparentDataPredicate = new WhereFilter() { Field = "ParentValue", value = null, Operator = "equal" };
                 childparentPredicates.Add(childparentDataPredicate);
                 var parent_Data = operation.PerformFiltering(DataSource, childparentPredicates, "and");
                 //Filter the all the child records
                 var child_Data = TreeData.GetTree().ToList().Where(item => item.ParentValue == parent_Data.ToList<TreeData>().First().TaskID);
                //Concate parnet and child records
                 DataSource = child_Data.Concat((IEnumerable<TreeData>)parent_Data);
             }
         }
         else if(dm.filter_mode =="None")
         {
             //Filter the current filter object
             DataSource = operation.PerformFiltering(DataSource, dm.Where[1].predicates, "and");  //filter the child records by passing the query

         }
     }

     int count = DataSource.ToList<TreeData>().Count;
    
     if (dm.Skip != 0)
     {
         DataSource = operation.PerformSkip(DataSource, dm.Skip);   //Paging
     }
     if (dm.Take != 0)
     {
         DataSource = operation.PerformTake(DataSource, dm.Take);
     }
     return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);

 }

Wildcard and LIKE operator filter

Wildcard and LIKE filter operators filters the value based on the given string pattern, and they apply to string-type columns. But it will work slightly differently.

Wildcard filtering

The Wildcard filter can process one or more search patterns using the “*” symbol, retrieving values matching the specified patterns.

  • The Wildcard filter option is supported for the Tree Grid that has all search options.

For example:

Operator Description
a*b Everything that starts with “a” and ends with “b”.
a* Everything that starts with “a”.
*b Everything that ends with “b”.
a Everything that has an “a” in it.
ab* Everything that has an “a” in it, followed by anything, followed by a “b”, followed by anything.

LIKE filtering

The LIKE filter can process single search patterns using the “%” symbol, retrieving values matching the specified patterns. The following Tree Grid features support LIKE filtering on string-type columns:

For example:

Operator Description
%ab% Returns all the value that are contains “ab” character.
ab% Returns all the value that are ends with “ab” character.
%ab Returns all the value that are starts with “ab” character.

By default, the Tree Grid uses different filter operators for different column types. The default filter operator for string type columns is startsWith, for numerical type columns is equal, and for boolean type columns is also equal.

Diacritics filter

The diacritics filter feature in the tree grid is useful when working with text data that includes accented characters (diacritic characters). By default, the tree grid ignores these characters during filtering. However, if you need to consider diacritic characters in your filtering process, you can enable this feature by setting the filterSettings.ignoreAccent property to true using the filterSettings.

Consider the following sample where the ignoreAccent property is set to true in order to include diacritic characters in the filtering process:

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' [treeColumnIndex]='0' height='275' [allowFiltering]='true' [filterSettings]='filterSettings'childMapping='Children' >
                    <e-columns>
                        <e-column field='EmpID' headerText='Employee ID' textAlign='Right' width=90></e-column>
                        <e-column field='Name' headerText='Name' textAlign='Left' width=180></e-column>
                        <e-column field='DOB' headerText='DOB' textAlign='Right' type='date' format='yMd' width=90></e-column>
                        <e-column field='Country' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public filterSettings?: Object;

    ngOnInit(): void {
        this.data = diacritics;
        this.filterSettings = { ignoreAccent: true };
    }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Filtering with case sensitivity

The Tree Grid provides the flexibility to enable or disable case sensitivity during filtering. This feature is useful when you want to control whether filtering operations should consider the case of characters. It can be achieved by using the enableCaseSensitivity property within the filterSettings of the grid object through the tree grid instance.

Below is an example code demonstrating how to enable or disable case sensitivity while filtering:

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

@Component({
    selector: 'app-container',
    template: `<div>
               <label for="unchecked"> Enable Case Sensitivity </label>
               <ejs-switch id="unchecked" (change)="onToggleCaseSensitive($event)"></ejs-switch>
               </div>
    
                <ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' [filterSettings]='filtersettings' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;
    public data?: Object[];
    public filtersettings?: Object;
    public isCaseSensitive: boolean = false;
    ngOnInit(): void {
        this.data = sampleData;
        this.filtersettings={enableCaseSensitivity: this.isCaseSensitive};
    }
    onToggleCaseSensitive(args:any): void {
      (this.treegrid?.grid.filterSettings as any).enableCaseSensitivity=args.checked;
      
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule,SwitchModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,SwitchModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Enable different filter dialog for a column

The Tree Grid offers the flexibility to customize filtering behavior for different columns by enabling various types of filters such as Menu, Excel. This feature allows you to tailor the filtering experience to suit the specific needs of each column in your tree grid. For example, you might prefer a menu-based filter for a task name column, an Excel-like filter for a Start date column.

It can be achieved by adjusting the column.filter.type property based on your requirements.

Here’s an example where the menu filter is enabled by default for all columns, but you can dynamically modify the filter types through a dropdown:

import { Component, OnInit,ViewChild} from '@angular/core';
import { sampleData } from './datasource';
import { Column, FilterSettingsModel, FilterType,TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { DropDownListComponent, ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns';

@Component({
    selector: 'app-container',
    template: `<div id="content" class="container">
                  <div class="input-container">
                    <label for="fields" class="label">Select Column</label>
                    <ejs-dropdownlist #field id="fields" [dataSource]="fieldData" (change)="onFieldChange($event)"
                      placeholder="Eg: OrderID"></ejs-dropdownlist>
                  </div>
                  <div class="input-container">
                    <label for="types" class="label">Select Filter Type</label>
                    <ejs-dropdownlist #type id="types" [dataSource]="typeData" (change)="onTypeChange($event)"
                      placeholder="Eg: Excel" [enabled]="false"></ejs-dropdownlist>
                  </div>
                </div>
    
                <ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' (dataBound)="dataBound()" [filterSettings]='filterSettings' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;
    
  @ViewChild('type') public typeDropdown?: DropDownListComponent;
    public data?: Object[];
    public filterSettings?: FilterSettingsModel = { type: 'Menu' };
    public columnFilterSettings?: FilterSettingsModel;
    public fieldData: string[] | undefined;
    public typeData: string[] = [];
    public column_inx: any;
    ngOnInit(): void {
        this.data = sampleData;
    }

    dataBound() {
      this.fieldData = (this.treegrid as TreeGridComponent).getColumnFieldNames();
    }
    onFieldChange(args: ChangeEventArgs): void {
      (this.typeDropdown as DropDownListComponent).enabled = true;
      this.typeData = ['Menu', 'Excel'];
      this.column_inx = (this.treegrid as TreeGridComponent).getColumnIndexByField(args.value as string);
    }
    onTypeChange(args: ChangeEventArgs): void {
      this.columnFilterSettings = { type: args.value as FilterType};
      ((this.treegrid as TreeGridComponent).columns[this.column_inx] as Column).filter=this.columnFilterSettings;
      (this.treegrid as TreeGridComponent).refreshColumns();
    }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

You can view the GitHub sample demonstrating different filter dialogs in a TreeGrid column.

Filter grid programmatically with single and multiple values using method

Programmatic filtering in the Tree Grid with single and multiple values allows you to apply filters to specific columns in the tree grid without relying on interactions through the interface.

This can be achieved by utilizing the filterByColumn method of the tree grid.

The following example demostrates, how to programmatically filter the tree grid using single and multiple values for the taskID and taskName columns. This is accomplished by calling the filterByColumn method within an external button click function.

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

@Component({
    selector: 'app-container',
    template: ` <button ejs-button cssClass="e-outline" (click)="onSingleValueFilter()">Filter with single value</button>
                <button ejs-button cssClass="e-outline" style="margin-left:5px" (click)="onMultipleValueFilter()">Filter with multiple values</button>
       
                <ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' [filterSettings]='filterSettings' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;

    public data?: Object[];
    public filterSettings?: FilterSettingsModel = { type: 'Excel' };
    
    ngOnInit(): void {
        this.data = sampleData;
    }

    onSingleValueFilter() {
      (this.treegrid as TreeGridComponent).clearFiltering();
      // filter TaskID column with single value
      (this.treegrid as TreeGridComponent).filterByColumn('taskID', 'equal', 7); 
  }
  onMultipleValueFilter() {
      (this.treegrid as TreeGridComponent).clearFiltering();
      // filter TaskName column with multiple values
      (this.treegrid as TreeGridComponent).filterByColumn('taskName', 'equal', [
          'Planning Complete',
          'Testing',
          'Design complete',
      ]); 
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

How to get filtered records

Retrieving filtered records in the tree grid is essential when you want to work with data that matches the currently applied filters. You can achieve this using available properties in the TreeGrid component.

1.Using the Filtered result property

The filteredResult property of filter module serves to obtain an array of records that correspond to the currently applied filters on the tree grid.

This property retrieves an array of records that match the currently applied filters on the tree grid by leveraging the filter module.

Below is an example demonstrating how to retrieve filtering data in a tree grid using the filteredResult property:

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

@Component({
    selector: 'app-container',
    template: ` <div class="control-section">
                  <div *ngIf="showWarning">
                    <ejs-message id="msg_warning" content="No Records" cssClass="e-content-center"
                      severity="Warning"></ejs-message>
                  </div>
                  <button ejs-button cssClass="e-success" (click)="click()">Get Filtered Data</button>
                  <button ejs-button cssClass="e-danger" (click)="clear()">Clear</button>

                <ejs-treegrid #treegrid id='treegrid' [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' format='yMd' width=90></e-column>
                        <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>
                
                <div *ngIf="showRecords" class="e-content">
                <h3>Filtered Records</h3>
                <ejs-treegrid #filtergrid [dataSource]="filteredData" childMapping='subtasks' allowPaging="true" [height]="200">
                    <e-columns>
                      <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' type='date' format='yMd' width=90></e-column>
                      <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>
            </div>
        </div>`
})
export class AppComponent implements OnInit {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;
     public filteredData?: Object;
    public data?: Object[];
    showRecords?: boolean;
    showWarning?: boolean;

    ngOnInit(): void {
        this.data = sampleData;
    }

   click(): void {
    this.filteredData = (this.treegrid as any).filterModule.filteredResult;
    if (this.filteredData) {
      this.showRecords = true;
    } else {
      this.showRecords = false;
    }
    this.showWarning = !this.showRecords;
  }
  clear(): void {
    (this.treegrid as TreeGridComponent).clearFiltering();
    this.showRecords = false;
    this.showWarning = false;
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';
import { MessageModule } from '@syncfusion/ej2-angular-notifications';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,MessageModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

2.Using the properties in the FilterEventArgs object

Alternatively, you can use the properties available in the FilterEventArgs object to obtain the filter record details.

  • columns: This property returns the collection of filtered columns.

  • currentFilterObject: This property returns the object that is currently filtered.

  • currentFilteringColumn: This property returns the column name that is currently filtered.

To access these properties, you can use the actionComplete event handler as shown below:

actionComplete(args: FilterEventArgs) {
    var column = args.columns;
    var object = args.currentFilterObject;
    var name = args.currentFilteringColumn;
}

Clear filtering using methods

The Tree Grid provides a method called clearFiltering to clear the filtering applied to the tree grid. This method is used to remove the filter conditions and reset the tree grid to its original state.

Here’s an example of how to clear the filtering in a tree grid using the clearFiltering method:

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

@Component({
    selector: 'app-container',
    template: ` <button ejs-button cssClass="e-primary" (click)="onClick()">Clear filter</button>

                <ejs-treegrid #treegrid id='treegrid' [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' childMapping='subtasks' >
                    <e-columns>
                        <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' type='date' 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 {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;
      public data?: Object[];
   
    ngOnInit(): void {
        this.data = sampleData;
    }

    public onClick(): void {
      this.treegrid?.clearFiltering(); //clear filtering for all columns
    }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Filtering events

Filtering events allow you to customize the behavior of the tree grid when filtering is applied. You can prevent filtering for specific columns, show messages, or perform other actions to suit your application’s needs.

To implement filtering events in the Tree Grid, you can utilize the available events such as actionBegin and actionComplete. These events allow you to intervene in the filtering process and customize it as needed.

In the given example, the filtering is prevented for duration column during actionBegin event.

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

@Component({
    selector: 'app-container',
    template: `<div id='message' style='color:red'>{{message}}</div>
                <ejs-treegrid #treegrid id='treegrid' [dataSource]='data' [treeColumnIndex]='1' height='275' [allowFiltering]='true' childMapping='subtasks' (actionBegin)="actionBegin($event)" (actionComplete)="actionComplete($event)">
                    <e-columns>
                        <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' type='date' 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 {

     @ViewChild('treegrid')
     public treegrid:TreeGridComponent | undefined;
      public data?: Object[];
      public message: string ='';
    ngOnInit(): void {
        this.data = sampleData;
    }

    actionBegin(args: any) {
      if (args.requestType == 'filtering' && args.currentFilteringColumn == 'duration') {
          args.cancel = true;
          this.message = 'The ' + args.type + ' event has been triggered and the ' + args.requestType + ' action is cancelled for ' + args.currentFilteringColumn +' column.';
      }
  }

  actionComplete(args: any) {
      if (args.requestType == 'filtering' && args.currentFilteringColumn) {
          this.message = 'The ' + args.type + ' event has been triggered and the ' + args.requestType + ' action for the ' + args.currentFilteringColumn + ' column has been successfully executed';
      } else {
          this.message = '';
      }
  }
}
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 { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
        FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);