All docs
V23.2
24.1
23.2
23.1
22.2
22.1
21.2
21.1
20.2
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.

jQuery DataGrid - Filtering and Searching

Filter Row

The filter row allows a user to filter data by individual columns' values. Usually, the filter row's cells are text boxes, but the cells of columns that hold date or Boolean values contain other filtering controls (calendars or select boxes).

DevExtreme HTML5 JavaScript jQuery Knockout Angular DataGrid Filtering FilterRow

To make the filter row visible, assign true to the filterRow.visible property. You can set a column's allowFiltering property to false if data should never be filtered by it.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterRow: { visible: true },
        columns: [{
            // ...
            allowFiltering: false
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-filter-row [visible]="true"></dxo-filter-row>
    <dxi-column [allowFiltering]="false" ... ></dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
        <DxFilterRow :visible="true" />
        <DxColumn :allow-filtering="false" ... />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxFilterRow
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxFilterRow
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column,
    FilterRow
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... >
                <FilterRow visible={true} />
                <Column allowFiltering={false} ... />
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .FilterRow(fr => fr.Visible(true))
    .Columns(columns => {
        columns.Add().AllowFiltering(false);
    })
)

A user-specified filter is automatically applied with a delay by default. Alternatively, it can be applied by a click on the "Apply Filter" button if you set the filterRow.applyFilter property to "onClick".

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterRow: {
            visible: true,
            applyFilter: "onClick"
        }
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-filter-row
        [visible]="true"
        applyFilter="onClick">
    </dxo-filter-row>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...>
        <DxFilterRow 
            :visible="true" 
            apply-filter="onClick"
        />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxFilterRow
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxFilterRow
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    FilterRow
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... >
                <FilterRow 
                    visible={true} 
                    applyFilter="onClick" 
                />
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .FilterRow(fr => fr
        .Visible(true)
        .ApplyFilter(GridApplyFilterMode.OnClick)
    )           
)

Each cell in the filter row contains a magnifying glass icon. Hovering the mouse pointer over it opens a drop-down list with the column's available filter operations.

DevExtreme HTML5 JavaScript jQuery Knockout Angular DataGrid Filtering FilterRow

