---
title: "Set Filter - API"
enterprise: true
framework: javascript
version: "36.1.0"
---

# Set Filter - API

This section describes how the Set Filter can be controlled programmatically using API calls.

## Set Filter Model

Get and set the state of the Set Filter by getting and setting the model on the grid API.

```js
// get filter model
const model = api.getColumnFilterModel('country');

// set filter model and update
await api.setColumnFilterModel('country', { values: ['Spain', 'Ireland', 'South Africa'] });

// refresh rows based on the filter (not automatic to allow for batching multiple filters)
api.onFilterChanged();
```

The filter model contains an array of string values where each item in the array corresponds to an element to be selected from the set.

Properties available on the `SetFilterModel` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `filterType` | `'set'` |  |  | 'set' |
| `values` | `SetFilterModelValue` |  |  | SetFilterModelValue |

When values are taken from the grid (the default, with no `filterParams.values` supplied), the model is reconciled against the values currently in the data when it is set. Any selected values that are not present are dropped and not retained: if those values later appear in the data they are not re-selected. Supply `filterParams.values` to keep selections for values that are not currently in the data. See [Refreshing Values](https://www.ag-grid.com/javascript-data-grid/filter-set-filter-list/#refreshing-values) and the [Excel Mode](https://www.ag-grid.com/javascript-data-grid/filter-set-excel-mode/) comparison.

> **Note**
>
> This value-level reconciliation is distinct from `setFilterModel` being applied asynchronously when inferring cell data types. With initially empty row data, the cell data types cannot be resolved, so the whole `setFilterModel` call is deferred until row data is added (set `cellDataType` to `false` or to an explicit value on every column to apply it synchronously). That defers the entire call once; it does not retain individual values that are absent from the data.

## Set Filter API

The Set Filter consists of two parts - the Set Filter UI (the UI component) and the Set Filter Handler (maintains the values and performs the filter logic).

Note that the Set Filter will always use a filter handler, regardless of whether `enableFilterHandlers` is enabled (which controls filter handlers for [Custom Filter Components](https://www.ag-grid.com/javascript-data-grid/component-filter/)).

The Set Filter values can be updated via the Set Filter Handler:

```js
// get filter handler
const countryFilterHandler = api.getColumnFilterHandler('country');
```

The `SetFilterHandler` interface defines the public API for the Set Filter Handler.

Properties available on the `SetFilterHandler&lt;TValue = string&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `getFilterKeys` | `Function` |  |  | Returns the full list of unique keys used by the Set Filter. |
| `getFilterValues` | `Function` |  |  | Returns the full list of unique values used by the Set Filter. |
| `setFilterValues` | `Function` |  |  | Sets the values used in the Set Filter on the fly. |
| `refreshFilterValues` | `Function` |  |  | Refreshes the values shown in the filter from the original source. For example, if a callback was provided, the callback will be executed again and the filter will refresh using the values returned. |
| `resetFilterValues` | `Function` |  |  | Resets the Set Filter to use values from the grid, rather than any values that have been provided directly. |

The Mini Filter can be interacted with via the Set Filter UI instance:

```js
// get filter UI instance
api.getColumnFilterInstance('country').then(countryFilterComponent => {
    // use set filter UI instance
});
```

The `SetFilterUi` interface defines the public API for the Set Filter UI component.

Properties available on the `SetFilterUi&lt;TValue = string&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `getMiniFilter` | `Function` |  |  | Returns the current mini-filter text. |
| `setMiniFilter` | `Function` |  |  | Sets the text in the Mini Filter at the top of the filter (the 'quick search' in the popup). |
| `getFilterHandler` | `Function` |  |  | Returns the corresponding Set Filter Handler. |

In the example below, you can see how the filter for the Athlete column is modified through the API.

#### Set Filter API

```ts
import {
  ClientSideRowModelModule,
  FirstDataRenderedEvent,
  GridApi,
  GridOptions,
  ISetFilterParams,
  KeyCreatorParams,
  ModuleRegistry,
  NumberFilterModule,
  SetFilterHandler,
  ValueFormatterParams,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  FiltersToolPanelModule,
  SetFilterModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  FiltersToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  SetFilterModule,
  NumberFilterModule,
]);

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: [
    {
      field: "athlete",
      filter: "agSetColumnFilter",
    },
    {
      field: "country",
      valueFormatter: (params: ValueFormatterParams) => {
        return `${params.value.name} (${params.value.code})`;
      },
      keyCreator: countryKeyCreator,
      filterParams: {
        valueFormatter: (params: ValueFormatterParams) => params.value.name,
      } as ISetFilterParams,
    },
    { field: "age", maxWidth: 120, filter: "agNumberColumnFilter" },
    { field: "year", maxWidth: 120 },
    { field: "date" },
    { field: "sport" },
    { field: "gold", filter: "agNumberColumnFilter" },
    { field: "silver", filter: "agNumberColumnFilter" },
    { field: "bronze", filter: "agNumberColumnFilter" },
    { field: "total", filter: "agNumberColumnFilter" },
  ],
  defaultColDef: {
    flex: 1,
    minWidth: 160,
    filter: true,
  },
  sideBar: "filters",
  onFirstDataRendered: onFirstDataRendered,
};

function countryKeyCreator(params: KeyCreatorParams) {
  return params.value.name;
}

function patchData(data: any[]) {
  // hack the data, replace each country with an object of country name and code
  data.forEach((row) => {
    const countryName = row.country;
    const countryCode = countryName.substring(0, 2).toUpperCase();
    row.country = {
      name: countryName,
      code: countryCode,
    };
  });
}

function selectJohnAndKenny() {
  gridApi!
    .setColumnFilterModel("athlete", {
      values: ["John Joe Nevin", "Kenny Egan"],
    })
    .then(() => {
      gridApi!.onFilterChanged();
    });
}

function selectEverything() {
  gridApi!.setColumnFilterModel("athlete", null).then(() => {
    gridApi!.onFilterChanged();
  });
}

function selectNothing() {
  gridApi!.setColumnFilterModel("athlete", { values: [] }).then(() => {
    gridApi!.onFilterChanged();
  });
}

function setCountriesToFranceAustralia() {
  const handler =
    gridApi!.getColumnFilterHandler<
      SetFilterHandler<{ name: string; code: string }>
    >("country");
  handler!.setFilterValues([
    {
      name: "France",
      code: "FR",
    },
    {
      name: "Australia",
      code: "AU",
    },
  ]);
}

function setCountriesToAll() {
  const handler =
    gridApi!.getColumnFilterHandler<
      SetFilterHandler<{ name: string; code: string }>
    >("country");
  handler!.resetFilterValues();
}

function onFirstDataRendered(params: FirstDataRenderedEvent) {
  params.api.getToolPanelInstance("filters")!.expandFilters();
}

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then(function (data) {
    patchData(data);
    gridApi!.setGridOption("rowData", data);
  });

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).selectJohnAndKenny = selectJohnAndKenny;
  (<any>window).selectEverything = selectEverything;
  (<any>window).selectNothing = selectNothing;
  (<any>window).setCountriesToFranceAustralia = setCountriesToFranceAustralia;
  (<any>window).setCountriesToAll = setCountriesToAll;
}
```

[Live example: Set Filter API](https://www.ag-grid.com/examples/filter-set-api/set-filter-api/typescript/)

### Enabling Case-Sensitivity

By default the API is case-insensitive. You can enable case sensitivity by using the `caseSensitive: true` filter parameter:

```js
const gridOptions = {
    columnDefs: [
        {
            field: 'colour',
            filter: 'agSetColumnFilter',
            filterParams: {
                caseSensitive: true
            }
        }
    ],

    // other grid options ...
}
```

> **Note**
>
> The `caseSensitive` option also affects [Mini-Filter](https://www.ag-grid.com/javascript-data-grid/filter-set-mini-filter/#enabling-case-sensitive-searches) searches and the values presented in the [Filter List](https://www.ag-grid.com/javascript-data-grid/filter-set-filter-list/#enabling-value-case-sensitivity).

The following example demonstrates the difference in behaviour between `caseSensitive: false` (the default) and `caseSensitive: true`:

- With `caseSensitive: false` (the default):
  - `setModel()` will perform **case-insensitive** matching against available values to decide what is enabled in the Filter List.
  - `setFilterValues()` will override the available values and force the case of the presented values in the Filter List to those provided.
    - Selected values will be maintained based upon **case-insensitive** matching.
- With `caseSensitive: true`:
  - `setModel()` will perform **case-sensitive** matching against available values to decide what is enabled in the Filter List.
  - `setFilterValues()` will override the available values and force the case of the presented values in the Filter List to those provided.
    - Selected values will be maintained based upon **case-sensitive** matching.
- In both cases `getModel()` and `getFilterValues()` will return the values with casing that matches those displayed in the Filter List. This is printed to the developer console.

#### Set Filter API - Case Sensitivity

```ts
import {
  ClientSideRowModelModule,
  FirstDataRenderedEvent,
  GridApi,
  GridOptions,
  ICellRendererParams,
  ISetFilterParams,
  ModuleRegistry,
  SetFilterHandler,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  FiltersToolPanelModule,
  SetFilterModule,
} from "ag-grid-enterprise";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  FiltersToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  SetFilterModule,
]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    {
      headerName: "Case Insensitive (default)",
      field: "colour",
      filter: "agSetColumnFilter",
      filterParams: {
        caseSensitive: false,
        cellRenderer: colourCellRenderer,
      } as ISetFilterParams,
    },
    {
      headerName: "Case Sensitive",
      field: "colour",
      filter: "agSetColumnFilter",
      filterParams: {
        caseSensitive: true,
        cellRenderer: colourCellRenderer,
      } as ISetFilterParams,
    },
  ],
  defaultColDef: {
    flex: 1,
    minWidth: 225,
    cellRenderer: colourCellRenderer,
    floatingFilter: true,
  },
  sideBar: "filters",
  onFirstDataRendered: onFirstDataRendered,
  rowData: getData(),
};

const FIXED_STYLES =
  "vertical-align: middle; border: 1px solid black; margin: 3px; display: inline-block; width: 10px; height: 10px";

const FILTER_TYPES: Record<string, string> = {
  insensitive: "colour",
  sensitive: "colour_1",
};

function colourCellRenderer(params: ICellRendererParams) {
  if (!params.value || params.value === "(Select All)") {
    return params.value;
  }

  return `<div style="background-color: ${params.value.toLowerCase()}; ${FIXED_STYLES}"></div>${params.value}`;
}

function setModel(type: string) {
  gridApi!
    .setColumnFilterModel(FILTER_TYPES[type], { values: MANGLED_COLOURS })
    .then(() => {
      gridApi!.onFilterChanged();
    });
}

function getModel(type: string) {
  console.log(
    JSON.stringify(gridApi!.getColumnFilterModel(FILTER_TYPES[type]), null, 2),
  );
}

function setFilterValues(type: string) {
  const handler = gridApi!.getColumnFilterHandler<SetFilterHandler>(
    FILTER_TYPES[type],
  );
  handler!.setFilterValues(MANGLED_COLOURS);
}

function getValues(type: string) {
  const handler = gridApi!.getColumnFilterHandler<SetFilterHandler>(
    FILTER_TYPES[type],
  );
  console.log(JSON.stringify(handler!.getFilterValues(), null, 2));
}

function reset(type: string) {
  const handler = gridApi!.getColumnFilterHandler<SetFilterHandler>(
    FILTER_TYPES[type],
  );
  handler!.resetFilterValues();
  gridApi!.setColumnFilterModel(FILTER_TYPES[type], null).then(() => {
    gridApi!.onFilterChanged();
  });
}

var MANGLED_COLOURS = ["ReD", "OrAnGe", "WhItE", "YeLlOw"];

function onFirstDataRendered(params: FirstDataRenderedEvent) {
  params.api.getToolPanelInstance("filters")!.expandFilters();
}

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).setModel = setModel;
  (<any>window).getModel = getModel;
  (<any>window).setFilterValues = setFilterValues;
  (<any>window).getValues = getValues;
  (<any>window).reset = reset;
}
```

[Live example: Set Filter API - Case Sensitivity](https://www.ag-grid.com/examples/filter-set-api/set-filter-api-case-sensitive/typescript/)
