---
title: "Floating Filters"
framework: angular
version: "36.1.0"
---

# Floating Filters

Floating Filters are an additional row under the column headers where the user will be able to see and optionally edit the filters associated with each column.

Floating filters are activated by setting the property `floatingFilter = true` on the `colDef`:

```ts
<ag-grid-angular
    [columnDefs]="columnDefs"
    /* other grid options ... */ />

this.columnDefs = [
    // column definition with floating filter enabled
    {
        field: 'country',
        filter: true,
        floatingFilter: true
    }
];
```

To have floating filters on for all columns by default, you should set `floatingFilter` on the `defaultColDef`. You can then disable floating filters on a per-column basis by setting `floatingFilter = false` on an individual `colDef`.

Floating filters depend on and co-ordinate with the main column filters. They do not have their own state, but rather display the state of the main filter and set state on the main filter if they are editable. For this reason, there is no API for getting or setting state of the floating filters.

Every floating filter takes a parameter to show/hide automatically a button that will open the main filter.

To see how floating filters work see [Floating Filter Components](https://www.ag-grid.com/angular-data-grid/component-floating-filter/).

The following example shows the following features of floating filters:

- Text filter: has out of the box read/write floating filter (Athlete and Sport columns)
- Set filter: has out of the box read-only floating filter (Country column)
- The 'Print Country' button prints the country filter model to the developer console.
- Date and Number filter: have out of the box read/write floating filters for all filters except when switching to in-range filtering, where the floating filter is read-only (Age and Date columns)
- Columns with `buttons` containing `'apply'` require the user to press `↵ Enter` on the floating filter for the filter to take effect (Gold column). (**Note:** this does not apply to floating Date Filters, which are always applied as soon as a valid date is entered.)
- Changes made directly to the main filter are reflected automatically in the floating filters (change any main filter)
- The user can configure when to show/hide the button that shows the full filter (Silver and Bronze columns)
- The Year column has a filter, but has the floating filter disabled
- The Total column has no filter and therefore no floating filter either

#### Floating Filter

```ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  DateFilterModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IDateFilterParams,
  INumberFilterParams,
  ModuleRegistry,
  NumberFilterModule,
  SetFilterHandler,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  SetFilterModule,
} from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  ColumnMenuModule,
  ContextMenuModule,
  SetFilterModule,
  TextFilterModule,
  NumberFilterModule,
  DateFilterModule,
]);
import { IOlympicData } from "./interfaces";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<div style="height: 100%; display: flex; flex-direction: column">
    <div>
      <span class="button-group">
        <button (click)="irelandAndUk()">Ireland &amp; UK</button>
        <button (click)="endingStan()">Countries Ending 'stan'</button>
        <button (click)="printCountryModel()">Print Country</button>
        <button (click)="clearCountryFilter()">Clear Country</button>
        <button (click)="destroyCountryFilter()">Destroy Country</button>
      </span>
      <span class="button-group">
        <button (click)="ageBelow25()">Age Below 25</button>
        <button (click)="ageAbove30()">Age Above 30</button>
        <button (click)="ageBelow25OrAbove30()">
          Age Below 25 or Above 30
        </button>
        <button (click)="ageBetween25And30()">Age Between 25 and 30</button>
        <button (click)="clearAgeFilter()">Clear Age Filter</button>
      </span>
      <span class="button-group">
        <button (click)="after2010()">Date after 01/01/2010</button>
        <button (click)="before2012()">Date before 01/01/2012</button>
        <button (click)="dateCombined()">Date combined</button>
        <button (click)="clearDateFilter()">Clear Date Filter</button>
      </span>
      <span class="button-group">
        <button (click)="sportStartsWithS()">Sport starts with S</button>
        <button (click)="sportEndsWithG()">Sport ends with G</button>
        <button (click)="sportsCombined()">
          Sport starts with S and ends with G
        </button>
      </span>
    </div>

    <div style="flex-grow: 1; height: 10px">
      <ag-grid-angular
        style="width: 100%; height: 100%;"
        [columnDefs]="columnDefs"
        [defaultColDef]="defaultColDef"
        [rowData]="rowData"
        (gridReady)="onGridReady($event)"
      />
    </div>
  </div> `,
})
export class AppComponent {
  private gridApi!: GridApi<IOlympicData>;

