---
title: "Filter Conditions"
framework: vue
version: "36.1.0"
---

# Filter Conditions

This section describes the Filter Conditions shared by the Simple Filters provided by the grid - [Text Filter](https://www.ag-grid.com/vue-data-grid/filter-text/), [Number Filter](https://www.ag-grid.com/vue-data-grid/filter-number/), [BigInt Filter](https://www.ag-grid.com/vue-data-grid/filter-bigint/) and [Date Filter](https://www.ag-grid.com/vue-data-grid/filter-date/).

Each Simple Filter follows the same layout. The filter consists of one or more Filter Conditions separated by zero or more Join Operators.

The only layout difference is the type of input field presented to the user: a text field for Text Filters, a number field for Number Filters, and a date picker field for Date Filters.

![Filter Panel Component](https://www.ag-grid.com/_astro/filter-panel-components.DEcGJvRp.png)

## Filter Options

Each filter provides a dropdown list of filter options to select from. Each filter option represents a filtering strategy, e.g. 'equals', 'not equals', etc.

Each filter's default filter options can be found on their respective pages:

- [Text Filter Options](https://www.ag-grid.com/vue-data-grid/filter-text/#text-filter-options)
- [Number Filter Options](https://www.ag-grid.com/vue-data-grid/filter-number/#number-filter-options)
- [Date Filter Options](https://www.ag-grid.com/vue-data-grid/filter-date/#filter-options)

Information on defining [Custom Filter Options](#custom-filter-options) can be found below.

## Filter Value

Each filter option takes zero (a possibility with custom options), one (for most) or two (for 'inRange') values. The value type depends on the filter type, e.g. the Date Filter takes Date values.

## Number of Conditions

By default each filter initially only displays one Filter Condition. When the user completes all the visible Filter Conditions, another Filter Condition becomes visible. When the user clears the last completed Filter Condition, any empty Filter Conditions on either side are hidden if required. Additionally, when the filter is closed, any empty Filter Conditions not at the end are removed if required.

The maximum number of Filter Conditions can be controlled by setting the Filter Parameter `maxNumConditions` (the default value is two).

It is also possible to always display a certain number of Filter Conditions by setting the Filter Parameter `numAlwaysVisibleConditions`. In this case, Filter Conditions at the end will be disabled until the previous Filter Condition has been completed.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `maxNumConditions` | `number` |  | `2` | Maximum number of conditions allowed in the filter. |
| `numAlwaysVisibleConditions` | `number` |  | `1` | By default only one condition is shown, and additional conditions are made visible when the previous conditions are entered (up to `maxNumConditions`). To have more conditions shown by default, set this to the number required. Conditions will be disabled until the previous conditions have been entered. Note that this cannot be greater than `maxNumConditions` - anything larger will be ignored. |

## Join Operator

The Join Operator decides how the Filter Conditions are joined, using either `AND` or `OR`. All Join Operators have the same value, with only the first one being editable when there are multiple.

## Example: Simple Filter Conditions

The following example demonstrates Filter Condition configuration that can be applied to any Simple Filter.

- The **Athlete** column shows a Text Filter with default behaviour for all options.
- The **Country** column shows a Text Filter with `filterOptions` set to show a different list of available options, and `defaultOption` set to change the default option selected.
- The **Sport** column shows a Text Filter with `maxNumConditions` set to `10` so that up to ten conditions can be entered.
- The **Age** column has a Number Filter with `numAlwaysVisibleConditions` set to `2` so that two conditions are always shown. The `defaultJoinOperator` is also set to `'OR'` rather than the default (`'AND'`).
- The **Date** column has a Date Filter with `maxNumConditions` set to `1`, so that only the first condition is shown.

#### Simple Filter Conditions

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  DateFilterModule,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IDateFilterParams,
  INumberFilterParams,
  ITextFilterParams,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  ClientSideRowModelModule,
  NumberFilterModule,
  DateFilterModule,
]);

const filterParams: IDateFilterParams = {
  maxNumConditions: 1,
  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;
  },
};

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,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "athlete" },
      {
        field: "country",
        filterParams: {
          filterOptions: ["contains", "startsWith", "endsWith"],
          defaultOption: "startsWith",
        } as ITextFilterParams,
      },
      {
        field: "sport",
        filterParams: {
          maxNumConditions: 10,
        } as ITextFilterParams,
      },
      {
        field: "age",
        filter: "agNumberColumnFilter",
        filterParams: {
          numAlwaysVisibleConditions: 2,
          defaultJoinOperator: "OR",
        } as INumberFilterParams,
        maxWidth: 100,
      },
      {
        field: "date",
        filter: "agDateColumnFilter",
        filterParams: filterParams,
      },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 150,
      filter: true,
    });
    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: Simple Filter Conditions](https://www.ag-grid.com/examples/filter-conditions/simple-filter-options/vue3)

## Custom Filter Options

For applications that have bespoke filtering requirements, it is also possible to add new custom filtering options to the number, text and date filters. For example, a 'Not Equal (with Nulls)' filter option could be included alongside the built in 'Not Equal' option.

Custom filter options are supplied to the grid via `filterParams.filterOptions` and must conform to the `IFilterOptionDef` interface:

Properties available on the `IFilterOptionDef` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `displayKey` | `string` |  |  | A unique key that does not clash with the built-in filter keys. |
| `displayName` | `string` |  |  | Display name for the filter. Can be replaced by a locale-specific value using a `localeTextFunc`. |
| `predicate` | `Function` |  |  | Custom filter logic that returns a boolean based on the `filterValues` and `cellValue`. |
| `numberOfInputs` | `0 \| 1 \| 2` |  |  | Number of inputs to display for this option. Defaults to `1` if unspecified. |

The `displayKey` should contain a unique key value that doesn't clash with the built-in filter keys. A default `displayName` should also be provided but can be replaced by a locale-specific value using a [getLocaleText](https://www.ag-grid.com/vue-data-grid/localisation/#locale-callback).

The custom filter logic is implemented through the `predicate` function, which receives the `filterValues` typed by the user along with the `cellValue` from the grid, and returns `true` or `false`.

The number of `filterValues` and corresponding inputs is controlled by the optional property `numberOfInputs`:

- If set to `0` all inputs are hidden, and an empty array of `filterValues` is provided to the `predicate` function.
- If unspecified or set to `1` a single input is displayed, and one-element array of `filterValues` are provided to the `predicate` function.
- If set to `2` two inputs are displayed, and a two-element array of `filterValues` is provided to the `predicate` function.

Custom `FilterOptionDef`s can be supplied alongside the built-in filter option `string` keys as shown below:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    {
        field: 'age',
        filter: 'agNumberColumnFilter',
        filterParams: {
            filterOptions: [
                'lessThan',
                {
                    displayKey: 'lessThanWithNulls',
                    displayName: 'Less Than with Nulls',
                    predicate: ([filterValue], cellValue) => cellValue == null
                        || cellValue < filterValue,
                },
                'greaterThan',
                {
                    displayKey: 'greaterThanWithNulls',
                    displayName: 'Greater Than with Nulls',
                    predicate: ([filterValue], cellValue) => cellValue == null
                       || cellValue > filterValue,
                },
                {
                    displayKey: 'betweenExclusive',
                    displayName: 'Between (Exclusive)',
                    predicate: ([fv1, fv2], cellValue) => cellValue == null
                        || fv1 < cellValue && fv2 > cellValue,
                    numberOfInputs: 2,
                }
            ]
        }
    }
];
```

When providing filter options, the default filter option (or the first option if no default set) must be an option with `numberOfInputs` greater than zero or the `'empty'` filter option (as a filter option with no inputs would mean the filter is active by default).

The following example demonstrates several custom filter options:

- The **Athlete** column contains four custom filter options managed by a [Text Filter](https://www.ag-grid.com/vue-data-grid/filter-text/):
  - `Starts with "A"` and `Starts with "N"` have no inputs; their predicate function is provided zero values.
  - `Regular Expression` has one input; its predicate function is provided one value.
  - `Between (Exclusive)` has two inputs; its predicate function is provided two values.
- The **Age** column contains five custom filter options managed by a [Number Filter](https://www.ag-grid.com/vue-data-grid/filter-number/):
  - `Even Numbers`, `Odd Numbers` and `Blanks` have no inputs; their predicate function is provided zero values.
  - `Age 5 Years Ago` has one input; its predicate function is provided one value.
  - `Between (Exclusive)` has two inputs; its predicate function is provided two values.
  - `Choose one` is a built-in option and acts as an inactive filter option.
  - The `maxNumConditions=1` option is used to only display one Filter Condition.
- The **Date** column contains three custom filter options managed by a [Date Filter](https://www.ag-grid.com/vue-data-grid/filter-date/):
  - `Equals (with Nulls)` has one inputs; its predicate function is provided one value.
  - `Leap Year` has no inputs; its predicate function is provided zero values.
  - `Between (Exclusive)` has two inputs; its predicate function is provided two values.
  - NOTE: a custom `comparator` is still required for the built-in date filter options, i.e. `equals`.
- The **Country** column includes:
  - a custom `* Not Equals (No Nulls) *` filter which also removes null values.
  - it also demonstrates how localisation can be achieved via the `gridOptions.getLocaleText(params)` callback function, where the default value is replaced for the filter option `'notEqualNoNulls'`.
- Saving and restoring custom filter options via `api.getFilterModel()` and `api.setFilterModel()` can be tested using the provided buttons.
- The `Print State` button prints the filter model to the developer console.

#### Custom Filter Options

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  DateFilterModule,
  GetLocaleText,
  GetLocaleTextParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IDateFilterParams,
  IFilterOptionDef,
  INumberFilterParams,
  ITextFilterParams,
  LocaleModule,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  LocaleModule,
  TextFilterModule,
  ClientSideRowModelModule,
  NumberFilterModule,
  DateFilterModule,
]);

declare let window: any;

const filterParams: INumberFilterParams = {
  filterOptions: [
    "empty",
    {
      displayKey: "evenNumbers",
      displayName: "Even Numbers",
      predicate: (_, cellValue) => cellValue != null && cellValue % 2 === 0,
      numberOfInputs: 0,
    },
    {
      displayKey: "oddNumbers",
      displayName: "Odd Numbers",
      predicate: (_, cellValue) => cellValue != null && cellValue % 2 !== 0,
      numberOfInputs: 0,
    },
    {
      displayKey: "blanks",
      displayName: "Blanks",
      predicate: (_, cellValue) => cellValue == null,
      numberOfInputs: 0,
    },
    {
      displayKey: "age5YearsAgo",
      displayName: "Age 5 Years Ago",
      predicate: ([fv1]: any[], cellValue) =>
        cellValue == null || cellValue - 5 === fv1,
      numberOfInputs: 1,
    },
    {
      displayKey: "betweenExclusive",
      displayName: "Between (Exclusive)",
      predicate: ([fv1, fv2], cellValue) =>
        cellValue == null || (fv1 < cellValue && fv2 > cellValue),
      numberOfInputs: 2,
    },
  ] as IFilterOptionDef[],
  maxNumConditions: 1,
};

const containsFilterParams: ITextFilterParams = {
  filterOptions: [
    "contains",
    {
      displayKey: "startsA",
      displayName: 'Starts With "A"',
      predicate: (_, cellValue) =>
        cellValue != null && cellValue.indexOf("A") === 0,
      numberOfInputs: 0,
    },
    {
      displayKey: "startsN",
      displayName: 'Starts With "N"',
      predicate: (_, cellValue) =>
        cellValue != null && cellValue.indexOf("N") === 0,
      numberOfInputs: 0,
    },
    {
      displayKey: "regexp",
      displayName: "Regular Expression",
      predicate: ([fv1]: any[], cellValue) => {
        if (cellValue === null) return true;
        try {
          let regex = new RegExp(fv1, "gi");
          return regex.test(cellValue);
        } catch {
          // Invalid RegExp, default to showing everything
          return true;
        }
      },
      numberOfInputs: 1,
    },
    {
      displayKey: "betweenExclusive",
      displayName: "Between (Exclusive)",
      predicate: ([fv1, fv2]: any[], cellValue) =>
        cellValue == null || (fv1 < cellValue && fv2 > cellValue),
      numberOfInputs: 2,
    },
  ] as IFilterOptionDef[],
};

const equalsFilterParams: IDateFilterParams = {
  filterOptions: [
    "equals",
    {
      displayKey: "equalsWithNulls",
      displayName: "Equals (with Nulls)",
      predicate: ([filterValue]: any[], cellValue) => {
        if (cellValue == null) return true;
        const parts = cellValue.split("/");
        const cellDate = new Date(
          Number(parts[2]),
          Number(parts[1] - 1),
          Number(parts[0]),
        );
        return cellDate.getTime() === filterValue.getTime();
      },
    },
    {
      displayKey: "leapYear",
      displayName: "Leap Year",
      predicate: (_, cellValue) => {
        if (cellValue == null) return true;
        const year = Number(cellValue.split("/")[2]);
        return year % 4 === 0 && year % 200 !== 0;
      },
      numberOfInputs: 0,
    },
    {
      displayKey: "betweenExclusive",
      displayName: "Between (Exclusive)",
      predicate: ([fv1, fv2]: any[], cellValue) => {
        if (cellValue == null) return true;
        const parts = cellValue.split("/");
        const cellDate = new Date(
          Number(parts[2]),
          Number(parts[1] - 1),
          Number(parts[0]),
        );
        return (
          cellDate.getTime() > fv1.getTime() &&
          cellDate.getTime() < fv2.getTime()
        );
      },
      numberOfInputs: 2,
    },
  ] as IFilterOptionDef[],
  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;
  },
};

const notEqualsFilterParams: ITextFilterParams = {
  filterOptions: [
    "notEqual",
    {
      displayKey: "notEqualNoNulls",
      displayName: "Not Equals without Nulls",
      predicate: ([filterValue], cellValue) => {
        if (cellValue == null) return false;
        return cellValue.toLowerCase() !== filterValue.toLowerCase();
      },
    },
  ] as IFilterOptionDef[],
};

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div style="margin-bottom: 5px">
        <button v-on:click="printState()">Print State</button>
        <button v-on:click="saveState()">Save State</button>
        <button v-on:click="restoreState()">Restore State</button>
        <button v-on:click="resetState()">Reset State</button>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :getLocaleText="getLocaleText"
        :rowData="rowData"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "athlete",
        filterParams: containsFilterParams,
      },
      {
        field: "age",
        minWidth: 120,
        filter: "agNumberColumnFilter",
        filterParams: filterParams,
      },
      {
        field: "date",
        filter: "agDateColumnFilter",
        filterParams: equalsFilterParams,
      },
      {
        field: "country",
        filterParams: notEqualsFilterParams,
      },
      { field: "gold", filter: "agNumberColumnFilter" },
      { field: "silver", filter: "agNumberColumnFilter" },
      { field: "bronze", filter: "agNumberColumnFilter" },
      { field: "total", filter: false },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 150,
      filter: true,
    });
    const getLocaleText = ref<GetLocaleText>((params: GetLocaleTextParams) => {
      if (params.key === "notEqualNoNulls") {
        return "* Not Equals (No Nulls) *";
      }
      return params.defaultValue;
    });
    const rowData = ref<IOlympicData[]>(null);

    function printState() {
      const filterState = gridApi.value!.getFilterModel();
      console.log("filterState: ", filterState);
    }
    function saveState() {
      window.filterState = gridApi.value!.getFilterModel();
      console.log("filter state saved");
    }
    function restoreState() {
      gridApi.value!.setFilterModel(window.filterState);
      console.log("filter state restored");
    }
    function resetState() {
      gridApi.value!.setFilterModel(null);
      console.log("column state reset");
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

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

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

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      getLocaleText,
      rowData,
      onGridReady,
      printState,
      saveState,
      restoreState,
      resetState,
    };
  },
});

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

[Live example: Custom Filter Options](https://www.ag-grid.com/examples/filter-conditions/custom-filter-options/vue3)

## Customising Filter Placeholder Text

Filter placeholder text can be customised on a per column basis using `filterParams.filterPlaceholder` within the grid option `columnDefs`. The placeholder can be either a string or a function as shown in the snippet below:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    {
        field: 'age',
        filter: 'agNumberColumnFilter',
        filterParams: {
            filterPlaceholder: 'Age...'
        }
    },
    {
        field: 'total',
        filter: 'agNumberColumnFilter',
        filterParams: {
            filterPlaceholder: (params) => {
                const { filterOption, placeholder } = params;
                return `${filterOption} ${placeholder}`;
            }
        }
    }
];
```