The set of available filter operations can be restricted using the filterOperations property. You can also preselect a filter operation and specify the initial filter value with the selectedFilterOperation and filterValue properties. Call the columnOption method at runtime to change these properties:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterRow: { visible: true },
        columns: [{
            dataField: "Status",
            filterOperations: ["contains", "="],
            selectedFilterOperation: "contains",
            filterValue: "Pending"
        }]
    })
});
JavaScript
$("#dataGridContainer").dxDataGrid("instance").columnOption("Status", {
    selectedFilterOperation: "=",
    filterValue: "Finished"
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-filter-row [visible]="true"></dxo-filter-row>
    <dxi-column 
        dataField="Status"
        [filterOperations]="['contains', '=']"
        [(selectedFilterOperation)]="selectedOperation"
        [(filterValue)]="filterValue">
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    selectedOperation: string = "contains";
    filterValue: any = "Pending";
    applyFilter (operation, value) {
        this.selectedOperation = operation;
        this.filterValue = value;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
        <DxFilterRow :visible="true />
        <DxColumn 
            :filter-operations="allowedOperations"
            v-model:selected-filter-operation="selectedOperation"
            v-model:filter-value="filterValue" 
            data-field="Status"
        />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxFilterRow
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxFilterRow
    },
    data() {
        return {
            allowedOperations: ['contains', '='],
            selectedOperation: 'contains',
            filterValue: 'Pending'
        }
    },
    methods: {
        applyFilter (operation, value) {
            this.selectedOperation = operation;
            this.filterValue = value;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column,
    FilterRow
} from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.filterOperations = ['contains', '='];
        this.state = {
            selectedOperation: 'contains',
            filterValue: 'Pending'
        }
    }

    render() {
        let { selectedOperation, filterValue } = this.state;
        return (
            <DataGrid onOptionChanged={this.optionChanged} ... >
                <FilterRow visible={true} />
                <Column 
                    dataField="Status"
                    filterOperations={this.filterOperations}
                    selectedFilterOperation={selectedOperation}
                    filterValue={filterValue}
                />
            </DataGrid>
        );
    }
    optionChanged = (e) => {
        if(e.fullName === "columns[0].filterValue") {
            this.setState({ 
                filterValue: e.value
            })
        }
        if(e.fullName === "columns[0].selectedFilterOperation") {
            this.setState({ 
                selectedOperation: e.value
            })
        }
    }
    applyFilter = (operation, value) => {
        this.setState({
            selectedOperation: operation,
            filterValue: value
        })
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .ID("dataGridContainer")
    .FilterRow(fr => fr.Visible(true))
    .Columns(columns => {
        columns.Add()
            .DataField("Status")
            .FilterOperations(new FilterOperations[] { FilterOperations.Contains, FilterOperations.Equal })
            .SelectedFilterOperation(FilterOperations.Equal)
            .FilterValue("Pending");
    })
)

<script type="text/javascript">       
    $("#dataGridContainer").dxDataGrid("instance").columnOption("Status", {
        selectedFilterOperation: "=",
        filterValue: "Finished"
    });
</script>
See Also

Header Filter

A header filter allows a user to filter values in an individual column by including or excluding them from the applied filter. Clicking a header filter icon invokes a popup menu with all the column's unique values. A user includes or excludes values from the filter by selecting or clearing their selection in this menu.

DevExtreme HTML5 JavaScript jQuery Knockout Angular DataGrid Filtering HeaderFilter

Assign true to the headerFilter.visible property to make header filter icons visible for all columns. Set a column's allowHeaderFiltering property to false if its header filter should not be available. Note that this property inherits the allowFiltering property's value by default.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        headerFilter: { visible: true },
        columns: [{
            // ...
            allowHeaderFiltering: false
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-header-filter [visible]="true"></dxo-header-filter>
    <dxi-column [allowHeaderFiltering]="false" ... ></dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
       <DxHeaderFilter :visible="true" />
       <DxColumn :allow-header-filtering="false" ... />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxHeaderFilter
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxHeaderFilter
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column,
    HeaderFilter
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... >
                <HeaderFilter visible={true} />
                <Column allowHeaderFiltering={false} ... />
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .HeaderFilter(hf => hf.Visible(true))
    .Columns(columns => {
        columns.Add().AllowHeaderFiltering(false);
    })
)

A user can change the applied filter by including or excluding values. Use a column's filterType property to specify the required mode. You can specify the initial filter by combining this property and the filterValues property. To change it at runtime, call the columnOption method:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        columns: [{
            // ...
            dataField: "OrderDate",
            filterType: "exclude", // or "include"
            filterValues: [2014]
        }]
    });
});
JavaScript
$("#dataGridContainer").dxDataGrid("instance").columnOption("OrderDate", {
    filterType: "include",
    filterValues: [2014, 2015]
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column 
        dataField="OrderDate"
        [(filterValues)]="filterValues"
        [(filterType)]="filterType"> 
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    filterValues: Array<any> = [2014];
    filterType: string = "exclude";    // or "include"
    applyFilter (filterType, values) {
        this.filterType = filterType;
        this.filterValues = values;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >           
        <DxColumn 
            v-model:filter-type="filterType"
            v-model:filter-values="filterValues" 
            data-field="OrderDate"
        />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn
    },
    data() {
        return {
           filterType: "exclude", // or "include" 
           filterValues: [2014]
        }
    },
    methods: {
        applyFilter (filterType, values) {
            this.filterType = filterType;
            this.filterValues = values;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column
} from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);            
        this.state = {
            filterType: 'exclude', // or 'include'
            filterValues: [2014]
        }
    }

    render() {
        let { filterType, filterValues } = this.state;
        return (
            <DataGrid ... 
                onOptionChanged={this.onOptionChanged}>                
                <Column 
                    dataField="OrderDate"
                    filterType={filterType}                   
                    filterValues={filterValues}
                />
            </DataGrid>
        );
    }
    onOptionChanged = (e) => {
        if(e.fullName === "columns[0].filterValues") {
            this.setState({ 
                filterValues: e.value
            })
        }
        if(e.fullName === "columns[0].filterType") {
            this.setState({ 
                filterType: e.value
            })
        }
    }
    applyFilter = (filterType, values) => {
        this.setState({
            filterType: filterType,
            filterValues: values
        })
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .ID("dataGridContainer")
    .Columns(columns => {
        columns.Add()
            .DataField("OrderDate")
            .FilterType(FilterType.Exclude) // or FilterType.Include
            .FilterValues(new int[] { 2014 });
    })
)

<script type="text/javascript">        
    $("#dataGridContainer").dxDataGrid("instance").columnOption("OrderDate", {
        filterType: "include",
        filterValues: [2014, 2015]
    });
</script>
NOTE
The filter row and header filter can work simultaneously. If you specify the filterValue property to set up the filter row, it limits the filter values for the header filter and vice versa: if you specify the filterValues property to set up the header filter, it limits the filter row's filter values.

You can use the headerFilter.allowSearch property to enable searching in the header filter. You can also declare this property in a column's configuration object to enable/disable searching in this column's header filter.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        headerFilter: { 
            visible: true,
            allowSearch: true
        },
        columns: [{
            // ...
            headerFilter: { 
                allowSearch: false
            }
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-header-filter [visible]="true" [allowSearch]="true"></dxo-header-filter>
    <dxi-column ... >
        <dxo-header-filter [allowSearch]="false"></dxo-header-filter>
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
        <DxHeaderFilter 
            :allow-search="true" 
            :visible="true" 
        />
        <DxColumn>
            <DxColumnHeaderFilter :allow-search="false" />
        </DxColumn>
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxHeaderFilter,
    DxColumnHeaderFilter
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxHeaderFilter,
        DxColumnHeaderFilter
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column,
    HeaderFilter,
    ColumnHeaderFilter
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... >
                <HeaderFilter 
                    allowSearch={true} 
                    visible={true} 
                />
                <Column>
                    <ColumnHeaderFilter allowSearch={false} />
                </Column>
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .HeaderFilter(hf => hf
        .Visible(true)
        .AllowSearch(true)
    )
    .Columns(columns => {
        columns.Add()
            .HeaderFilter(hf => hf.AllowSearch(false));
    })
)    

A header filter's popup menu lists all column values by default. You can group them using the headerFilter.groupInterval property if they are numbers or dates. You can also provide a custom data source for a header filter using the dataSource property. Refer to the property's description for details.

See Also

Search Panel

The search panel allows a user to search for values in several columns at once. Search is case-insensitive.

DevExtreme HTML5 JavaScript jQuery Angular Knockout UI component DataGrid SearchPanel

To make the search panel visible, assign true to the searchPanel.visible property. You can set a column's allowSearch property to false if it should be excluded from searching. Note that this property inherits the allowFiltering property's value by default.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        searchPanel: { visible: true },
        columns: [{
            // ...
            allowSearch: false
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-search-panel [visible]="true"></dxo-search-panel>
    <dxi-column [allowSearch]="false" ... ></dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
       <DxSearchPanel :visible="true" />
       <DxColumn :allow-search="false" />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxSearchPanel
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxSearchPanel
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column,
    SearchPanel
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... >
              <SearchPanel visible={true} />
              <Column allowSearch={false} />
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .SearchPanel(sp => sp.Visible(true))
    .Columns(columns => {
        columns.Add().AllowSearch(false);
    })
)    

Use the searchPanel.text property to predefine the search value. You can also change it at runtime by calling the searchByText(text) method:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        searchPanel: {
            visible: true,
            text: "4/1/2015"
        }
    });
});
JavaScript
$("#dataGridContainer").dxDataGrid("instance").searchByText("1/29/2016");
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-search-panel 
        [visible]="true" 
        [(text)]="searchText">
    </dxo-search-panel>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    searchText: string = "4/1/2015";
    setSearchValue (searchText) {
        this.searchText = searchText;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... >
        <DxSearchPanel 
            :visible="true"
            v-model:text="searchText" 
        />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxSearchPanel
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxSearchPanel
    },
    data() {
       return {
           searchText: "4/1/2015",
       }
    },
    methods: {
        setSearchValue (searchText) {
            this.searchText = searchText;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    SearchPanel
} from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            searchText: "4/1/2015"
        }
    }

    render() {
        let { searchText } = this.state;
        return (
            <DataGrid ... 
                onOptionChanged={this.onOptionChanged}>
                <SearchPanel 
                    visible={true}
                    text={searchText} 
                />
            </DataGrid>
        );
    }
    onOptionChanged = (e) => {
        if(e.fullName === "searchPanel.text") {
            this.setSearchValue(e.value);
        }
    }
    setSearchValue = (searchText) => {
        this.setState({
            searchText: searchText
        })
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .ID("dataGridContainer")
    .SearchPanel(sp => sp
        .Visible(true)
        .Text("4/1/2015")
    )
)  