  columnDefs: ColDef[] = [
    { field: "athlete", filter: "agTextColumnFilter" },
    { field: "age", filter: "agNumberColumnFilter" },
    { field: "country", filter: "agSetColumnFilter" },
    {
      field: "year",
      maxWidth: 120,
      filter: "agNumberColumnFilter",
      floatingFilter: false,
    },
    {
      field: "date",
      minWidth: 215,
      filter: "agDateColumnFilter",
      filterParams: dateFilterParams,
    },
    { field: "sport", filter: "agTextColumnFilter" },
    {
      field: "gold",
      filter: "agNumberColumnFilter",
      filterParams: {
        buttons: ["apply"],
      } as INumberFilterParams,
    },
    {
      field: "silver",
      filter: "agNumberColumnFilter",
      floatingFilterComponentParams: {},
      suppressFloatingFilterButton: true,
    },
    {
      field: "bronze",
      filter: "agNumberColumnFilter",
      floatingFilterComponentParams: {},
      suppressFloatingFilterButton: true,
    },
    { field: "total", filter: false },
  ];
  defaultColDef: ColDef = {
    flex: 1,
    minWidth: 150,
    filter: true,
    floatingFilter: true,
    suppressHeaderMenuButton: true,
  };
  rowData!: IOlympicData[];

  constructor(private http: HttpClient) {}

