---
title: "Applying Filters"
framework: react
version: "36.1.0"
---

# Applying Filters

This section describes the different ways to apply column filters.

## Apply, Clear, Reset and Cancel Buttons

By default, the provided filters - [Text Filter](https://www.ag-grid.com/react-data-grid/filter-text/), [Number Filter](https://www.ag-grid.com/react-data-grid/filter-number/), [BigInt Filter](https://www.ag-grid.com/react-data-grid/filter-bigint/), [Date Filter](https://www.ag-grid.com/react-data-grid/filter-date/) and [Set Filter](https://www.ag-grid.com/react-data-grid/filter-set/) - support different action buttons. When `enableFilterHandlers = true`, the [Multi Filter](https://www.ag-grid.com/react-data-grid/filter-multi/#applying-multi-filters) and [Custom Filter Components](https://www.ag-grid.com/react-data-grid/component-filter/#using-buttons) can also support action buttons.

The four supported action buttons are:

- **Apply** - When the Apply button is used, the filter is only applied once the Apply button is pressed. This is useful if the filtering operation will take a long time because the dataset is large, or if using server-side filtering (thus preventing unnecessary calls to the server). Pressing `↵ Enter` is equivalent to pressing the Apply button (except for the [Set Filter](https://www.ag-grid.com/react-data-grid/filter-set-mini-filter/#keyboard-shortcuts)).
- **Clear** - The Clear button clears just the filter UI.
- **Reset** - The Reset button clears the filter UI and removes any active filters for that column.
- **Cancel** - The Cancel button will discard any changes that have been made in the UI, restoring the state of the filter to match the applied model.

The buttons will be displayed in the order they are specified in the `buttons` array of the filter params (`FilterWrapperParams`).

If the filter is in a popup, it can be closed after using a button via `closeOnApply`. Note the expected behaviour when clicking the filter popup buttons:

- Apply closes popup only when `closeOnApply` set to `true`.
- Reset closes popup only when `closeOnApply` set to `true` and Apply button is present.
- Cancel closes popup only when `closeOnApply` set to `true`.
- Clear never closes popup.

### Example: Using Buttons

The example below demonstrates using the different buttons. It also demonstrates the relationship between the buttons and filter events. Note the following:

- The **Athlete** and **Age** columns have filters with Apply and Reset buttons, but different orders.
- The **Country** column has a filter with Apply and Clear buttons.
- The **Year** column has a filter with Apply and Cancel buttons.
- The **Age** and **Year** columns have `closeOnApply` set to `true`, so the filter popup will be closed immediately when the filter is applied or cancelled. Pressing `↵ Enter` will also apply the filter and close the popup.
- In the **Age** column, Reset will close the filter popup due to the presence of Apply button.

Note the following about filter events:

- `onFilterOpened` is called when the filter is opened.
- `onFilterModified` is called when the filter changes regardless of whether the Apply button is present.
- `onFilterChanged` is called only after a new filter is applied.
- Looking at the console, it can be noted when a filter is changed, the result of `getModel()` and `getModelFromUi()` are different. The first reflects the active filter, while the second reflects what is in the UI (and not yet applied).

#### Buttons and Filter Events

```tsx
("use client");

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  FilterChangedEvent,
  FilterModifiedEvent,
  FilterOpenedEvent,
  GridApi,
  GridOptions,
  INumberFilterParams,
  IProvidedFilter,
  ITextFilterParams,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  TextFilterModule,
  NumberFilterModule,
];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    {
      field: "athlete",
      filter: "agTextColumnFilter",
      filterParams: {
        buttons: ["reset", "apply"],
      } as ITextFilterParams,
    },
    {
      field: "age",
      maxWidth: 100,
      filter: "agNumberColumnFilter",
      filterParams: {
        buttons: ["apply", "reset"],
        closeOnApply: true,
      } as INumberFilterParams,
    },
    {
      field: "country",
      filter: "agTextColumnFilter",
      filterParams: {
        buttons: ["clear", "apply"],
      } as ITextFilterParams,
    },
    {
      field: "year",
      filter: "agNumberColumnFilter",
      filterParams: {
        buttons: ["apply", "cancel"],
        closeOnApply: true,
      } as INumberFilterParams,
      maxWidth: 100,
    },
    { field: "sport" },
    { field: "gold", filter: "agNumberColumnFilter" },
    { field: "silver", filter: "agNumberColumnFilter" },
    { field: "bronze", filter: "agNumberColumnFilter" },
    { field: "total", filter: "agNumberColumnFilter" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 150,
      filter: true,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const onFilterOpened = useCallback((e: FilterOpenedEvent) => {
    console.log("onFilterOpened", e);
  }, []);

  const onFilterChanged = useCallback((e: FilterChangedEvent) => {
    console.log("onFilterChanged", e);
    console.log(
      "gridRef.current!.api.getFilterModel() =>",
      e.api.getFilterModel(),
    );
  }, []);

  const onFilterModified = useCallback((e: FilterModifiedEvent) => {
    console.log("onFilterModified", e);
    console.log("applied model =>", e.api.getColumnFilterModel(e.column));
    console.log(
      "unapplied model =>",
      (e.filterInstance as unknown as IProvidedFilter).getModelFromUi(),
    );
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            ref={gridRef}
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            onFilterOpened={onFilterOpened}
            onFilterChanged={onFilterChanged}
            onFilterModified={onFilterModified}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Buttons and Filter Events](https://www.ag-grid.com/examples/filter-applying/buttons-and-filter-events/reactFunctionalTs)

## Applying the UI Model

Filters maintain a separate unapplied model representing what is shown in the UI, which might change without having yet been applied, for example when an Apply button is present and the user has made changes in the UI but not yet clicked Apply.

This happens for all grid provided filters, or when `enableFilterHandlers = true`.

Calling `api.getColumnFilterModel(column, true)` will always return a model representing the current UI, whereas `api.getColumnFilterModel(column)` will return the applied model that is currently being used for filtering.

It is also possible to perform filter actions such as applying the model via the API `doFilterAction(params)`.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `getColumnFilterModel` | `Function` |  |  | Gets the current filter model for the specified column. Will return `null` if no active filter. Modules (any of): [`TextFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`NumberFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`DateFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`SetFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`MultiFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`CustomFilterModule`](https://www.ag-grid.com/react-data-grid/modules/). |
| `doFilterAction` | `Function` |  |  | Perform the provided filter action for the column specified, or all columns. Requires `enableFilterHandlers = true`. Modules (any of): [`TextFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`NumberFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`DateFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`SetFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`MultiFilterModule`](https://www.ag-grid.com/react-data-grid/modules/), [`CustomFilterModule`](https://www.ag-grid.com/react-data-grid/modules/). |