<script type="text/javascript">
    $("#dataGridContainer").dxDataGrid("instance").searchByText("1/29/2016");
</script>

Searching is performed differently depending on a column's data type. Numeric, Boolean, and date columns require that a user enters a full value into the search panel. Searching columns containing string values and specifying the search value using the API requires entering only a part of a value.

See Also

Filter Panel with Filter Builder

The filter panel displays the applied filter expression.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Filter Panel

You can click the filter expression to open the integrated filter builder.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Filter Panel

View Demo

Set the filterPanel.visible property to true to make the filter panel visible.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterPanel: { visible: true }
    });
});
Angular
HTML
<dx-data-grid ... >
    <dxo-filter-panel [visible]="true"></dxo-filter-panel>
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ... >
       <DxFilterPanel :visible="true />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {      
    DxFilterPanel
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxFilterPanel
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    FilterPanel
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...>
                <FilterPanel visible={true} />                  
            </DataGrid>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .FilterPanel(fp => fp.Visible(true))
)   

If a user changes the filter expression in the filter panel or filter builder, the changes are reflected in the filter row and header filter, and vice versa. Set the filterSyncEnabled property to false to disable this synchronization. In this case, the filter panel remains synchronized with the filter builder.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterSyncEnabled: false
    });
});
Angular
HTML
<dx-data-grid ...
    [filterSyncEnabled]="false">
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ... 
        :filter-sync-enabled="false"
    />
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                filterSyncEnabled={false}
            />
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ...*@
    .FilterSyncEnabled(false)
)

You can define the filter expression programmatically with the filterValue property. See the property's description for the full list of available filter operations and their peculiarities.

The filterValue is updated when a user changes the filter expression from the UI. Use the option method to update it from the API:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterValue: ["SaleAmount", "<>", null],
        filterPanel: { 
            visible: true
        }
    });
});
JavaScript
$("#dataGridContainer").dxDataGrid("instance").option("filterValue", ["Employee", "contains", "Clark"]);
Angular
HTML
TypeScript
<dx-data-grid ...
    [(filterValue)]="filterValue">
    <dxo-filter-panel 
        [visible]="true">
    </dxo-filter-panel>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    filterValue: Array<any> = ['SaleAmount', '<>', null];
    applyFilter (filterExpression) {
        this.filterValue = filterExpression;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... 
        v-model:filter-value="filterValue">
        <DxFilterPanel :visible="true" />
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxFilterPanel
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxFilterPanel
    },
    data() {
        return {
            filterValue: ['SaleAmount', '<>', null]
        };
    },
    methods: {
        applyFilter (filterExpression) {
            this.filterValue = filterExpression;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    FilterPanel
} from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            filterValue: ['SaleAmount', '<>', null]
        }
    }

    render() {
        let { filterValue } = this.state;
        return (
            <DataGrid ...
                onOptionChanged={this.onOptionChanged} 
                filterValue={filterValue}>
                <FilterPanel visible={true} />                  
            </DataGrid>
        );
    }
    onOptionChanged = (e) => {
        if(e.fullName === "filterValue") {
            this.applyFilter(e.value);
        }      
    }
    applyFilter = (filterExpression) => {
        this.setState({
            filterValue: filterExpression
        });
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .ID("dataGridContainer")
    .FilterPanel(fp => fp.Visible(true))
    .FilterValue(new object[] { "SaleAmount", FilterBuilderFieldFilterOperations.NotEqual, null })
)

