All docs
V25.2
25.2
25.1
24.2
24.1
The page you are viewing does not exist in version 24.1.
23.2
The page you are viewing does not exist in version 23.2.
23.1
The page you are viewing does not exist in version 23.1.
22.2
The page you are viewing does not exist in version 22.2.
22.1
The page you are viewing does not exist in version 22.1.
21.2
The page you are viewing does not exist in version 21.2.
21.1
The page you are viewing does not exist in version 21.1.
20.2
The page you are viewing does not exist in version 20.2.
20.1
The page you are viewing does not exist in version 20.1.
19.2
The page you are viewing does not exist in version 19.2.
19.1
The page you are viewing does not exist in version 19.1.
18.2
The page you are viewing does not exist in version 18.2.
18.1
The page you are viewing does not exist in version 18.1.
17.2
The page you are viewing does not exist in version 17.2.

JavaScript/jQuery 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.

DevExtreme DataGrid Hierarchical Header Filter

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.html
    app.component.ts
    <dx-data-grid ... >
        <dxi-data-grid-column>
            <dxo-data-grid-header-filter
                [groupInterval]="groupInterval"
            ></dxo-data-grid-header-filter>
        </dxi-data-grid-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.tsx
    import { 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 the text, value, and items[] properties:

    jQuery
    index.js
    $('#gridContainer').dxDataGrid({
        columns: [{
            headerFilter: {
                groupInterval: ["State", "City"],
                dataSource: [{
                    text: "Arkansas",
                    value: "Arkansas",
                    items: [{
                        text: "Bentonville",
                        value: "Bentonville",
                    }]
                }]
            }
        }]
    })
    Angular
    app.component.html
    app.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.tsx
    import { 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
data.js
const cities = [{
    ID: 1,
    City: 'Bentonville',
    State: 'Arkansas',
}, {
    ID: 2,
    City: 'Atlanta',
    State: 'Georgia',
}, {
    // ...
}]
Angular
data.ts
cities = [{
    ID: 1,
    City: 'Bentonville',
    State: 'Arkansas',
}, {
    ID: 2,
    City: 'Atlanta',
    State: 'Georgia',
}, {
    // ...
}]
Vue
data.ts
const cities = [{
    ID: 1,
    City: 'Bentonville',
    State: 'Arkansas',
}, {
    ID: 2,
    City: 'Atlanta',
    State: 'Georgia',
}, {
    // ...
}]
React
data.ts
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
index.js
$('#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
app.component.html
app.component.ts
<dx-data-grid ... >
    <dxi-data-grid-column>
        <dxo-data-grid-header-filter
            [calculateFilterExpression]="calculateFilterExpression"
        ></dxo-data-grid-header-filter>
    </dxi-data-grid-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
App.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
App.tsx
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>
    )
}