React DataGrid - Implement a Hierarchical Header Filter
DataGrid supports hierarchical data structures in column headerFilters. This tutorial demonstrates how to implement a hierarchical header filter for a specific column.

Configure the Header Filter
To configure a hierarchical header filter, specify the following properties:
groupInterval
Assign a string array that contains multiple items to the groupInterval property. Specify the nesting levels you want to implement in this array:jQuery
index.js$('#gridContainer').dxDataGrid({ columns: [{ headerFilter: { groupInterval: ["State", "City"], } }] })Angular
app.component.htmlapp.component.ts<dx-data-grid ... > <dxi-column> <dxo-header-filter [groupInterval]="groupInterval" ></dxo-header-filter> </dxi-column> </dx-data-grid>export class AppComponent { groupInterval = ["State", "City"]; }Vue
App.vue<template> <DxDataGrid ... > <DxColumn ... > <DxHeaderFilter :group-interval="groupInterval" /> </DxColumn> </DxDataGrid> <template> <script setup lang="ts"> import { DxDataGrid, DxColumn, DxHeaderFilter } from 'devextreme-vue/data-grid'; const groupInterval = ["State", "City"]; </script>React
App.tsximport { DataGrid, Column, HeaderFilter } from 'devextreme-react/data-grid'; const groupInterval = ["State", "City"]; function App() { return ( <DataGrid ... > <Column ... > <HeaderFilter groupInterval={groupInterval} /> </Column> </DataGrid> ) }headerFilter.dataSource
Configure a hierarchical headerFilter.dataSource following the "tree" DataStructure. Specify thetext,value, anditems[]properties:jQuery
index.js$('#gridContainer').dxDataGrid({ columns: [{ headerFilter: { groupInterval: ["State", "City"], dataSource: [{ text: "Arkansas", value: "Arkansas", items: [{ text: "Bentonville", value: "Bentonville", }] }] } }] })Angular
app.component.htmlapp.component.ts<dx-data-grid ... > <dxi-column> <dxo-header-filter [groupInterval]="groupInterval" [dataSource]="headerFilterDataSource" ></dxo-header-filter> </dxi-column> </dx-data-grid>export class AppComponent { groupInterval = ["State", "City"]; headerFilterDataSource = [{ text: "Arkansas", value: "Arkansas", items: [{ text: "Bentonville", value: "Bentonville", }] }]; }Vue
App.vue<template> <DxDataGrid ... > <DxColumn ... > <DxHeaderFilter :group-interval="groupInterval" :data-source="headerFilterDataSource" /> </DxColumn> </DxDataGrid> <template> <script setup lang="ts"> import { DxDataGrid, DxColumn, DxHeaderFilter } from 'devextreme-vue/data-grid'; const groupInterval = ["State", "City"]; const headerFilterDataSource = [{ text: "Arkansas", value: "Arkansas", items: [{ text: "Bentonville", value: "Bentonville", }] }]; </script>React
App.tsximport { DataGrid, Column, HeaderFilter } from 'devextreme-react/data-grid'; const groupInterval = ["State", "City"]; const headerFilterDataSource = [{ text: "Arkansas", value: "Arkansas", items: [{ text: "Bentonville", value: "Bentonville", }] }] function App() { return ( <DataGrid ... > <Column ... > <HeaderFilter groupInterval={groupInterval} dataSource={headerFilterDataSource} /> </Column> </DataGrid> ) }
For more information about hierarchical data structures in DevExtreme, refer to the following topic: TreeList - dataStructure.
Update Component Data
To enable selection of all items within a group, add group fields to your data source. For instance, to group an array of cities by state, add a "State" field to each array item:
jQuery
const cities = [{
ID: 1,
City: 'Bentonville',
State: 'Arkansas',
}, {
ID: 2,
City: 'Atlanta',
State: 'Georgia',
}, {
// ...
}]Angular
cities = [{
ID: 1,
City: 'Bentonville',
State: 'Arkansas',
}, {
ID: 2,
City: 'Atlanta',
State: 'Georgia',
}, {
// ...
}]Vue
const cities = [{
ID: 1,
City: 'Bentonville',
State: 'Arkansas',
}, {
ID: 2,
City: 'Atlanta',
State: 'Georgia',
}, {
// ...
}]React
const cities = [{
ID: 1,
City: 'Bentonville',
State: 'Arkansas',
}, {
ID: 2,
City: 'Atlanta',
State: 'Georgia',
}, {
// ...
}]Implement calculateFilterExpression()
To apply hierarchical header filter values, define the calculateFilterExpression function. Return a group filter expression that compares filterValue with both item and group fields:
jQuery
$('#gridContainer').dxDataGrid({
columns: [{
calculateFilterExpression(filterValue, selectedFilterOperation, target) {
if (target === "headerFilter" && filterValue) {
return [["City", selectedFilterOperation, filterValue], "or", ["State", selectedFilterOperation, filterValue]];
}
return this.defaultCalculateFilterExpression(filterValue, selectedFilterOperations, target);
},
}]
})Angular
<dx-data-grid ... >
<dxi-column>
<dxo-header-filter
[calculateFilterExpression]="calculateFilterExpression"
></dxo-header-filter>
</dxi-column>
</dx-data-grid>
export class AppComponent {
calculateFilterExpression(this: DxDataGridTypes.Column, filterValue, selectedFilterOperation, target) {
if (target === "headerFilter" && filterValue) {
return [["City", selectedFilterOperation, filterValue], "or", ["State", selectedFilterOperation, filterValue]];
}
return this.defaultCalculateFilterExpression(filterValue, selectedFilterOperations, target);
}
}Vue
<template>
<DxDataGrid ... >
<DxColumn ... >
<DxHeaderFilter
:group-interval="groupInterval"
:calculate-filter-expression="calculateFilterExpression"
/>
</DxColumn>
</DxDataGrid>
<template>
<script setup lang="ts">
import { DxDataGrid, DxColumn, DxHeaderFilter, type DxDataGridTypes } from 'devextreme-vue/data-grid';
const groupInterval: string[] = ["State", "City"];
function calculateFilterExpression(this: DxDataGridTypes.Column, filterValue, selectedFilterOperation, target) {
if (target === "headerFilter" && filterValue) {
return [["City", selectedFilterOperation, filterValue], "or", ["State", selectedFilterOperation, filterValue]];
}
return this.defaultCalculateFilterExpression(filterValue, selectedFilterOperations, target);
}
</script>React
import { DataGrid, Column, HeaderFilter, type DxDataGridTypes } from 'devextreme-react/data-grid';
const groupInterval: string[] = ["State", "City"];
function calculateFilterExpression(this: DxDataGridTypes.Column, filterValue, selectedFilterOperation, target) {
if (target === "headerFilter" && filterValue) {
return [["City", selectedFilterOperation, filterValue], "or", ["State", selectedFilterOperation, filterValue]];
}
return this.defaultCalculateFilterExpression(filterValue, selectedFilterOperations, target);
}
function App() {
return (
<DataGrid ... >
<Column ... >
<HeaderFilter
groupInterval={groupInterval}
calculateFilterExpression={calculateFilterExpression}
/>
</Column>
</DataGrid>
)
}If you have technical questions, please create a support ticket in the DevExpress Support Center.