<script type="text/javascript"> 
    $("#dataGridContainer").dxDataGrid("instance")
        .option("filterValue", ["Employee", "contains", "Clark"]);
</script> 

The DataGrid provides the filterBuilder and filterBuilderPopup objects that configure the integrated filter builder and the popup in which it appears. These objects can contain the FilterBuilder's and Popup's properties. In the following code, the filter builder has an additional filter operation Is Zero; the filter builder's popup is customized and displayed on a button click:

jQuery
JavaScript
$(function() {
    var dataGrid = $("#dataGridContainer").dxDataGrid({
        // ...
        filterPanel: { visible: false },
        filterSyncEnabled: true,
        filterBuilder: {
            customOperations: [{
                name: "isZero",
                caption: "Is Zero",
                dataTypes: ["number"],
                hasValue: false,
                calculateFilterExpression: function(filterValue, field) {
                    return [field.dataField, "=", 0];
                }
            }]
        }, 
        filterBuilderPopup: {
            width: 400,
            title: "Synchronized Filter"
        }
    }).dxDataGrid("instance");
    $("#button").dxButton({
        text: "Show Filter Builder",
        onClick: function () {
            dataGrid.option("filterBuilderPopup", { visible: true });
        }
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... 
    [filterSyncEnabled]="true">
    <dxo-filter-panel [visible]="false"></dxo-filter-panel>
    <dxo-filter-builder 
        [customOperations]="customOperations">
    </dxo-filter-builder>
    <dxo-filter-builder-popup 
        [width]="400"
        title="Synchronized Filter"
        [(visible)]="popupVisible">
    </dxo-filter-builder-popup>
</dx-data-grid>
<dx-button
    text="Show Filter Builder"
    (onClick)="showFilterBuilder()">
</dx-button>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    popupVisible: boolean = false;
    customOperations = [{
        name: "isZero",
        caption: "Is Zero",
        dataTypes: ["number"],
        hasValue: false,
        calculateFilterExpression: function(filterValue, field) {
            return [field.dataField, "=", 0];
        }
    }];
    showFilterBuilder () {
        this.popupVisible = true;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <div>
        <DxDataGrid ... 
            :filter-sync-enabled="true">
            <DxFilterPanel :visible="false" />
            <DxFilterBuilder :custom-operations="customOperations" />
            <DxFilterBuilderPopup 
                :width="400"
                v-model:visible="popupVisible"
                title="Synchronized Filter"
            />
        </DxDataGrid>
        <DxButton
            @click="showFilterBuilder"
            text="Show Filter Builder"                
        />
    </div>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxButton from 'devextreme-vue/button';

import DxDataGrid, {
    DxFilterPanel,
    DxFilterBuilder,
    DxFilterBuilderPopup
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxFilterPanel,
        DxFilterBuilder,
        DxFilterBuilderPopup,
        DxButton
    },
    data() {
        return {
            customOperations: [{
                name: "isZero",
                caption: "Is Zero",
                dataTypes: ["number"],
                hasValue: false,
                calculateFilterExpression: function(filterValue, field) {
                    return [field.dataField, "=", 0];
                }
            }],
            popupVisible: false                
        };
    },
    methods: {
        showFilterBuilder () {
            this.popupVisible = true;
        }            
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import Button from 'devextreme-react/button';

import DataGrid, {
    FilterPanel,        
    FilterBuilder,
    FilterBuilderPopup
} from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            popupVisible: false
        }
        this.customOperations = [{
            name: "isZero",
            caption: "Is Zero",
            dataTypes: ["number"],
            hasValue: false,
            calculateFilterExpression: function(filterValue, field) {
                return [field.dataField, "=", 0];
            }
        }]
    }

    render() {
        let { popupVisible } = this.state;
        return (
            <React.Fragment>
                <DataGrid ... 
                    filterSyncEnabled={true} >
                    <FilterPanel visible={false} />
                    <FilterBuilder customOperations={this.customOperations} />
                    <FilterBuilderPopup 
                        width={400}
                        title="Synchronized Filter"
                        visible={popupVisible}
                    />                  
                </DataGrid>
                <Button 
                    text="Show Filter Builder" 
                    onClick={this.showFilterBuilder} 
                />
            </React.Fragment>
        );
    }
    showFilterBuilder = () => {
        this.setState({
            popupVisible: true
        });
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    @* ... *@
    .ID("dataGridContainer")
    .FilterPanel(fp => fp.Visible(false))
    .FilterSyncEnabled(true)
    .FilterBuilderPopup(fbp => fbp.Width(400).Title("Synchronized Filter"))
    .FilterBuilder(fb => fb
        .CustomOperations(co => {
            co.Add().Name("isZero")
                .Caption("Is Zero")
                .DataTypes(new[] { FilterBuilderFieldDataType.Number })        
                .HasValue(false)
                .CalculateFilterExpression("calculateFilterExpression");
        })
    )
)
@(Html.DevExtreme().Button()
    .Text("Show Filter Builder")
    .OnClick("showFilterBuilder")
)

<script type="text/javascript">
    function showFilterBuilder() {
        $("#dataGridContainer").dxDataGrid('instance').option('filterBuilderPopup', { visible: true })
    }
    function calculateFilterExpression(filterValue, field) { 
        return [field.dataField, "=", 0]; 
    }
</script>
See Also

Standalone Filter Builder

The DataGrid UI component has an integrated filter builder that can be invoked using the filter panel. You can also use the FilterBuilder UI component as a standalone component. Pass an array of columns that should be filtered to the FilterBuilder's fields property. Each item in this array should at least specify a dataField. The following code passes DataGrid columns to the FilterBuilder:

jQuery
JavaScript
var columns = [{
    caption: "ID",
    dataField: "Product_ID",
    dataType: "number"
}, {
    dataField: "Product_Name"
}, {
    caption: "Cost",
    dataField: "Product_Cost",
    dataType: "number",
    format: "currency"
}];

$(function () {
    $("#dataGrid").dxDataGrid({
        // ...
        columns: columns
    });
    $("#filterBuilder").dxFilterBuilder({
        fields: columns
    });
});
Angular
HTML
TypeScript
<dx-filter-builder 
    [fields]="columns">
</dx-filter-builder>
<dx-data-grid ...       
    [columns]="columns">
</dx-data-grid>
import { DxDataGridModule, DxFilterBuilderModule } from "devextreme-angular";
// ...
export class AppComponent {
    columns = [{
        caption: "ID",
        dataField: "Product_ID",
        dataType: "number"
    }, {
        dataField: "Product_Name"
    }, {
        caption: "Cost",
        dataField: "Product_Cost",
        dataType: "number",
        format: "currency"
    }];
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        DxFilterBuilderModule
    ],
    // ...
})
Vue
App.vue
<template>
    <div>
        <DxDataGrid :columns="columns" />
        <DxFilterBuilder :fields="columns" />          
    </div>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';
import DxFilterBuilder from 'devextreme-vue/filter-builder';

export default {
    components: {
        DxDataGrid,
        DxFilterBuilder
    },
    data() {
        return {
            columns: [{
                caption: "ID",
                dataField: "Product_ID",
                dataType: "number"
            }, {
                dataField: "Product_Name"
            }, {
                caption: "Cost",
                dataField: "Product_Cost",
                dataType: "number",
                format: "currency"
            }]
        };
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';
import FilterBuilder from 'devextreme-react/filter-builder';

const columns = [{
    caption: "ID",
    dataField: "Product_ID",
    dataType: "number"
}, {
    dataField: "Product_Name"
}, {
    caption: "Cost",
    dataField: "Product_Cost",
    dataType: "number",
    format: "currency"
}];

class App extends React.Component {
    render() {
        return (
            <React.Fragment>
                <DataGrid defaultColumns={columns} />              
                <FilterBuilder defaultFields={columns} />
            </React.Fragment>
        );
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .Columns(columns => {
        columns.Add()
            .Caption("ID")
            .DataField("Product_ID")
            .DataType(GridColumnDataType.Number);
        columns.Add()
            .DataField("Product_Name");
        columns.Add()
            .Caption("Cost")
            .DataField("Product_Cost")
            .DataType(GridColumnDataType.Number)
            .Format(Format.Currency);
    })
)

@(Html.DevExtreme().FilterBuilder()
    .Fields(fields => {
        fields.Add()
            .Caption("ID")
            .DataField("Product_ID")
            .DataType(FilterBuilderFieldDataType.Number);
        fields.Add()
            .DataField("Product_Name");
        fields.Add()
            .Caption("Cost")
            .DataField("Product_Cost")
            .DataType(FilterBuilderFieldDataType.Number)
            .Format(Format.Currency);
    })
) 

Then, add a button that updates a filter of the DataGrid's data source according to the filter expression:

jQuery
JavaScript
$(function () {
    // ...
    $("#button").dxButton({
        text: "Apply Filter",
        onClick: function () {
            var filter = $("#filterBuilder").dxFilterBuilder("instance").getFilterExpression();
            $("#dataGrid").dxDataGrid("instance").filter(filter);
        },
    });
});
Angular
TypeScript
HTML
import { 
    DxDataGridModule, 
    DxButtonModule,
    DxFilterBuilderModule, 
    DxDataGridComponent, 
    DxFilterBuilderComponent 
} from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
    @ViewChild(DxFilterBuilderComponent, { static: false }) filterBuilder: DxFilterBuilderComponent;
    // Prior to Angular 8
    // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
    // @ViewChild(DxFilterBuilderComponent) filterBuilder: DxFilterBuilderComponent;

    // ...
    buttonClick () {
        this.dataGrid.instance.filter(this.filterBuilder.instance.getFilterExpression());
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        DxButtonModule,
        DxFilterBuilderModule
    ],
    // ...
})
<dx-button 
    text="Apply Filter"
    (onClick)="buttonClick()">
</dx-button>
Vue
App.vue
<template>
    <div>
        <DxDataGrid ... 
           :ref="gridRefKey"
        />
        <DxFilterBuilder ... 
            :ref="fbRefKey"
        />
        <DxButton 
            @click="buttonClick"
            text="Apply Filter"   
        />               
    </div>    
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';
import DxFilterBuilder from 'devextreme-vue/filter-builder';
import DxButton from 'devextreme-vue/button';

const gridRefKey = 'data-grid';
const fbRefKey = 'filter-builder';

export default {
    components: {
        DxDataGrid,
        DxButton,
        DxFilterBuilder
    },
    data() {
        return {
            // ...
            gridRefKey,
            fbRefKey
        };
    },
    methods: {
        buttonClick () {
            this.dataGrid.filter(this.filterBuilder.getFilterExpression());
        }
    },
    computed: {
        dataGrid: function() {
            return this.$refs[gridRefKey].instance;
        },
        filterBuilder: function(){
            return this.$refs[fbRefKey].instance;                
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';
import FilterBuilder from 'devextreme-react/filter-builder';
import Button from 'devextreme-react/button';

class App extends React.Component {
    constructor(props) {
        super(props);    
        this.gridRef = React.createRef();
        this.fbRef = React.createRef();                   
    }
    get dataGrid() {
        return this.gridRef.current.instance;
    }
    get filterBuilder() {
        return this.fbRef.current.instance;
    }

    render() {
        return (
            <React.Fragment>
                <DataGrid ... 
                    :ref="gridRef" />              
                <FilterBuilder ...
                    :ref="fbRef" />
                <Button 
                    text="Apply Filter" 
                    onClick={this.buttonClick} />    
            </React.Fragment>
        );
    }
    buttonClick = () => {
        this.dataGrid.filter(this.filterBuilder.getFilterExpression());
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .ID("dataGrid")
    // ... 
)

@(Html.DevExtreme().FilterBuilder()
    .ID("filterBuilder")
    // ...       
)

<script type="text/javascript">
    var filter = $("#filterBuilder").dxFilterBuilder("instance").getFilterExpression();
    $("#dataGrid").dxDataGrid("instance").filter(filter);
</script>

View Demo

See Also

API

Initial and Runtime Filtering

The initial and runtime filtering API depends on the UI element and is described in the topics above. This API is designed to filter data the data source returns. If you need to pre-filter data in the data source, call the filter(filterExpr) method by passing a filter expression as an argument. Note that this filter can only be cleared programmatically.

jQuery
JavaScript
$("#dataGridContainer").dxDataGrid("instance").filter([
    [ "Cost", ">", 1000 ],
    "and",
    [ "Cost", "<=", 2000 ]
]);
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
    // Prior to Angular 8
    // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
    filterByCost () {
        this.dataGrid.instance.filter([
            [ "Cost", ">", 1000 ],
            "and",
            [ "Cost", "<=", 2000 ]
        ]);
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ... 
        :ref="gridRefKey"
    />      
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';

const gridRefKey = 'data-grid';

export default {
    components: {
        DxDataGrid,
    },
    data() {
        return {
            // ...
            gridRefKey
        };
    },
    methods: {
        filterByCost() {
            this.dataGrid.filter([
                [ "Cost", ">", 1000 ],
                "and",
                [ "Cost", "<=", 2000 ]
            ]);
        }
    },
    computed: {
        dataGrid: function() {
            return this.$refs[gridRefKey].instance;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);    
        this.gridRef = React.createRef();                  
    }
    get dataGrid() {
        return this.gridRef.current.instance;
    }

    render() {
        return (
            <DataGrid ... 
                :ref="gridRef" /> 
        );
    }

    filterByCost = () => {
        this.dataGrid.filter([
            [ "Cost", ">", 1000 ],
            "and",
            [ "Cost", "<=", 2000 ]
        ]);
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .ID("dataGridContainer")
    // ... 
)

<script type="text/javascript">
    $("#dataGridContainer").dxDataGrid("instance").filter([
        [ "Cost", ">", 1000 ],
        "and",
        [ "Cost", "<=", 2000 ]
    ]);
</script>    

You can create a filter that combines all the applied filters by calling the getCombinedFilter() method. It returns a filter with getters by default. Call it by passing true as the argument to get the combined filter with data fields.

jQuery
JavaScript
var filterExpression = $("#dataGridContainer").dxDataGrid("instance").getCombinedFilter(true);
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {        
    @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
    // Prior to Angular 8
    // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
    getCombinedFilter () {
        return this.dataGrid.instance.getCombinedFilter(true);
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <div>
        <DxDataGrid ... 
           :ref="gridRefKey"
        />   
    </div>    
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';

const gridRefKey = 'data-grid';

export default {
    components: {
        DxDataGrid,
    },
    data() {
        return {
            // ...
            gridRefKey
        };
    },
    methods: {
        getCombinedFilter () {
            return this.dataGrid.getCombinedFilter(true);
        }
    },
    computed: {
        dataGrid: function() {
            return this.$refs[gridRefKey].instance;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);    
        this.gridRef = React.createRef();                  
    }
    get dataGrid() {
        return this.gridRef.current.instance;
    }

    render() {
        return (               
            <DataGrid ... 
                :ref="gridRef" />
        );
    }

    getCombinedFilter = () => {
        return this.dataGrid.getCombinedFilter(true);
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .ID("dataGridContainer")
    // ... 
)

<script type="text/javascript">
    var filterExpression = $("#dataGridContainer").dxDataGrid("instance").getCombinedFilter(true);
</script>       
See Also

Filtering Columns Bound to Collection

This section describes how to bind a DataGrid column to data that contains a collection and implement filtering by this column both on the client and server.

Client-Side Filtering

The following code example demonstrates how to filter data on the client. To implement data filtering on the client, bind the DataGrid to a local array, and disable remote filtering.

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        remoteOperations: { filtering: false },
        columns: [
            {
                dataField: 'Products',
                dataType: "string",
                calculateFilterExpression: (filterValue, selectedFilterOperation, target) => {
                    let column = this;
                    if (filterValue) {
                        let selector = (data) => {
                            let applyOperation = (arg1, arg2, op) => {
                                if (op === "=") return arg1 === arg2;
                                if (op === "contains") return arg1.includes(arg2);
                                if (op === "startswith") return arg1.startsWith(arg2);
                                if (op === "endswith") return arg1.endsWith(arg2);
                            };
                            let values = column.calculateCellValue(data);
                            return values && !!values.find(v => applyOperation(v, filterValue, selectedFilterOperation));
                        };
                        return [selector, "=", true];
                    }
                    return this.defaultCalculateFilterExpression.apply(this, arguments);
                }
            },
            // ...
        ],
        // ...
    });
});
Angular
app.component.html
app.component.ts
<dx-data-grid 
    [remoteOperations]="{ filtering: false }"
    // ...
>
    <dxi-column
        dataField="Products"
        dataType="string"
        [calculateFilterExpression]="calculateFilterExpression">
    </dxi-column>
    // ...
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    // ...
    calculateFilterExpression(filterValue, selectedFilterOperation, target) {
        let column = this;
        if (filterValue) {
            let selector = (data) => {
                let applyOperation = (arg1, arg2, op) => {
                    if (op === "=") return arg1 === arg2;
                    if (op === "contains") return arg1.includes(arg2);
                    if (op === "startswith") return arg1.startsWith(arg2);
                    if (op === "endswith") return arg1.endsWith(arg2);
                };
                let values = column.calculateCellValue(data);
                return values && !!values.find(v => applyOperation(v, filterValue, selectedFilterOperation));
            };
            return [selector, "=", true];
        }
        return this.defaultCalculateFilterExpression.apply(this, arguments);
    }
}
Vue
App.vue
<template>
    <DxDataGrid ... >
        <DxRemoteOperations :filtering="false" />
        <DxColumn
            data-field="Products"
            data-type="string"
            :calculate-filter-expression="calculateFilterExpression"
        >
        </DxColumn>
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxRemoteOperations,
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxRemoteOperations,
    },
    data() {
        // ...
    },
    methods: {
        calculateFilterExpression(filterValue, selectedFilterOperation, target) {
            let column = this;
            if (filterValue) {
                let selector = (data) => {
                    let applyOperation = (arg1, arg2, op) => {
                        if (op === "=") return arg1 === arg2;
                        if (op === "contains") return arg1.includes(arg2);
                        if (op === "startswith") return arg1.startsWith(arg2);
                        if (op === "endswith") return arg1.endsWith(arg2);
                    };
                    let values = column.calculateCellValue(data);
                    return values && !!values.find(v => applyOperation(v, filterValue, selectedFilterOperation));
                };
                return [selector, "=", true];
            }
            return this.defaultCalculateFilterExpression.apply(this, arguments);
        }
    }
}
</script>
React
App.js
import React from 'react';

import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column, RemoteOperations, 
} from 'devextreme-react/data-grid';

const calculateFilterExpression = (filterValue, selectedFilterOperation, target) => {
    let column = this;
    if (filterValue) {
        let selector = (data) => {
            let applyOperation = (arg1, arg2, op) => {
                if (op === "=") return arg1 === arg2;
                if (op === "contains") return arg1.includes(arg2);
                if (op === "startswith") return arg1.startsWith(arg2);
                if (op === "endswith") return arg1.endsWith(arg2);
            };
            let values = column.calculateCellValue(data);
            return values && !!values.find(v => applyOperation(v, filterValue, selectedFilterOperation));
        };
        return [selector, "=", true];
    }
    return this.defaultCalculateFilterExpression.apply(this, arguments);
}

export default function App() { 
    return (
        <DataGrid ... >
            <RemoteOperations filtering={false} />
            <Column
                dataField="Products"
                dataType="string"
                calculateFilterExpression={calculateFilterExpression}
            />
        </DataGrid>
    );
}

Server-Side Filtering

The following code example demonstrates how to bind the DataGrid to the OData service and enable remote filtering. To make this solution work, make sure that your OData service supports the Any filtering operator (see Support for Any and All). This concept is also described in the following topic: Azure: OData Collection Operators.

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        columns: [
            {
                dataField: 'Products',
                dataType: "string",
                calculateCellValue: (data) => {
                    var res = [];
                    for (var i = 0; i < data.Products.length; i++)
                        res.push(data.Products[i].ProductName);
                    return res.join(', ');
                },
                calculateFilterExpression: (filterValue, selectedFilterOperation, target) {
                    return [
                        [new DevExpress.data.EdmLiteral("Products/any(o: substringof('" + filterValue + "',o/ProductName) eq true)"), "=", true]
                    ];
                }   
            },
            // ...
        ],
        // ...
    });
});
Angular
app.component.html
app.component.ts
<dx-data-grid ... >
    <dxi-column
        dataField="Products"
        dataType="string"
        [calculateFilterExpression]="calculateFilterExpression"
        [calculateCellValue]="calculateCellValue"
    >
    </dxi-column>
    // ...
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {

    calculateFilterExpression(filterValue, selectedFilterOperation, target) {
        return [
            [new DevExpress.data.EdmLiteral("Products/any(o: substringof('" + filterValue + "',o/ProductName) eq true)"), "=", true]
        ];
    }

    calculateCellValue(data) {
        var res = [];
        for (var i = 0; i < data.Products.length; i++)
            res.push(data.Products[i].ProductName);
        return res.join(', ');
    }

    // ...
}
Vue
App.vue
<template>
    <DxDataGrid ... >
        // ...
        <DxColumn
            data-field="Products"
            data-type="string"
            :calculate-filter-expression="calculateFilterExpression"
            :calculate-cell-value="calculateCellValue"
        >
        </DxColumn>
    </DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid, {
    DxColumn,
    DxRemoteOperations,
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxRemoteOperations,
    },
    data() {
        // ...
    },
    methods: {
        calculateFilterExpression(filterValue, selectedFilterOperation, target) {
            return [
                [new DevExpress.data.EdmLiteral("Products/any(o: substringof('" + filterValue + "',o/ProductName) eq true)"), "=", true]
            ];
        },
        calculateCellValue(data) {
            var res = [];
            for (var i = 0; i < data.Products.length; i++)
                res.push(data.Products[i].ProductName);
            return res.join(', ');
        }
    }
}
</script>
React
App.js
import React from 'react';

