---
product: "AG Grid"
title: "Filter Component - Legacy"
description: "The example below shows two custom filters. The first is on the Athlete column and demonstrates a filter with \"fuzzy\" matching and the second is on the Year column with preset options."
framework: vue
version: "36.2.0"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Filter Component - Legacy

> **Warning**
>
> This page describes the old way of declaring custom filter components when the grid option `enableFilterHandlers` is not set. It is strongly recommended to instead use the new behaviour described on the [Filter Component](https://www.ag-grid.com/archive/36.2.0/vue-data-grid/component-filter/) page.

The example below shows two custom filters. The first is on the `Athlete` column and demonstrates a filter with "fuzzy" matching and the second is on the `Year` column with preset options.

#### Custom Filter Component

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./style.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  CustomFilterModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import PersonFilter from "./personFilterVue";
import YearFilter from "./yearFilterVue";
import { IOlympicData } from "./interfaces";

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

ModuleRegistry.registerModules([CustomFilterModule, ClientSideRowModelModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    PersonFilter,
    YearFilter,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete", minWidth: 150, filter: "PersonFilter" },
      { field: "year", minWidth: 130, filter: "YearFilter" },
      { field: "country", minWidth: 150 },
      { field: "sport" },
      { field: "gold" },
      { field: "silver" },
      { field: "bronze" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => {
        rowData.value = data;
      };

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Custom Filter Component](https://www.ag-grid.com/archive/36.2.0/examples/component-filter-legacy/custom-filter-legacy/vue3/)

## Implementing a Filter Component

When a Vue component is instantiated the grid will make the grid APIs, a number of utility methods as well as the cell & row values available to you via `this.params`.

The interface for a custom filter component is as follows:

```ts
interface IFilter {

    // Return true if the filter is active. If active then 1) the grid will show the filter icon in the column
    // header and 2) the filter will be included in the filtering of the data.
    isFilterActive(): boolean;

    // The grid will ask each active filter, in turn, whether each row in the grid passes. If any
    // filter fails, then the row will be excluded from the final set. A params object is supplied
    // containing attributes of node (the rowNode the grid creates that wraps the data) and data (the data
    // object that you provided to the grid for that row). Note that this is only called for the
    // Client-Side Row Model, and can just return `true` if being used exclusively with other row models.
    doesFilterPass(params: IDoesFilterPassParams): boolean;

    // Gets the filter state. If filter is not active, then should return null/undefined.
    // The grid calls getModel() on all active filters when gridApi.getFilterModel() is called.
    getModel(): any;

    // Restores the filter state. Called by the grid after gridApi.setFilterModel(model) is called.
    // The grid will pass undefined/null to clear the filter.
    setModel(model: any): void;

    // Optional methods

    // Gets called when new rows are inserted into the grid. If the filter needs to change its
    // state after rows are loaded, it can do it here. For example the set filters uses this
    // to update the list of available values to select from (e.g. 'Ireland', 'UK' etc for
    // Country filter). To get the list of available values from within this method from the
    // Client Side Row Model, use gridApi.forEachLeafNode(callback)
    onNewRowsLoaded?(): void;

    // Called whenever any filter is changed.
    onAnyFilterChanged?(): void;

    // When defined, this method is called whenever the parameters provided in colDef.filterParams
    // change. The result returned by this method will determine if the filter should be
    // refreshed and reused, or if a new filter instance should be created.
    //
    // When true is returned, the existing filter instance should be refreshed and reused instead
    // of being destroyed. This is useful if the new params passed are compatible with the
    // existing filter instance. When false is returned, the existing filter will be destroyed
    // and a new filter instance will be created. This should be done if you do not wish to reuse
    // the existing filter instance.
    //
    // When this method is not provided, the default behaviour is to destroy and recreate the
    // filter instance everytime colDef.filterParams changes.
    refresh?(newParams: IFilterParams): boolean;

    // Gets called when the column is destroyed. If your custom filter needs to do
    // any resource cleaning up, do it here. A filter is NOT destroyed when it is
    // made 'not visible', as the GUI is kept to be shown again if the user selects
    // that filter again. The filter is destroyed when the column it is associated with is
    // destroyed, either when new columns are set into the grid, or the grid itself is destroyed.
    destroy?(): void;

    // If floating filters are turned on for the grid, but you have no floating filter
    // configured for this column, then the grid will check for this method. If this
    // method exists, then the grid will provide a read-only floating filter for you
    // and display the results of this method. For example, if your filter is a simple
    // filter with one string input value, you could just return the simple string
    // value here.
    getModelAsString?(model: any): string;

    // Gets called every time the popup is shown, after the GUI returned in
    // getGui is attached to the DOM. If the filter popup is closed and re-opened, this method is
    // called each time the filter 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 a
    // 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;

    // Gets called every time the popup is hidden, after the GUI returned in getGui is detached
    // from the DOM. If the filter popup is closed and re-opened, this method is called each time
    // the filter is hidden. This is useful for any logic to reset the UI state back to the model
    // before the component is reopened.
    afterGuiDetached?(): void;
}
```

## Custom Filter Parameters

When a Vue component is instantiated the grid will make the grid APIs, a number of utility methods as well as the cell and row values available to you via `this.params` - the interface for what is provided is documented below.

If custom params are provided via the `colDef.filterParams` property, these will be additionally added to the params object, overriding items of the same name if a name clash exists.

Properties available on the `IFilterParams&lt;TData = any, TContext = any&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `filterChangedCallback` | `Function` |  |  |  |
| `filterModifiedCallback` | `Function` |  |  |  |
| `column` | `Column` |  |  |  |
| `colDef` | `ColDef` |  |  |  |
| `getValue` | `Function` |  |  |  |
| `doesRowPassOtherFilter` | `Function` |  |  |  |
| `api` | `GridApi` |  |  |  |
| `context` | `TContext` |  |  |  |

### IDoesFilterPassParams

The method `doesFilterPass(params)` takes the following as a parameter:

Properties available on the `IDoesFilterPassParams&lt;TData = any&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `node` | `IRowNode` |  |  |  |
| `data` | `TData` |  |  |  |
