Framework:Javascript Data GridAngular Data GridReact Data GridVue Data Grid

React Data Grid: Multi Filter

The Multi Filter allows multiple Provided Filters or Custom Filters to be used on the same column. This provides greater flexibility when filtering data in the grid.

Multi Filter

Enabling the Multi Filter

To use a Multi Filter, specify the following in your Column Definition:

    {/* column configured to use the Multi Filter */}
    <AgGridColumn field="athlete" filter="agMultiColumnFilter" />

By default the Multi Filter will show a Text Filter and Set Filter, but you can specify which filters you would like to use in the filters array. The filters will be displayed in the same order as they are specified.

The example below shows the Multi Filter in action. Note the following:

  • The Athlete has a Multi Filter with default behaviour.
  • The Country, Gold and Date columns have Multi Filters with the child filters configured explicitly, using the Text, Number and Date Simple Filters respectively.
  • Different filterParams can be supplied to each child filter:

    • The Text Filter in the Country column has a different default option ('startsWith')
    • The Date Filter in the Date column has a custom comparator to compare dates correctly
    • The Set Filter in the Date column has a custom comparator, so the values are displayed in ascending order

Floating Filters

When Floating Filters are used, the Floating Filter shown is for the child filter in the Multi Filter that was most recently applied and is still active. If no child filters are active, the Floating Filter for the first child filter in the Multi Filter is shown instead.

The example below shows Floating Filters enabled for all columns. Note how the Floating Filters change when you apply different child filters from the Multi Filter.

Display Style

By default, all filters in the Multi Filter are shown inline in the same view, so that the user has easy, immediate access. However, you can change how filters are presented, by either using sub-menus or accordions to wrap each filter. To do this, you can set display to the style of how you would like a particular filter to be displayed:

const athleteFilterParams = {
    filters: [
            filter: 'agTextColumnFilter',
            display: 'subMenu',
            filter: 'agSetColumnFilter',

    <AgGridColumn field="athlete" filter="agMultiColumnFilter" filterParams={athleteFilterParams} />

The options for display are 'inline', 'subMenu' or 'accordion'.

Please note that sub-menus will be shown as accordions in the Tool Panel.

You can also provide a title that will be used in the menu item or accordion title by using the title property.

The following example demonstrates the different display styles.

  • The Athlete column demonstrates having the first filter inside a sub-menu.
  • The sub-menu for the Athlete filter is shown as an accordion inside the Tool Panel.
  • The Country column demonstrates having both filters as accordions.
  • A custom title is used for the first filter in the Country column.
  • The Sport column shows the default behaviour, where all filters are inline.

Custom Filters

You can use your own Custom Filters with the Multi Filter.

The example below shows a Custom Filter in use on the Year column, used alongside the grid-provided Number Filter.

Multi Filter Model

The model for the Multi Filter wraps the models for all the child filters inside it. It has the IMultiFilterModel interface:

Properties available on the IMultiFilterModel interface.

Multi filter type.
any[] | null
Child filter models in the same order as the filters are specified in filterParams.

The filterType will always be set to 'multi'. The models array is the same length as the number of child filters, containing the models for the child filters in the same order as the filters were specified in the filterParams. Each array entry will either be set to null if the corresponding child filter is not active, or to the current model for the child filter if it is active.

For example, if the Multi Filter has the default Text Filter and Set Filter, and the Set Filter is active, the Multi Filter model might look something like this:

const filterModels = [
    { filterType: 'set', values: ['A', 'B', 'C'] }

    <AgGridColumn filterType="multi" filterModels={filterModels} />

The example below allows you to see the Multi Filter Model in use. You can print the current filter state to the console and save/restore it using the buttons at the top of the grid

Accessing Child Filters

The Multi Filter acts as a wrapper around a list of child filters inside it. The order of the filters is the same order as they are specified in the filters array in the filterParams. If you want to interact with the individual child filters, you can retrieve a particular child filter instance from the Multi Filter by calling getChildFilterInstance(index), where index is the same as the index in the filters array. You can then call any API methods that are available on that particular child filter instance.

The example below shows how you can access child filter instances and call methods on them:

  • Clicking the Print Text Filter model button will access the Text Filter inside the Multi Filter and print the model for the current UI to the console.
  • Clicking the Print Set Filter search text button will access the Set Filter inside the Multi Filter and print the current search text to the console.

Multi Filter Parameters

Properties available on the IMultiFilterParams interface.

An array of filter definition objects.
filters: IMultiFilterDef[];

interface IMultiFilterDef {
  // Configures how the filter is shown in the Multi Filter.
  // Default: `inline` 
  display?: 'inline' | 'accordion' | 'subMenu';
  // The title to be used when a filter is displayed inside a sub-menu or accordion. 
  title?: string;
  // Filter component to use for this column.
  // - Set to `true` to use the default filter.
  // - Set to the name of a provided filter: `set`, `number`, `text`, `date`. 
  // - Set to a `IFilterComp`. 
  filter?: IFilterType;
  // Provided a custom framework filter to use for this column. 
  filterFramework?: any;
  // Params to be passed to the filter component specified in `filter` or `filterFramework`. 
  filterParams?: any;
  // The custom component to be used for rendering the floating filter.
  // If none is specified the default AG Grid is used. 
  floatingFilterComponent?: IFloatingFilterType;
  // Floating filter framework component to use for this column. 
  floatingFilterComponentFramework?: any;
  // Params to be passed to `floatingFilterComponent` or `floatingFilterComponentFramework`. 
  floatingFilterComponentParams?: any;
If true, all UI inputs managed by this filter are for display only, and the filter can only be affected by API calls. Does NOT affect child filters, they need to be individually configured with readOnly where applicable. See Read-only Filter UI.
Default: false


Properties available on the IMultiFilterDef interface.

'inline' | 'accordion' | 'subMenu'
Configures how the filter is shown in the Multi Filter. See Display Style.
Default: inline
The title to be used when a filter is displayed inside a sub-menu or accordion.
Child filter component to use inside the Multi Filter.
filter: IFilterType;

type IFilterType = 
    | { new (): IFilterComp; } 
    | boolean
Child framework filter component to use inside the Multi Filter.
Custom parameters to be passed to the child filter component.
Floating filter component to use for the child filter.
floatingFilterComponent: IFloatingFilterType;

type IFloatingFilterType = 
    | { new (): IFloatingFilterComp; }

interface IFloatingFilterComp {
  onParentModelChanged(parentModel: any, filterChangedEvent?: FilterChangedEvent | null): void;
  // Return the DOM element of your component, this is what the grid puts into the DOM 
  getGui(): HTMLElement;
  // Gets called once by grid when the component is being removed; if your component needs to do any cleanup, do it here 
  destroy?(): void;
  // A hook to perform any necessary operation just after the GUI for this component has been rendered
  // on the screen.
  // If a parent popup is closed and reopened (e.g. for filters), this method is called each time the component is shown.
  // This is useful for any
  // logic that requires attachment before executing, such as putting focus on a particular DOM
  // element. The params has one callback method 'hidePopup', which you can call at any later
  // point to hide the popup - good if you have an 'Apply' button and you want to hide the popup
  // after it is pressed. 
  afterGuiAttached?(params?: IAfterGuiAttachedParams): void;
  // The init(params) method is called on the component once. See below for details on the parameters. 
  init?(params: IFloatingFilterParams): AgPromise<void> | void;

interface FilterChangedEvent {
  // True if the filter was changed as a result of data changing 
  afterDataChange?: boolean;
  // True if filter was changed via floating filter 
  afterFloatingFilter?: boolean;
  // Columns affected by the filter change. Array contents depend on the source of the event.
  // - Expect 1 element for UI-driven column filter changes.
  // - Expect 0-N elements (all affected columns) for calls to `gridOptions.api.setFilterModel()`.
  // - Expect 0-N elements (removed columns) for calls to `gridOptions.api.setColumnDefs()`.
  // - Expect 0 elements for quick-filters and calls to `gridOptions.api.onFilterChanged()`. 
  columns: Column[];
  api: GridApi;
  columnApi: ColumnApi;
  // Event identifier 
  type: string;

interface IAfterGuiAttachedParams {
  container?: ContainerType;
  hidePopup?: () => void;
  suppressFocus?: boolean;

type ContainerType = 
    | 'contextMenu' 
    | 'toolPanel' 
    | 'floatingFilter'

interface IFloatingFilterParams {
  // The column this filter is for. 
  column: Column;
  // The params object passed to the filter. 
  // This is to allow the floating filter access to the configuration of the parent filter.
  // For example, the provided filters use debounceMs from the parent filter params. 
  filterParams: IFilterParams;
  // Boolean flag to indicate if the button in the floating filter that opens the parent filter in a popup should be displayed. 
  suppressFilterButton: boolean;
  api: GridApi;
  // This is a shortcut to invoke getModel on the parent filter.
  // If the parent filter doesn't exist (filters are lazily created as needed)
  // then it returns null rather than calling getModel() on the parent filter. 
  currentParentModel: () => any;
  // Gets a reference to the parent filter. The result is returned asynchronously
  // via a callback as the parent filter may not exist yet. If it does
  // not exist, it is created and asynchronously returned (AG Grid itself
  // does not create components asynchronously, however if providing a framework
  // provided filter e.g. React, it might be).
  // The floating filter can then call any method it likes on the parent filter.
  // The parent filter will typically provide its own method for the floating
  // filter to call to set the filter. For example, if creating custom filter A,
  // it should have a method your floating A can call to set the state
  // when the user updates via the floating filter. 
  parentFilterInstance: (callback: (filterInstance: IFilterComp) => void) => void;
  // Shows the parent filter popup. 
  showParentFilter: () => void;

interface IFilterParams {
  // The column this filter is for. 
  column: Column;
  // The column definition for the column. 
  colDef: ColDef;
  // The row model, helpful for looking up data values if needed.
  // If the filter needs to know which rows are
  // a) in the table,
  // b) currently visible (i.e. not already filtered),
  // c) which groups,
  // d) what order - all of this can be read from the rowModel. 
  rowModel: IRowModel;
  // A function callback to be called when the filter changes. The
  // grid will then respond by filtering the grid data. The callback
  // takes one optional parameter which, if included, will get merged
  // to the FilterChangedEvent object (useful for passing additional
  // information to anyone listening to this event, however such extra
  // attributes are not used by the grid). 
  filterChangedCallback: (additionalEventAttributes?: any) => void;
  // A function callback, to be optionally called, when the filter UI changes.
  // The grid will respond with emitting a FilterModifiedEvent.
  // Apart from emitting the event, the grid takes no further action. 
  filterModifiedCallback: () => void;
  // A function callback for the filter to get cell values from the row data.
  // Call with a node to be given the value for that filter's column for that node.
  // The callback takes care of selecting the right column definition and deciding whether to use valueGetter or field etc.
  // This is useful in, for example, creating an Excel style filter,
  // where the filter needs to lookup available values to allow the user to select from. 
  valueGetter: (rowNode: RowNode) => any;
  // A function callback, call with a node to be told whether the node passes all filters except the current filter.
  // This is useful if you want to only present to the user values that this filter can filter given the status of the other filters.
  // The set filter uses this to remove from the list,
  // items that are no longer available due to the state of other filters (like Excel type filtering). 
  doesRowPassOtherFilter: (rowNode: RowNode) => boolean;
  api: GridApi;
  columnApi: ColumnApi;
  // The context as provided on `gridOptions.context` 
  context: any;

interface IRowModel {
  // Returns the rowNode at the given index. 
  getRow(index: number): RowNode | undefined;
  // Returns the rowNode for given id. 
  getRowNode(id: string): RowNode | undefined;
  // This is legacy, not used by AG Grid, but keeping for backward compatibility 
  getRowCount(): number;
  getTopLevelRowCount(): number;
  getTopLevelRowDisplayedIndex(topLevelIndex: number): number;
  // Returns the row index at the given pixel 
  getRowIndexAtPixel(pixel: number): number;
  // Returns true if the provided rowNode is in the list of rows to render 
  isRowPresent(rowNode: RowNode): boolean;
  // Returns row top and bottom for a given row 
  getRowBounds(index: number): RowBounds | null;
  // Returns true if this model has no rows, regardless of model filter. EG if rows present, but filtered
  // out, this still returns false. If it returns true, then the grid shows the 'no rows' overlay - but we
  // don't show that overlay if the rows are just filtered out. 
  isEmpty(): boolean;
  // Returns true if no rows (either no rows at all, or the rows are filtered out). This is what the grid
  // uses to know if there are rows to render or not. 
  isRowsToRender(): boolean;
  // Returns all rows in range that should be selected. If there is a gap in range (non ClientSideRowModel) then
  // then no rows should be returned 
  getNodesInRangeForSelection(first: RowNode, last: RowNode | null): RowNode[];
  // Iterate through each node. What this does depends on the model type. For clientSide, goes through
  // all nodes. For serverSide, goes through what's loaded in memory. 
  forEachNode(callback: (rowNode: RowNode, index: number) => void): void;
  // The base class returns the type. We use this instead of 'instanceof' as the client might provide
  // their own implementation of the models in the future. 
  getType(): string;
  // It tells us if this row model knows about the last row that it can produce. This is used by the
  // PaginationPanel, if last row is not found, then the 'last' button is disabled and the last page is
  // not shown. This is always true for ClientSideRowModel. It toggles for InfiniteRowModel. 
  isLastRowIndexKnown(): boolean;
  // Used by CSRM only - is makes sure there are now estimated row heights within the range. 
  ensureRowHeightsValid(startPixel: number, endPixel: number, startLimitIndex: number, endLimitIndex: number): boolean;
  // Gets called after grid is initialised. What happens depends on row model. Client Side will take rowData
  // from gridOptions, the other row models will start calling their datasources. 
  start(): void;

interface RowBounds {
  rowTop: number;
  rowHeight: number;
  rowIndex?: number;
Floating framework filter component to use for the child filter.
Custom parameters to be passed to the floating filter component.

Multi Filter API

Returns true if the filter is currently active, otherwise false.
function isFilterActive(): boolean;
Returns a model representing the current state of the filter, or null if the filter is not active.
function getModel(): IMultiFilterModel;

interface IMultiFilterModel {
  // Multi filter type. 
  filterType?: 'multi';
  // Child filter models in the same order as the filters are specified in `filterParams`. 
  filterModels: any[] | null;
Sets the state of the child filters using the supplied models. Providing null will de-activate all child filters.

Note: if you are providing values asynchronously to a child Set Filter, you need to wait for these changes to be applied before performing any further actions by waiting on the returned grid promise, e.g. filter.setModel([null, { values: ['a', 'b'] }]).then(function() { gridApi.onFilterChanged(); });
function setModel(
    model: IMultiFilterModel | null
): void;
Returns the child filter instance at the specified index. See Accessing Child Filters.
function getChildFilterInstance(index: number): IFilterComp;