Filter bar in Angular Grid component
16 Sep 202524 minutes to read
The filter bar feature in the Syncfusion Angular Grid provides an intuitive and immediate way to filter data by displaying input fields directly below each column header. This filtering approach allows users to enter filter criteria and instantly view filtered results, making it ideal for scenarios requiring quick data searches and real-time filtering feedback.
The filter bar is particularly effective for applications where users need to perform frequent filtering operations or when working with datasets that require immediate visual feedback during the filtering process. Unlike other filtering methods, the filter bar maintains visibility of filter criteria, providing users with a clear understanding of applied filters at all times.
To enable the filter bar, set the allowFiltering property to true. This renders a filter bar row next to the header, allowing users to filter records using different expressions based on column data types.
Filter bar expressions:
You can enter the following filter expressions(operators) manually in the filter bar.
| Expression | Example | Description | Column Type |
|---|---|---|---|
| = | =value | equal | Number |
| != | !=value | notequal | Number |
| > | >value | greaterthan | Number |
| < | <value | lessthan | Number |
| >= | >=value | greaterthanorequal | Number |
| <= | <=value | lessthanorequal | Number |
| * | *value | startswith | String |
| % | %value | endswith | String |
| N/A | N/A | Always equal operator will be used for Date filter | Date |
| N/A | N/A | Always equal operator will be used for Boolean filter | Boolean |
The following example demonstrates basic filter bar activation in the grid:
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids'
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons'
import { Component, OnInit } from '@angular/core';
import { FilterSettingsModel, PageSettingsModel } from '@syncfusion/ej2-angular-grids';
import { data } from './datasource';
@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='273px' [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.
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 { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids'
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { ButtonModule, CheckBoxModule } from '@syncfusion/ej2-angular-buttons'
import { Component, OnInit } from '@angular/core';
import { FilterSettingsModel, PageSettingsModel } from '@syncfusion/ej2-angular-grids';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns';
import { data } from './datasource';
@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)'></ejs-dropdownlist>
</div>
<ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]="pageSettings" [allowFiltering]='true' height='273px' [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: string[] = ['Immediate', 'OnEnter'];
ngOnInit(): void {
this.data = data;
}
onModeChange(args: ChangeEventArgs): void {
this.filterSettings = {
mode: args.value,
}
};
}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 Syncfusion Angular Grid provides functionality to display current filter status within the pager component. This feature helps users understand applied filters and filtering criteria without examining individual filter bar cells.
Enable this feature by setting the showFilterBarStatus property to true within the filterSettings configuration. The pager will then display a summary of active filters, providing clear visibility into the current filtering state.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids'
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { ButtonModule, CheckBoxModule, SwitchModule } from '@syncfusion/ej2-angular-buttons'
import { Component, OnInit } from '@angular/core';
import { FilterSettingsModel, PageSettingsModel } from '@syncfusion/ej2-angular-grids';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-buttons';
import { data } from './datasource';
@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 Syncfusion Angular Grid allows users to modify filter operators directly within the filter bar cells during the filtering process. This feature enables dynamic operator changes without accessing separate dialog boxes or menus.
For example, while the default operator for string-type columns is “startswith,” users can change this to other operators like “contains,” “endswith,” or “equal” directly within the filter bar interface.
Enable this functionality by setting the showFilterBarOperator property to true within the filterSettings configuration.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids'
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { ButtonModule, CheckBoxModule, SwitchModule } from '@syncfusion/ej2-angular-buttons'
import { Component, OnInit } from '@angular/core';
import { FilterSettingsModel, PageSettingsModel } from '@syncfusion/ej2-angular-grids';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-buttons';
import { data } from './datasource';
@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='273px' [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
You can disable filtering for specific columns by setting the allowFiltering property to false within the column configuration. This feature is useful when certain columns contain data that should not be filtered, such as action columns or calculated fields.
When filtering is disabled for a column, the filter bar input field for that column will not be rendered, providing a cleaner interface and preventing unnecessary filtering attempts.
The following example demonstrates how to disable the filter bar for the CustomerID column:
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids'
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
@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
By default, the filter bar is disabled for template columns since template content may not correspond directly to filterable data. However, you can explicitly hide the filter bar for template columns to provide a cleaner interface.
Use the filterTemplate property of the column to define custom filter bar behavior for template columns. Setting this property to an empty template effectively hides the filter bar for that column.
The following example demonstrates how to hide the filter bar for a template column:
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'
import { ButtonModule } from '@syncfusion/ej2-angular-buttons'
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids'
import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { GridComponent, Column } 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="350" (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 feature enables you to replace the default text box in filter bar cells with custom components. This powerful customization option allows you to implement specialized filtering interfaces using various Syncfusion components such as DatePicker, NumericTextBox, ComboBox, or MultiSelect.
Custom filter bar templates are particularly useful when:
- Default text input doesn’t provide optimal user experience for specific data types
- You need specialized filtering controls 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 { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids'
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons'
import { Component, ViewChild } from '@angular/core';
import { data } from './datasource';
import { GridComponent, IFilterUI, parentsUntil } from '@syncfusion/ej2-angular-grids';
import { ComboBox, DropDownList, MultiSelect} from '@syncfusion/ej2-dropdowns';
import { DataManager, DataUtil, Predicate, Query } from '@syncfusion/ej2-data';
import { DatePicker } from '@syncfusion/ej2-calendars';
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">
<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));