When `filterPlaceholder` is a function, the parameters are made up of the following:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `filterOptionKey` | `ISimpleFilterModelType` |  |  | The filter option key |
| `filterOption` | `string` |  |  | The filter option name as localised text |
| `placeholder` | `string` |  |  | The default placeholder text |

The following example shows the various ways of specifying filter placeholders. Click on the filter menu for the different columns in the header row to see the following:

- `Athlete` column shows the default placeholder of `Filter...` with no configuration
- `Country` column shows the string `Country...` for all filter options
- `Sport` column shows the filter option key with the default placeholder eg, for the `Contains` filter option, it shows `contains - Filter...`.
- `Total` column shows the filter option name with the suffix `total` eg, for the `Equals` filter option, it shows `Equals total`.

#### Filter Placeholder Text

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  IFilterPlaceholderFunctionParams,
  INumberFilterParams,
  ITextFilterParams,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  TextFilterModule,
  NumberFilterModule,
]);

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,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "athlete",
      },
      {
        field: "country",
        filter: "agTextColumnFilter",
        filterParams: {
          filterPlaceholder: "Country...",
        } as ITextFilterParams,
      },
      {
        field: "sport",
        filter: "agTextColumnFilter",
        filterParams: {
          filterPlaceholder: (params: IFilterPlaceholderFunctionParams) => {
            const { filterOptionKey, placeholder } = params;
            return `${filterOptionKey} - ${placeholder}`;
          },
        } as ITextFilterParams,
      },
      {
        field: "total",
        filter: "agNumberColumnFilter",
        filterParams: {
          filterPlaceholder: (params: IFilterPlaceholderFunctionParams) => {
            const { filterOption } = params;
            return `${filterOption} total`;
          },
        } as INumberFilterParams,
      },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      filter: true,
    });
    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: Filter Placeholder Text](https://www.ag-grid.com/examples/filter-conditions/filter-placeholder-text/vue3)

> **Note**
>
> [Date Filters](https://www.ag-grid.com/vue-data-grid/filter-date/) use the native browser date input by default, which may not support placeholders. To use placeholders with Date Filters, you may need to use a [Custom Date Component](https://www.ag-grid.com/vue-data-grid/filter-date/#custom-selection-component).
