Searching in Angular TreeGrid component

24 Apr 202424 minutes to read

The Syncfusion Angular TreeGrid component includes a powerful built-in searching feature that facilitates searching for specific data within the tree grid. This feature enables efficient filtering of tree grid records based on user-defined search criteria, making it easier to locate and display relevant information. Whether you have a large dataset or simply need to find specific records quickly, the search feature provides a convenient solution.

To enable the searching feature in the tree grid, set the allowSearching property to true.

To further enhance the search functionality, you can integrate a search text box directly into the tree grid’s toolbar. This allows you to enter search criteria conveniently within the tree grid interface. To add the search item to the tree grid’s toolbar, use the toolbar property and add Search item.

Here is an example that demonstrates the default searching 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='270'  [toolbar]='toolbarOption' 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 toolbarOption?: string[];

    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOption = ['Search'];
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

The clear icon is shown in the Tree Grid search text box when it is focused on search text or after typing the single character in the search text box. A single click of the clear icon clears the text in the search box as well as the search results in the Tree Grid.

By default, the search operation is performed on the tree grid data after the tree grid renders. However, there might be scenarios where need to perform a search operation on the tree grid data during the initial rendering of the tree grid. In such cases, you can make use of the initial search feature provided by the tree grid.

To apply search at initial rendering, need to set the following properties in the searchSettings object.

Property Description
fields Specifies the fields in which the search operation needs to be performed.
operator Specifies the operator to be used for the search operation.
key Specifies the key value to be searched.
ignoreCase ignoreCase specifies whether the search operation needs to be case-sensitive or case-insensitive.
ignoreAccent ignoreAccent property will ignore the diacritic characters or accents in the text during a search operation.

The following example demonstrates how to set an initial search in the tree grid using the searchSettings property. The searchSettings property is set with the following values:

  1. fields: taskName specifies that the search should be performed only in the ‘taskName’ field.
  2. operator: contains indicates that the search should find records that contain the specified search key.
  3. key: plan is the initial search key that will be applied when the grid is rendered.
  4. ignoreCase: true makes the search case-insensitive.
  5. ignoreAccent: true ignores diacritic characters or accents during the search operation.
import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' [treeColumnIndex]='1' height='270' [toolbar]='toolbarOption' childMapping='subtasks' [searchSettings]='searchSettings' >
                    <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 toolbarOption?: string[];
    public searchSettings?: Object;
    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOption = ['Search'];
        this.searchSettings = { fields: ['taskName'], operator: 'contains', key: 'plan', ignoreCase: true,ignoreAccent:true };
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

By default, tree grid searches all the bound column values. However, you can customize this behavior by definining the searchSettings.fields property.

Search operators

Search operators are symbols or keywords used to define the type of comparison or condition applied during a search operation. They help specify how the search key should match the data being searched. The searchSettings.operator property can be used to define the search operator in the tree grid.

By default, the searchSettings.operator is set to contains, which returns the values contains the search key. The following operators are supported in searching:

Operator  Description
startswith  Checks whether a value begins with the specified value.
endswith  Checks whether a value ends with the specified value.
contains  Checks whether a value contains with the specified value.
wildcard Processes one or more search patterns using the “*“ symbol, returning values that match the given patterns.
like Processes a single search pattern using the ”%” symbol, retrieving values that match the specified pattern.
equal  Checks whether a value equal to the specified value.
notequal  Checks whether a value not equal to the specified value.

These operators provide flexibility in defining the search behavior and allow you to perform different types of comparisons based on your requirements.

The following example demonstrates how to set the searchSettings.operator property based on changing the dropdown value using the change event of the DropDownList component.

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