import 'devextreme/dist/css/dx.light.css';

import DataGrid, {
    Column, 
} from 'devextreme-react/data-grid';

const calculateFilterExpression = (filterValue, selectedFilterOperation, target) => {
    return [
        [new DevExpress.data.EdmLiteral("Products/any(o: substringof('" + filterValue + "',o/ProductName) eq true)"), "=", true]
    ];
}

const calculateCellValue = (data) => {
    var res = [];
    for (var i = 0; i < data.Products.length; i++)
        res.push(data.Products[i].ProductName);
    return res.join(', ');
}

export default function App() { 
    return (
        <DataGrid ... >
            // ...
            <Column
                dataField="Products"
                dataType="string"
                calculateFilterExpression={calculateFilterExpression}
                calculateCellValue={calculateCellValue}
            />
        </DataGrid>
    );
}

You need to specify the calculateFilterExpression property and pass the "Products/any(o: substringof("filterValue",o/ProductName) eq true)" expression to the EdmLiteral method. In addition, you need to handle the calculateCellValue property and create a comma-separated string from ProductNames. This string will be displayed in column cells.

For the DevExtreme.AspNet.Data library, you can implement a custom filter expression compiler and pass it to the BinaryExpressionCompiler method. This method should be called before DataSourcerLoader.Load in the Controller.