  irelandAndUk() {
    this.gridApi
      .setColumnFilterModel("country", { values: ["Ireland", "Great Britain"] })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  clearCountryFilter() {
    this.gridApi.setColumnFilterModel("country", null).then(() => {
      this.gridApi.onFilterChanged();
    });
  }

  destroyCountryFilter() {
    this.gridApi.destroyFilter("country");
  }

  endingStan() {
    const countriesEndingWithStan = this.gridApi
      .getColumnFilterHandler<SetFilterHandler>("country")!
      .getFilterKeys()
      .filter(function (value: any) {
        return value.indexOf("stan") === value.length - 4;
      });
    this.gridApi
      .setColumnFilterModel("country", { values: countriesEndingWithStan })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  printCountryModel() {
    const model = this.gridApi.getColumnFilterModel("country");
    if (model) {
      console.log("Country model is: " + JSON.stringify(model));
    } else {
      console.log("Country model filter is not active");
    }
  }

  sportStartsWithS() {
    this.gridApi
      .setColumnFilterModel("sport", {
        type: "startsWith",
        filter: "s",
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  sportEndsWithG() {
    this.gridApi
      .setColumnFilterModel("sport", {
        type: "endsWith",
        filter: "g",
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  sportsCombined() {
    this.gridApi
      .setColumnFilterModel("sport", {
        conditions: [
          {
            type: "endsWith",
            filter: "g",
          },
          {
            type: "startsWith",
            filter: "s",
          },
        ],
        operator: "AND",
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  ageBelow25() {
    this.gridApi
      .setColumnFilterModel("age", {
        type: "lessThan",
        filter: 25,
        filterTo: null,
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  ageAbove30() {
    this.gridApi
      .setColumnFilterModel("age", {
        type: "greaterThan",
        filter: 30,
        filterTo: null,
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  ageBelow25OrAbove30() {
    this.gridApi
      .setColumnFilterModel("age", {
        conditions: [
          {
            type: "greaterThan",
            filter: 30,
            filterTo: null,
          },
          {
            type: "lessThan",
            filter: 25,
            filterTo: null,
          },
        ],
        operator: "OR",
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  ageBetween25And30() {
    this.gridApi
      .setColumnFilterModel("age", {
        type: "inRange",
        filter: 25,
        filterTo: 30,
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  clearAgeFilter() {
    this.gridApi.setColumnFilterModel("age", null).then(() => {
      this.gridApi.onFilterChanged();
    });
  }

  after2010() {
    this.gridApi
      .setColumnFilterModel("date", {
        type: "greaterThan",
        dateFrom: "2010-01-01",
        dateTo: null,
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  before2012() {
    this.gridApi
      .setColumnFilterModel("date", {
        type: "lessThan",
        dateFrom: "2012-01-01",
        dateTo: null,
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  dateCombined() {
    this.gridApi
      .setColumnFilterModel("date", {
        conditions: [
          {
            type: "lessThan",
            dateFrom: "2012-01-01",
            dateTo: null,
          },
          {
            type: "greaterThan",
            dateFrom: "2010-01-01",
            dateTo: null,
          },
        ],
        operator: "OR",
      })
      .then(() => {
        this.gridApi.onFilterChanged();
      });
  }

  clearDateFilter() {
    this.gridApi.setColumnFilterModel("date", null).then(() => {
      this.gridApi.onFilterChanged();
    });
  }

  onGridReady(params: GridReadyEvent<IOlympicData>) {
    this.gridApi = params.api;

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

const dateFilterParams: IDateFilterParams = {
  comparator: (filterLocalDateAtMidnight: Date, cellValue: string) => {
    const dateAsString = cellValue;
    if (dateAsString == null) return -1;
    const dateParts = dateAsString.split("/");
    const cellDate = new Date(
      Number(dateParts[2]),
      Number(dateParts[1]) - 1,
      Number(dateParts[0]),
    );
    if (filterLocalDateAtMidnight.getTime() === cellDate.getTime()) {
      return 0;
    }
    if (cellDate < filterLocalDateAtMidnight) {
      return -1;
    }
    if (cellDate > filterLocalDateAtMidnight) {
      return 1;
    }
    return 0;
  },
};
```

[Live example: Floating Filter](https://www.ag-grid.com/examples/floating-filters/floating-filter/angular)

## Provided Floating Filters

All the default filters provided by the grid provide their own implementation of a floating filter. All you need to do to enable these floating filters is set the `floatingFilter = true` column property. The features of the provided floating filters are as follows:

| Filter | Editable | Description |
| --- | --- | --- |
| Text | Sometimes | Provides a text input field to display the filter value, or a read-only label if read-only. |
| Number | Sometimes | Provides a number input field to display the filter value (unless using [Custom Number Support](https://www.ag-grid.com/angular-data-grid/filter-number/#custom-number-support)), or a read-only label if read-only. |
| Date | Sometimes | Provides a date input field to display the filter value, or a read-only label if read-only. |
| Set | No | Provides a read-only label by concatenating all selected values. |

The floating filters for Text, Number and Date (the simple filters) are editable when the filter has one condition and one value. If the floating filter has a) two or more conditions or b) zero (custom option) or two ('inRange') values, the floating filter is read-only.

The screen shots below show example scenarios where the provided Number floating filter is editable and read-only.

- **One Value and One Condition - Editable**

  ![One Value One Condition](https://www.ag-grid.com/_astro/oneValueOneCondition.dztnZIQ-.png)
- **One Value and Two Conditions - Read-Only**

  ![One Value Two Conditions](https://www.ag-grid.com/_astro/oneValueTwoConditions.DMIZHOvh.png)
- **Two Values and One Condition - Read-Only**

  ![Two Values One Condition](https://www.ag-grid.com/_astro/twoValuesOneCondition.CsQZWkEh.png)

### Controlling Autocomplete on Floating Filters

The `Text` and `Number` floating filters support overriding the browser's autocomplete behaviour on the filter's input field. You can control that autocomplete behaviour by passing `browserAutoComplete` parameter in `floatingFilterComponentParams` (as defined in `ITextFloatingFilterParams` and `INumberFloatingFilterParams`).

Possible values for `browserAutoComplete`:

- `true` to allow the browser's default autocomplete/autofill behaviour.
- `false` to disable the browser autocomplete/autofill behaviour by setting the `autocomplete` attribute to `off`.
- A **string** to be used as the [autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) attribute value.

**By default**, `browserAutoComplete` is set to `false` to disable autocomplete.

Some browsers do not respect setting the HTML attribute `autocomplete="off"` and display the auto-fill prompts anyway.

### Placeholder Text on Floating Filters

By default, no placeholder text is displayed in floating filter inputs. Placeholder text can be set using the `filterPlaceholder` property of `floatingFilterComponentParams` (as found in `ITextFloatingFilterParams` and `INumberFloatingFilterParams`):

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `filterPlaceholder` | `string \| boolean` |  |  | Placeholder text for the filter textbox. When set to `true`, inherits the placeholder text of the parent filter. |

## Custom Floating Filters

In addition to the floating filters provided by the grid, you can also create your own [Custom Floating Filter Components](https://www.ag-grid.com/angular-data-grid/component-floating-filter/).
