HelpBot Assistant

How can I help you?

Filter Bar in Angular Grid Component

19 Mar 202624 minutes to read

The filter bar feature provides a row of input fields directly below the grid headers, enabling instant data filtering. Each column displays an input field where filter criteria can be entered, and the grid updates immediately to show matching results.

To activate the filter bar, set the allowFiltering property to true and include the FilterService in the providers array.

Filter bar expressions:

Filter expressions are operators that define how the grid compares entered values against data. The available operators depend on the column data type.

Expression Example Description Column Type
= =value Matches values exactly equal to the entered value Number
!= !=value Matches values not equal to the entered value Number
> >value Matches values greater than the entered value Number
< <value Matches values less than the entered value Number
>= >=value Matches values greater than or equal to the entered value Number
<= <=value Matches values less than or equal to the entered value Number
* *value Matches values that start with the entered text String
% %value Matches values that end with the entered text String
N/A N/A Always uses equal operator for Date columns Date
N/A N/A Always uses equal operator for Boolean columns Boolean

The following example demonstrates basic filter bar activation in the grid:

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons';
import { CheckBoxSelectionService, DropDownListAllModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterService, FilterSettingsModel, GridModule, PageService, PageSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [  
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule
        ],
    providers: [FilterService, PageService,CheckBoxSelectionService],
    standalone: true,
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]="pageSettings" [allowFiltering]='true' height='150px' [filterSettings]='filterSettings'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='OrderDate' headerText='Ship City' width=100 format='yMd'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=100></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public filterSettings?: FilterSettingsModel;
    public pageSettings?: PageSettingsModel = { pageSize: 5 };

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

To enable or dynamically switch the filter type, set the filterSettings.type as FilterBar mode.

Filter bar modes

The Syncfusion Angular Grid filter bar operates in two distinct modes that determine when filtering actions are triggered. These modes provide different user experiences based on application requirements and user preferences.

OnEnter Mode:

When filterSettings.mode is set to OnEnter, the filter bar captures filter criteria but delays filtering execution until the Enter key is pressed. This mode is beneficial when:

  • Users need to enter complex filter criteria without triggering multiple filtering operations.
  • Working with large datasets where immediate filtering might cause performance issues.
  • Users prefer to review and confirm their filter criteria before applying changes.

Immediate Mode:

When filterSettings.mode is set to Immediate, the filter bar applies filtering instantly as users type or modify filter criteria. This mode provides:

  • Real-time filtering feedback and immediate result previews.
  • Enhanced user experience for quick data searches.
  • Instant visual confirmation of filter effects.
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { ButtonModule, CheckBoxModule } from '@syncfusion/ej2-angular-buttons';
import { ChangeEventArgs, CheckBoxSelectionService, DropDownListAllModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterBarMode, FilterService, FilterSettingsModel, GridModule, PageService, PageSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [ 
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule,
        ButtonModule
        ],
    providers: [FilterService, PageService,CheckBoxSelectionService],
    standalone: true,
    selector: 'app-root',
    template: `<div class='input-container'>
			    <label for='fields' class='label'>Select Filter Mode</label>
			    <ejs-dropdownlist #field id='fields' [dataSource]='filterModesData' (change)='onModeChange($event)' [fields]="{ text: 'text', value: 'value' }"></ejs-dropdownlist>
               </div>
               <ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]="pageSettings" [allowFiltering]='true' height='150px' [filterSettings]='filterSettings'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='OrderDate' headerText='Ship City' width=100 format='yMd'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=100></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public filterSettings!: FilterSettingsModel;
    public pageSettings: PageSettingsModel = { pageSize: 5 };
    public filterModesData: { text: string; value: FilterBarMode }[] = [
        { text: 'Immediate', value: 'Immediate' },
        { text: 'OnEnter', value: 'OnEnter' },
    ];

    ngOnInit(): void { 
        this.data = data;
    }
   onModeChange(args: ChangeEventArgs): void {
    const mode = (
      typeof args.value === 'string' ? args.value : 'Immediate'
    ) as FilterBarMode;
    this.filterSettings = { mode };
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Display filter text in pager

The showFilterBarStatus property displays the current filter criteria in the grid pager area. This provides a clear summary of active filters without examining each column’s filter bar input.

When to use: Enable this when working with complex multi-column filters to maintain awareness of all active filtering criteria. This is particularly useful when filters are applied across columns that are scrolled out of view.

The following example shows filter status display in the pager:

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { ButtonModule, ChangeEventArgs, CheckBoxModule, SwitchModule } from '@syncfusion/ej2-angular-buttons';
import { CheckBoxSelectionService, DropDownListAllModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterService, FilterSettingsModel, GridModule, PageService, PageSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [ 
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule,
        ButtonModule,
        SwitchModule
        ],
    providers: [FilterService, PageService,CheckBoxSelectionService],
    standalone: true,
    selector: 'app-root',
    template: ` <div class='container'>
                    <label for="checked"> <b> Show filter bar status </b> </label>
                    <ejs-switch id="checked" [checked]="true" (change)="onChange($event)"></ejs-switch>
                </div>
                <ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]='pageSettings' [allowFiltering]='true' height='150px' [filterSettings]='filterSettings'>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='OrderDate' headerText='Ship City' width=100 format='yMd'></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                        <e-column field='ShipName' headerText='Ship Name' width=100></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public filterSettings!: FilterSettingsModel;
    public pageSettings: PageSettingsModel = { pageSize: 5 };

    ngOnInit(): void {
        this.data = data;
    }
    onChange(args: ChangeEventArgs): void {
        this.filterSettings = {
            showFilterBarStatus: args.checked,
        };
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Show or hide filter bar operator in filter bar cell

The showFilterBarOperator property displays a dropdown in each filter bar cell, allowing the filter operator to be changed directly in the UI. By default, string columns use the startswith operator, but this can be changed to contains, endswith, equal, etc.

To display the operator dropdown in filter bar cells, set the showFilterBarOperator property of the filterSettings configuration to true. By default, this property is set to false.

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { ButtonModule, ChangeEventArgs, CheckBoxModule, SwitchModule } from '@syncfusion/ej2-angular-buttons';
import { CheckBoxSelectionService, DropDownListAllModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterService, FilterSettingsModel, GridModule, PageService, PageSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule,
        ButtonModule,
        SwitchModule
        ],
    providers: [FilterService, PageService,CheckBoxSelectionService],
    standalone: true,
    selector: 'app-root',
    template: ` <div class='container'>
                    <label for="checked"> <b> Show filter bar operator </b> </label>
                    <ejs-switch id="checked" (change)="onChange($event)"></ejs-switch>
                </div>
                <ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]='pageSettings' [allowFiltering]='true' height='150px' [filterSettings]='filterSettings'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='OrderDate' headerText='Ship City' width=100 format='yMd'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=100></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public filterSettings!: FilterSettingsModel;
    public pageSettings: PageSettingsModel = { pageSize: 5 };

    ngOnInit(): void {
        this.data = data;
    }
    onChange(args: ChangeEventArgs): void {
        this.filterSettings = {
            showFilterBarOperator: args.checked,
        };
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Prevent filtering for particular column

Set the allowFiltering property to false on a column to disable the filter bar input for that specific column. Disable filtering on non-filterable columns like action (button) columns, image columns, etc.

The following example disables filtering for the “Customer ID” column.

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterService, GridModule, GroupService, PageService, SortService } from '@syncfusion/ej2-angular-grids';

@Component({
  imports: [ GridModule, DropDownListAllModule],
  providers: [ PageService, SortService, FilterService, GroupService],
  standalone: true,
  selector: 'app-root',
  template: `<ejs-grid [dataSource]='data' [allowFiltering]='true' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120 [allowFiltering]='false'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=100 ></e-column>
                </e-columns>
                </ejs-grid>`,
})
export class AppComponent implements OnInit {
  public data?: object[];

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

Hide filter bar for template column

Template columns can be used to render images, action buttons, or other custom components that are inherently non-filterable. To completely hide the filter bar input for a template column, use the filterTemplate property with an empty element.

The following example demonstrates to hide the filter bar for a template column:

import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { Column, FilterService, GridComponent, GridModule, GroupService, PageService, SortService } from '@syncfusion/ej2-angular-grids';

@Component({
  imports: [GridModule,ButtonModule],
  providers: [PageService,SortService,FilterService,GroupService],
  standalone: true,
  selector: 'app-root',
  template: `
  <ejs-grid #grid [dataSource]="data" allowFiltering="true" height="220" (load)="load()" allowPaging="true">
  <e-columns>
      <e-column field="OrderID" headerText="Order ID" width="120" textAlign="Right"></e-column>
      <e-column field="CustomerID" headerText="Customer Name" width="150"></e-column>
      <e-column headerText="Action" width="150">
          <ng-template #template let-data>
              <button ejs-button >Custom action</button>
          </ng-template>
      </e-column>
  </e-columns>`,
})
export class AppComponent implements OnInit {
  @ViewChild('grid')
  public grid?: GridComponent;
  public data?: object[];
  public pageSettings: Object = { pageCount: 5 };

  ngOnInit(): void {
    this.data = data;
  }
  load() {
    // Set filterTemplate to an empty span to hide the filter bar for the template column
    ((this.grid as GridComponent).columns[2] as Column).filterTemplate = '<span></span>';
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Filter bar template with custom component

The filterBarTemplate property replaces the default text input with a custom component in the filter bar. This allows using specialized input controls like date pickers, dropdowns, or numeric inputs that provide a better filtering experience for specific data types.

Custom filter bar templates are particularly useful when:

  • Default text input doesn’t provide optimal user experience for specific data types.
  • Specialized filtering controls are required for complex data structures.
  • Application design requires consistent component usage across the interface.
  • Users need guided input through dropdown selections or date pickers.

To implement a custom filter bar template, define the filterBarTemplate property within the column configuration:

import { data } from './datasource';
import { Component, ViewChild } from '@angular/core';
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons';
import { CheckBoxSelectionService, DropDownListAllModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { FilterService, GridComponent, GridModule, IFilterUI, PageService, parentsUntil } from '@syncfusion/ej2-angular-grids';
import { DatePicker } from '@syncfusion/ej2-calendars';
import { DataManager, DataUtil, Predicate, Query } from '@syncfusion/ej2-data';
import { ComboBox, DropDownList, MultiSelect } from '@syncfusion/ej2-dropdowns';
import { NumericTextBox } from '@syncfusion/ej2-inputs';

@Component({
    imports: [
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule
    ],
    providers: [FilterService, PageService,CheckBoxSelectionService],
    standalone: true,
    selector: 'app-root',
    templateUrl: 'app.template.html'
})
export class AppComponent {
    public pageSettings?: Object;
    public orderidrules?: Object;
    public templateOptionsDropDown?: IFilterUI;
    public templateOptionsNumericTextBox?: IFilterUI;
    public templateOptionsDatePicker?: IFilterUI;
    public templateOptionsComboBox?: IFilterUI;
    public templateOptionsMultiSelect?: IFilterUI;
    public shipCountryDistinctData?: object[];
    public shipCityDistinctData?: object[];
    public data?: object[];
    public dropdown?: HTMLElement;
    public numElement?: HTMLInputElement;
    public dateElement?: HTMLInputElement;
    public comboelement?: HTMLElement;
    public multiselectelement?: HTMLElement;
    @ViewChild('grid')
    public grid?: GridComponent;
    public handleFilterChange(args: { element: Element; value: string }) {
        let targetElement = parentsUntil(args.element, 'e-filtertext');
        let columnName: string = targetElement.id.replace('_filterBarcell', '');
        if (args.value) {
            (this.grid as GridComponent).filterByColumn(columnName, 'equal', args.value);
        } else {
            (this.grid as GridComponent).removeFilteredColsByField(columnName);
        }
    } public multiselectFunction(args: { value: string }) {
        var selectedValues = args.value;
        if (selectedValues.length === 0) {
            var OrginalData = new DataManager(this.data).executeLocal(new Query());
            (this.grid as GridComponent).dataSource = OrginalData;
        } else {
            var predicate: Predicate | null = null;
            for (let x = 0; x < selectedValues.length; x++) {
                if (predicate === null) {
                    predicate = new Predicate('ShipCountry', 'equal', selectedValues[x]);
                } else {
                    predicate = predicate.or('ShipCountry', 'equal', selectedValues[x]);
                }
            }
            var filteredData = new DataManager(this.data).executeLocal(new Query().where(predicate as Predicate));
            (this.grid as GridComponent).dataSource = filteredData;
        }
    }
    public dropdownFunction(args: { value: string; item: { parentElement: { id: string } } }
    ) {
        if (args.value !== 'All') {
            (this.grid as GridComponent).filterByColumn(args.item.parentElement.id.replace('_options', ''), 'equal', args.value);
        } else {
            (this.grid as GridComponent).removeFilteredColsByField(args.item.parentElement.id.replace('_options', ''));
        }
    }

    public ngOnInit(): void {
        this.data = data;
        this.pageSettings = { pageCount: 5 };
        this.orderidrules = { required: true };

        this.shipCityDistinctData = DataUtil.distinct(data, 'ShipCity', true);
        this.shipCountryDistinctData = DataUtil.distinct(data, 'ShipCountry', true);

        this.templateOptionsDropDown = {
            create: () => {
                this.dropdown = document.createElement('select');
                this.dropdown.id = 'CustomerID';

                var option = document.createElement('option');
                option.value = 'All';
                option.innerText = 'All';
                this.dropdown.appendChild(option);

                (this.data as Object[]).forEach((item: object) => {
                    const option = document.createElement('option');
                    option.value = (item as ItemType).CustomerID;
                    option.innerText = (item as ItemType).CustomerID;
                    (this.dropdown as HTMLElement).appendChild(option);
                });
                return this.dropdown;
            },
            write: () => {
                const dropdownlist = new DropDownList({
                    change: this.dropdownFunction.bind(this),
                });
                dropdownlist.appendTo(this.dropdown);
            },
        };
        this.templateOptionsNumericTextBox = {
            create: () => {
                this.numElement = document.createElement('input');
                return this.numElement;
            },
            write: () => {
                const numericTextBox = new NumericTextBox({
                    format: '00.00',
                    value: 10,
                });
                numericTextBox.appendTo(this.numElement);
            },
        };
        this.templateOptionsDatePicker = {
            create: () => {
                this.dateElement = document.createElement('input');
                return this.dateElement;
            },
            write: (args: { column: { field: string | number | Date } }) => {
                const datePickerObj = new DatePicker({
                    value: new Date(args.column.field),
                    change: this.handleFilterChange.bind(this),
                });
                datePickerObj.appendTo(this.dateElement);
            },
        };
        this.templateOptionsComboBox = {
            create: () => {
                this.comboelement = document.createElement('input');
                this.comboelement.id = 'ShipCity';
                return this.comboelement;
            },
            write: (args: { value: string }) => {
                const comboBox = new ComboBox({
                    value: args.value,
                    placeholder: 'Select a city',
                    change: this.handleFilterChange.bind(this),
                    dataSource: (this.shipCityDistinctData as object[]).map(
                        (item: object) => (item as ItemType).ShipCity
                    ),
                });
                comboBox.appendTo(this.comboelement);
            },
        };
        this.templateOptionsMultiSelect = {
            create: () => {
                this.multiselectelement = document.createElement('input');
                this.multiselectelement.id = 'ShipCountry';
                return this.multiselectelement;
            },
            write: (args: { value: string[] | number[] | boolean[] | undefined }) => {
                const multiselect = new MultiSelect({
                    value: args.value,
                    placeholder: 'Select a country',
                    change: this.multiselectFunction.bind(this),
                    dataSource: (this.shipCountryDistinctData as object[]).map(
                        (item: object) => (item as ItemType).ShipCountry

                    ),
                });
                multiselect.appendTo(this.multiselectelement);
            },
        };
    }
}

interface ItemType {
    CustomerID: string,
    ShipCity: string,
    ShipCountry: string
}
<div class="control-section">
    <ejs-grid #grid [dataSource]="data" [allowPaging]="true" [pageSettings]="pageSettings" [allowFiltering]="true" [allowSorting]="true" height='250px'>
        <e-columns>
            <e-column field="OrderID" headerText="Order ID" width="120" textAlign="Right"
                [validationRules]="orderidrules" isPrimaryKey="true"></e-column>
            <e-column field="CustomerID" headerText="Customer ID" width="120" textAlign="Right"
                [filterBarTemplate]="templateOptionsDropDown"></e-column>
            <e-column field="Freight" headerText="Freight" width="100" format="C2" textAlign="Right"
                [filterBarTemplate]="templateOptionsNumericTextBox"></e-column>
            <e-column field="OrderDate" headerText="Order Date" width="120" format="yMd" type="date"
                [filterBarTemplate]="templateOptionsDatePicker"></e-column>
            <e-column field="ShipCity" headerText="Ship City" width="120"
                [filterBarTemplate]="templateOptionsComboBox"></e-column>
            <e-column field="ShipCountry" headerText="Ship Country" width="120"
                [filterBarTemplate]="templateOptionsMultiSelect"></e-column>
        </e-columns>
    </ejs-grid>
</div>
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

See also