---
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: angular
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/angular-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 { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import "./style.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  CustomFilterModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";

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

ModuleRegistry.registerModules([CustomFilterModule, ClientSideRowModelModule]);
import { PersonFilter } from "./person-filter.component";
import { YearFilter } from "./year-filter.component";
import { IOlympicData } from "./interfaces";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular, PersonFilter, YearFilter],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [rowData]="rowData"
    (gridReady)="onGridReady($event)"
  /> `,
})
export class AppComponent {
  columnDefs: 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" },
  ];
  defaultColDef: ColDef = {
    flex: 1,
    minWidth: 100,
  };
  rowData!: IOlympicData[];

  constructor(private http: HttpClient) {}

  onGridReady(params: GridReadyEvent<IOlympicData>) {
    this.http
      .get<
        IOlympicData[]
      >("https://www.ag-grid.com/example-assets/olympic-winners.json")
      .subscribe((data) => {
        this.rowData = data;
      });
  }
}
```

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

## Implementing a Filter Component

The interface for a custom filter component is as follows:

```ts
interface IFilterAngularComp {
    // Mandatory - params for filter operations (see below for more details)
    agInit(params: IFilterParams): void;

    // 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 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;

    // 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;
}
```

## Custom Filter Parameters

The `agInit(params)` method takes a params object with the items listed 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` |  |  |  |
