Skip to content

Data Grid - Filtering

Easily filter your rows based on one or several criteria.

The filters can be modified through the grid interface in several ways:

  • By opening the column menu and clicking the Filter menu item.
  • By clicking the Filters button in the grid toolbar (if enabled).

Each column types has its own filter operators. The demo below let you explore all the operators for each built-in column type.

See the dedicated section to learn how to create your own custom filter operator.

Single and multi-filtering

⚠️ The DataGrid can only filter the rows according to one criterion at the time.

To use multi-filtering, you need to upgrade to the Pro plan

The demo below lets you filter the rows according to several criteria at the same time.

Pass filters to the grid

Structure of the model

The full typing details can be found on the GridFilterModel API page.

The filter model is composed of a list of items and a linkOperator:

The items

A filter item represents a filtering rule and is composed of several elements:

  • filterItem.columnField: the field on which we want to apply the rule.
  • filterItem.value: the value to look for.
  • filterItem.operatorValue: name of the operator method to use (e.g. contains), matches the value key of the .
  • filterItem.id (): only useful when multiple filters are used.

Note: Some operators do not need any value (for instance the isEmpty operator of the string column).

The linkOperator

The linkOperator tells the grid if a row should satisfy all (AND) filter items or at least one (OR) in order to be considered valid.

// Example 1: get rows with rating > 4 OR isAdmin = true
const filterModel: GridFilterModel = {
  items: [
    { id: 1, columnField: 'rating', operatorValue: '>', value: '4' },
    { id: 2, columnField: 'isAdmin', operatorValue: 'is', value: 'true' },
  ],
  linkOperator: GridLinkOperator.Or,
};

// Example 2: get rows with rating > 4 AND isAdmin = true
const filterModel: GridFilterModel = {
  items: [
    { id: 1, columnField: 'rating', operatorValue: '>', value: '4' },
    { id: 2, columnField: 'isAdmin', operatorValue: 'is', value: 'true' },
  ],
  linkOperator: GridLinkOperator.And,
};

If no linkOperator is provided, the grid will use GridLinkOperator.Or by default.

Initialize the filters

To initialize the filters without controlling them, provide the model to the initialState prop.

<DataGrid
  initialState={{
    filter: {
      filterModel: {
        items: [{ columnField: 'rating', operatorValue: '>', value: '2.5' }],
      },
    },
  }}
/>

Controlled filters

Use the filterModel prop to control the filter applied on the rows.

You can use the onFilterModelChange prop to listen to changes to the filters and update the prop accordingly.

<DataGrid
  filterModel={{
    items: [{ columnField: 'rating', operatorValue: '>', value: '2.5' }],
  }}
/>

Disable the filters

For all columns

Filters are enabled by default, but you can easily disable this feature by setting the disableColumnFilter prop.

<DataGrid disableColumnFilter />

For some columns

To disable the filter of a single column, set the filterable property in GridColDef to false.

In the example below, the rating column can not be filtered.

<Datagrid columns={[...columns, { field: 'rating', filterable: false }]} />

Customize the operators

The full typing details can be found on the GridFilterOperator api page.

An operator determines if a cell value should be considered as a valid filtered value. The candidate value used by the operator is the one corresponding to the field attribute or the value returned by the valueGetter of the GridColDef.

Each column type comes with a default array of operators. You can get them by importing the following functions:

Column type Function
string getGridStringOperators()
number getGridNumericOperators()
boolean getGridBooleanOperators()
date getGridDateOperators()
dateTime getGridDateOperators(true)
singleSelect getGridSingleSelectOperators()

You can find more information about the supported column types in the columns section.

Create a custom operator

If the built-in filter operators are not enough, creating a custom operator is an option. A custom operator is defined by creating a GridFilterOperator object. This object has to be added to the filterOperators attribute of the GridColDef.

The main part of an operator is the getApplyFilterFn function. When applying the filters, the grid will call this function with the filter item and the column on which the item must be applied. This function must return another function that takes the cell value as an input and return true if it satisfies the operator condition.

const operator: GridFilterOperator = {
  label: 'From',
  value: 'from',
  getApplyFilterFn: (filterItem: GridFilterItem, column: GridColDef) => {
    if (!filterItem.columnField || !filterItem.value || !filterItem.operatorValue) {
      return null;
    }

    return (params: GridCellParams): boolean => {
      return Number(params.value) >= Number(filterItem.value);
    };
  },
  InputComponent: RatingInputValue,
  InputComponentProps: { type: 'number' },
};