The DataGrid sends a filter expression to the backend and expects relevant data as a result. The solution for filtering depends on the backend type. However, a common requirement is that the backend should implement the corresponding filtering operation.

Clear Filtering Settings

The clearFilter(filterName) method allows you to clear different filter settings depending on the argument. Acceptable arguments are listed in the method's description.

jQuery
JavaScript
// Clears the search panel
$("#dataGridContainer").dxDataGrid("instance").clearFilter("search");
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
    // Prior to Angular 8
    // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
    clearSearchPanel () {
        this.dataGrid.instance.clearFilter("search");
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template> 
    <DxDataGrid ... 
        :ref="gridRefKey"
    />       
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxDataGrid from 'devextreme-vue/data-grid';

const gridRefKey = 'data-grid';

export default {
    components: {
        DxDataGrid,
    },
    data() {
        return {
            // ...
            gridRefKey
        };
    },
    methods: {
        clearSearchPanel = () => {
            this.dataGrid.clearFilter("search");
        }
    },
    computed: {
        dataGrid: function() {
            return this.$refs[gridRefKey].instance;
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    constructor(props) {
        super(props);    
        this.gridRef = React.createRef();                  
    }
    get dataGrid() {
        return this.gridRef.current.instance;
    }

    render() {
        return (
            <DataGrid ... 
                :ref="gridRef" 
            />
        );
    }

    clearSearchPanel = () => {
        this.dataGrid.clearFilter("search");
    }
}
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .ID("dataGridContainer")
    // ... 
)

<script type="text/javascript">
    // Clears the search panel
    $("#dataGridContainer").dxDataGrid("instance").clearFilter("search");
</script>    
See Also