@Component({
    selector: 'app-container',
    template: `<div style="display: flex">
                  <label style="padding:  10px 10px 26px 0">Change the search operators:</label>
                  <ejs-dropdownlist style="margin-top:5px" id="value" #dropdown index="0" width="100" [dataSource]="ddlData" [fields]='fields' (change)="valueChange($event)"></ejs-dropdownlist>
                </div>
    
                <ejs-treegrid #treegrid [dataSource]='data' [treeColumnIndex]='1' height='270' [toolbar]='toolbarOptions' childMapping='subtasks' [searchSettings]='searchSettings' >
                    <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 toolbarOptions?: ToolbarItems[];
    public searchSettings?: SearchSettingsModel
    @ViewChild('treegrid') public treegrid?: TreeGridComponent;
    public fields?: object = { text: 'text', value: 'value' };
    public ddlData?: object[] = [
      { text: 'startswith', value: 'startswith' },
      { text: 'endswith', value: 'endswith' },
      { text: 'wildcard', value: 'wildcard' },
      { text: 'like', value: 'like' },
      { text: 'equal', value: 'equal' },
      { text: 'not equal', value: 'notequal' },
    ];
    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
        this.searchSettings = { operator: 'contains' };
      }
      valueChange(args: ChangeEventArgs): void {
        (this.treegrid as TreeGridComponent).searchSettings.operator = args.value as string; 
      }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Search by external button

The TreeGrid component allows you to perform searches programmatically, enabling you to search for records using an external button instead of relying solely on the built-in search bar. This feature provides flexibility and allows for custom search implementations within your application. To search for records using an external button, you can utilize the search method provided by the TreeGrid component.

The search method allows you to perform a search operation based on a search key or criteria. The following example demonstatres how to implement search by an external button using the following steps:

  1. Add a button element outside of the TreeGrid component.
  2. Attach a click event handler to the button.
  3. Inside the event handler, get the reference of the TreeGrid component.
  4. Invoke the search method of the tree grid by passing the search key as a parameter.
import { Component, OnInit, ViewChild } from '@angular/core';
import { sampleData } from './datasource';
import { TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import {TextBoxComponent} from '@syncfusion/ej2-angular-inputs';

@Component({
    selector: 'app-container',
    template: `<div class="e-float-input" style="width: 120px; display: inline-block;">
                    <ejs-textbox #searchInput width="100" placeholder="Search text"></ejs-textbox>
                    <span class="e-float-line"></span>
                </div>
                <button ejs-button id='search' (click)='search()'>Search</button>

                <ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' 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[];
    @ViewChild('treegrid') public treegrid?: TreeGridComponent;
    @ViewChild('searchInput') public searchInput?: TextBoxComponent;
    ngOnInit(): void {
        this.data = sampleData;
        
    }
    search() {
        const searchText: string = (this.searchInput as TextBoxComponent).value;
        (this.treegrid as TreeGridComponent).search(searchText);
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,TextBoxModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Search specific columns

By default, the search functionality searches all visible columns. However, if you want to search only specific columns, you can define the specific column’s field names in the searchSettings.fields property. This allows you to narrow down the search to a targeted set of columns, which is particularly useful when dealing with large datasets or tree grids with numerous columns.

The following example demonstrates how to search specific columns such as taskName and progress by using the searchSettings.fields property.

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' childMapping='subtasks' [searchSettings]='searchSettings'>
                    <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='progress' headerText='Progress'></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 toolbarOptions?: ToolbarItems[];
    public searchSettings?: SearchSettingsModel;
    @ViewChild('treegrid') public treegridObj?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.searchSettings = { fields: ['taskName','progress']};
        this.toolbarOptions = ['Search'];
    }

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

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Search on each key stroke

The search on each keystroke feature in the Tree Grid enables you to perform real-time searching of tree grid data as they type in the search text box. This functionality provides a seamless and interactive searching experience, allowing you to see the search results dynamically updating in real time as they enter each keystroke in the search box

To achieve this, you need to bind the keyup event to the search input element inside the created event of the TreeGrid component.

In the following example, the created event is bound to the TreeGrid component, and inside the event handler, the keyup event is bound to the search input element. Whenever the keyup event is triggered, the current search string is obtained from the search input element, and the search method is invoked on the tree grid instance with the current search string as a parameter. This allows the search results to be displayed in real-time as you type in the search box.

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' childMapping='subtasks' (created)='created($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' 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 toolbarOptions?: ToolbarItems[];
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
    }
    created(args: any): void {
        (document.getElementById((this.treegrid as TreeGridComponent).grid.element.id + "_searchbar") as HTMLElement).addEventListener('keyup', () => {
                (this.treegrid as TreeGridComponent).search(((event as MouseEvent).target as HTMLInputElement).value)
        });
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Search on each key stroke approach may affect the performance of the application when dealing with a large number of records.

Perform search based on column formatting

By default, the search operation considers the underlying raw data of each cell for searching. However, in some cases, you may want to search based on the formatted data visible to the users. To search data based on column formatting, you can utilize the grid.valueFormatterService.fromView method within the actionBegin event. This method allows you to retrieve the formatted value of a cell and perform searching on each column using the OR predicate.

The following example demonstrates how to implement searching based on column formatting in the Tree Grid. In the actionBegin event, retrieve the search value from the getColumns method. Iterate through the columns and check whether the column has a format specified. If the column has a format specified, use the grid.valueFormatterService.fromView method to get the formatted value of the cell. If the formatted value matches the search value, set the OR predicate that includes the current column filter and the new filter based on the formatted value.

import { Component, OnInit, ViewChild } from '@angular/core';
import { sampleData } from './datasource';
import { ToolbarItems, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { SearchEventArgs, KeyboardEventArgs } from '@syncfusion/ej2-angular-grids';
import { Query, Predicate } from '@syncfusion/ej2-data';
@Component({
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' childMapping='subtasks' (actionBegin)="actionBegin($event)" (keyPressed)="keyPressed($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' 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 toolbarOptions?: ToolbarItems[];
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
    }
    actionBegin(args:any) {
      if (args.requestType == 'searching') {
          args.cancel = true;
          setTimeout(() => {
            var columns = (this.treegrid as TreeGridComponent).grid.getColumns();
            var predicate = null;
            for (var i = 0; i < columns.length; i++) {
            
              var val = (this.treegrid as TreeGridComponent).grid.valueFormatterService.fromView(
                args.searchString as string,
                (columns[i] as any).getParser(),
                columns[i].type
              );
              if (val) {
                if (predicate == null) {
                  predicate = new Predicate(columns[i].field,'contains',val,true, true);
                } else {
                  predicate = predicate.or(columns[i].field,'contains',val,true, true);
                }
              }
            }
            (this.treegrid as TreeGridComponent).query = new Query().where(predicate as Predicate);
          }, 200);
      }
  }

  keyPressed(args: any) {
      if (
        args.key == 'Enter' &&
        args.target instanceof HTMLElement &&
        args.target.closest('.e-search') &&
        (args.target as HTMLInputElement).value == ''
      ) {
        args.cancel = true;
        (this.treegrid as TreeGridComponent).query = new Query();
      }
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,TextBoxModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Perform search operation in Grid using multiple keywords

In addition to searching with a single keyword, the TreeGrid component offers the capability to perform a search operation using multiple keywords. This feature enables you to narrow down your search results by simultaneously matching multiple keywords. It can be particularly useful when you need to find records that meet multiple search conditions simultaneously. This can be achieved by the actionBegin event of the Tree Grid.

The following example demonstrates, how to perform a search with multiple keywords in the tree grid by using the query property when the requestType is searching in the actionBegin event. The searchString is divided into multiple keywords using a comma (,) as the delimiter. Each keyword is then utilized to create a predicate that checks for a match in the desired columns. If multiple keywords are present, the predicates are combined using an OR condition. Finally, the Tree Grid’s query property is updated with the constructed predicate, and the Tree Grid is refreshed to update the changes in the UI.

On the other hand, the actionComplete event is used to manage the completion of the search operation. It ensures that the search input value is updated if necessary and clears the query when the search input is empty.

import { Component, OnInit, ViewChild } from '@angular/core';
import { sampleData } from './datasource';
import { Column, SearchSettingsModel, ToolbarItems, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { SearchEventArgs, KeyboardEventArgs } from '@syncfusion/ej2-angular-grids';
import { Query, Predicate } from '@syncfusion/ej2-data';

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [searchSettings]='searchOptions' [toolbar]='toolbarOptions' 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='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' width=80></e-column>
                        <e-column field='priority' headerText='Priority' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public toolbarOptions?: ToolbarItems[];
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;
    public values?: string;
    public key = '';
    public removeQuery = false;
    public valueAssign = false;
    public searchOptions?: SearchSettingsModel;
    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
        this.searchOptions = {
          fields: [
              'taskID',
              'taskName',
              'duration',
              'progress',
              'priority'
          ],
          operator: 'contains',
          key: '',
          ignoreCase: true,
      };
    }
    actionBegin({ requestType, searchString }: SearchEventArgs) {
      if (requestType == 'searching') {
          const keys = (searchString as string).split(',');
          var flag = true;
          var predicate: any;
          if (keys.length > 1) {
              if ((this.treegrid as TreeGridComponent).searchSettings.key !== '') {
                  this.values = searchString;
                  keys.forEach((key: string) => {
                      (this.treegrid as TreeGridComponent).getColumns().forEach((col: Column) => {
                          if (flag) {
                              predicate = new Predicate(col.field, 'contains', key, true);
                              flag = false;
                          }
                          else {
                              var predic = new Predicate(col.field, 'contains', key, true);
                              predicate = predicate.or(predic);
                          }
                      });
                  });
                  
                  (this.treegrid as TreeGridComponent).query = new Query().where(predicate);
                  (this.treegrid as TreeGridComponent).searchSettings.key = '';
                  this.valueAssign = true;
                  this.removeQuery = true;
                  (this.treegrid as TreeGridComponent).refresh();
              }
          }
      }
  }
  actionComplete(args: SearchEventArgs) {
      if (args.requestType === 'refresh' && this.valueAssign) {
          const searchBar = document.querySelector<HTMLInputElement>('#' + (this.treegrid as TreeGridComponent).element.id + '_searchbar');
          if (searchBar) {
              searchBar.value = this.values || '';
              this.valueAssign = false;
          }
          else if (
              args.requestType === 'refresh' &&
              this.removeQuery
          ) {
              const searchBar = document.querySelector<HTMLInputElement>('#' + (this.treegrid as TreeGridComponent).element.id + '_searchbar');
              if (searchBar) {
                  searchBar.value = '';
              }
              (this.treegrid as TreeGridComponent).query = new Query();
              this.removeQuery = false;
              (this.treegrid as TreeGridComponent).refresh();
          }
      }
  }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,TextBoxModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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 ignore accent while searching

By default, the searching operation in the TreeGrid component does not ignore diacritic characters or accents. However, there are cases where ignoring diacritic characters becomes necessary. This feature enhances the search experience by enabling data searching without considering accents, ensuring a more comprehensive and accurate search and it can be achieved by utilizing the searchSettings.ignoreAccent property of the TreeGrid component as true.

The following example demonstrates how to define the ignoreAccent property within the searchSettings property of the tree grid. Additionally, the EJ2 Toggle Switch Button component is included to modify the value of the searchSettings.ignoreAccent property. When the switch is toggled, the change event is triggered, and the searchSettings.ignoreAccent property is updated accordingly. This functionality helps to visualize the impact of the searchSettings.ignoreAccent setting when performing search operations.

import { Component, OnInit, ViewChild } from '@angular/core';
import { diacritics } from './datasource';
import { ToolbarItems, SearchSettingsModel, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { SearchEventArgs } from '@syncfusion/ej2-angular-grids';
import { Predicate, Query } from '@syncfusion/ej2-data';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-buttons';

@Component({
    selector: 'app-container',
    template: `<div>
                <label style="padding: 10px 10px">Enable or disable ignoreAccent property</label>
                <ejs-switch id="switch" [checked]=true (change)="onSwitchChange($event)"></ejs-switch>
               </div>
                <ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' childMapping='Children'>
                    <e-columns>
                        <e-column field='EmpID' headerText='ID' textAlign='Right' width=90></e-column>
                        <e-column field='Name' headerText='Name' textAlign='Left' width=180></e-column>
                        <e-column field='Designation' headerText='Designation' textAlign='Right' width=150></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {
    
    public data?: Object[];
    public toolbarOptions?: ToolbarItems[];
    @ViewChild('treegrid') public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = diacritics;
        this.toolbarOptions = ['Search'];
    }
    onSwitchChange(args: any) {
        if (args.checked) {
            ((this.treegrid as TreeGridComponent).grid.searchSettings as any).ignoreAccent = true;
        } else {
           ((this.treegrid as TreeGridComponent).grid.searchSettings as any).ignoreAccent = false;
        }
    }
   }
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } 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';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,SwitchModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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 set searchSettings.ignoreAccent property along with other search settings such as fields, operator, and ignoreCase to achieve the desired search behavior.
  • This feature works only for the characters that are not in the ASCII range.
  • This feature may have a slight impact on search performance.

Highlight the search text

The TreeGrid component allows you to visually highlight search results within the displayed data. This feature helps you to quickly identify where the search items are found within the displayed data. By adding a style to the matched text, you can quickly identify where the search items are present in the tree grid.

To achieve search text highlighting in the Tree Grid, you can utilize the queryCellInfo event. This event is triggered for each cell during the Tree Grid rendering process, allowing you to customize the cell content based on your requirements.

The following example demonstrates how to highlight search text in tree grid using the queryCellInfo event. The queryCellInfo event checks if the current cell is in the desired search column, retrieves the cell value, search keyword and uses the includes method to check if the cell value contains the search keyword. If it does, the matched text is replaced with the same text wrapped in a span tag with a customcss class. You can then use CSS to define the customcss class and style to easily identify where the search keywords are present in the tree grid.

import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { sampleData } from './datasource';
import { ToolbarItems, SearchSettingsModel, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { QueryCellInfoEventArgs, SearchEventArgs } from '@syncfusion/ej2-angular-grids';


@Component({
    selector: 'app-container',
    encapsulation:ViewEncapsulation.None,
    template: `<ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' (actionBegin)="actionBegin($event)" (queryCellInfo)="queryCellInfo($event)" 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='priority' headerText='Priority' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`,
    styles:[`.e-rowcell .customcss{
          background-color:yellow;
    }`]
})
export class AppComponent implements OnInit {
   
    public key = '';
    public data?: Object[];
    public toolbarOptions?: ToolbarItems[];
   
    @ViewChild('treegrid') public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
    }
    actionBegin(args: SearchEventArgs) {
       
        if (args.requestType === 'searching') {
            (this.key as string) = (args.searchString as string).toLowerCase();
        }
    }
   queryCellInfo(args: QueryCellInfoEventArgs) {
        if ((this.key as string) != '') {
          var cellContent = (args.data as any)[(args.column as any).field];
          var parsedContent = cellContent.toString().toLowerCase();
          if (parsedContent.includes((this.key as string).toLowerCase())) {
            var i = 0;
            var searchStr = '';
            while (i < (this.key as string).length) {
              var index = parsedContent.indexOf((this.key as string)[i]);
              searchStr = searchStr + cellContent.toString()[index];
              i++;
            }
            (args.cell as HTMLElement).innerHTML = ((args.cell as HTMLElement).innerText as any).replaceAll(
              searchStr,
              "<span class='customcss'>" + searchStr + '</span>'
            );
          }
        }
    }
  }
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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);

Clear search by external button

The TreeGrid component provides a capability to clear searched data in the tree grid. This functionality offers the ability to reset or clear any active search filters that have been applied to the tree grid’s data.

To clear the searched tree grid records from an external button, you can set the searchSettings.key property to an empty string to clear the search text. This property represents the current search text in the search box.

The following example demonstrates how to clear the searched records using an external button.

import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { sampleData } from './datasource';
import { ToolbarItems, SearchSettingsModel, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { QueryCellInfoEventArgs, SearchEventArgs } from '@syncfusion/ej2-angular-grids';
import { Predicate, Query } from '@syncfusion/ej2-data';

@Component({
    selector: 'app-container',
    encapsulation:ViewEncapsulation.None,
    template: `<button ejs-button id='clear' (click)='clearSearch()'>Clear Search</button>
                <ejs-treegrid #treegrid [dataSource]='data' height='270' [treeColumnIndex]='1' [toolbar]='toolbarOptions' [searchSettings]='searchOptions' 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='priority' headerText='Priority' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`,
})
export class AppComponent implements OnInit {
   
     public searchOptions?: SearchSettingsModel;
    public data?: Object[];
    public toolbarOptions?: ToolbarItems[];
   
    @ViewChild('treegrid') public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.toolbarOptions = ['Search'];
         this.searchOptions = { fields: ['taskName'], operator: 'contains', key: 'plan', ignoreCase: true};
   
    }
    clearSearch() {
      (this.treegrid as TreeGridComponent).searchSettings.key = '';
  }
  }
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PageService, SortService, FilterService,ToolbarService,TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                ToolbarService]
})
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 also clear the searched records by using the clear icon within the search input field.

See also