Note: The valueFormatter is only used for rendering purposes.

Note: If the column has a valueGetter, then params.value will be the resolved value.

In the demo below, you can see how to create a completely new operator for the Rating column.

Multiple values operator

You can create a custom operator which accepts multiple values. To do this, provide an array of values to the value property of the filterItem. The valueParser of the GridColDef will be applied to each item of the array.

The filtering function getApplyFilterFn must be adapted to handle filterItem.value as an array. Below is an example for a "between" operator, applied on the "Quantity" column.

{
  label: 'Between',
  value: 'between',
  getApplyFilterFn: (filterItem: GridFilterItem) => {
    if (!Array.isArray(filterItem.value) || filterItem.value.length !== 2) {
      return null;
    }
    if (filterItem.value[0] == null || filterItem.value[1] == null) {
      return null;
    }
    return ({ value }): boolean => {
      return value != null && filterItem.value[0] <= value && value <= filterItem.value[1];
    };
  },
  InputComponent: InputNumberInterval,
}

Remove an operator

To remove built-in operators, import the method to generate them and filter the output to fit your needs.

// Only keep '>' and '<' default operators
const filterOperators = getGridNumericOperators().filter(
  (operator) => operator.value === '>' || operator.value === '<',
);

In the demo below, the rating column only has the < and > operators.

Edit an operator

The value used by the operator to look for has to be entered by the user. On most column types, a text field is used. However, a custom component can be rendered instead.

In the demo below, the rating column reuses the numeric operators but the rating component is used to enter the value of the filter.

Custom column types

When defining a custom column type, by default the grid will reuse the operators from the type that was extended. The filter operators can then be edited just like on a regular column.

const ratingColumnType: GridColTypeDef = {
  extendType: 'number',
  filterOperators: getGridNumericOperators().filter(
    (operator) => operator.value === '>' || operator.value === '<',
  ),
};

Custom filter panel

You can customize the rendering of the filter panel as shown in the component section of the documentation.

The demo below shows how to anchor the filter panel to the toolbar button instead of the column header.

Server-side filter

Filtering can be run server-side by setting the filterMode prop to server, and implementing the onFilterModelChange handler.

Below is a very simple demo on how you could achieve server-side filtering.

<DataGrid
  rows={rows}
  columns={columns}
  filterMode="server"
  onFilterModelChange={onFilterChange}
  loading={loading}
/>

Quick filter

The grid does not natively include quick filtering. However, it can be implemented as in the demo below.

⚠️ This feature isn't natively implemented in the grid package. It's coming.

👍 Upvote issue #2842 if you want to see it land faster.

apiRef

⚠️ Only use this API as the last option. Give preference to the props to control the grid.

Signature:
deleteFilterItem: (item: GridFilterItem) => void
Signature:
getVisibleRowModels: () => Map<GridRowId, GridRowModel>
Signature:
hideFilterPanel: () => void
Signature:
setFilterLinkOperator: (operator: GridLinkOperator) => void
Signature:
setFilterModel: (model: GridFilterModel) => void
Signature:
showFilterPanel: (targetColumnField?: string) => void
Signature:
upsertFilterItem: (item: GridFilterItem) => void

Selectors

Signature:
gridFilterModelSelector: (state: GridState) => GridFilterModel
Example
const filterModel = gridFilterModelSelector(
  apiRef.current.state
);
Signature:
gridVisibleRowCountSelector: (state: GridState) => number
Example
const visibleRowCount = gridVisibleRowCountSelector(
  apiRef.current.state
);
Signature:
gridVisibleSortedRowEntriesSelector: (state: GridState) => { id: GridRowId; model: { [key: string]: any } }[]
Example
const visibleSortedRowEntries = gridVisibleSortedRowEntriesSelector(
  apiRef.current.state
);
Signature:
gridVisibleSortedRowIdsSelector: (state: GridState) => GridRowId[]
Example
const visibleSortedRowIds = gridVisibleSortedRowIdsSelector(
  apiRef.current.state
);
Signature:
gridVisibleSortedTopLevelRowEntriesSelector: (state: GridState) => { id: GridRowId; model: { [key: string]: any } }[]
Example
const visibleSortedTopLevelRowEntries = gridVisibleSortedTopLevelRowEntriesSelector(
  apiRef.current.state
);
Signature:
gridVisibleTopLevelRowCountSelector: (state: GridState) => number
Example
const visibleTopLevelRowCount = gridVisibleTopLevelRowCountSelector(
  apiRef.current.state
);

More information about the selectors and how to use them on the dedicated page

API