Configure which columns appear in the Advanced Filter including how they are named and which filter options each offers based on its Cell Data Type or filter used.
Columns Copy Link
Every column with filtering enabled appears in the Advanced Filter under its header name, with the exceptions and overrides described below.
Including Hidden Columns Copy Link
By default, hidden columns do not appear in the Advanced Filter. To make hidden columns appear, set the grid option includeHiddenColumnsInAdvancedFilter = true.
Hidden columns are excluded from the Advanced Filter by default.
To include hidden columns, set to true. |
Column Names Copy Link
All column names that are enabled for filtering must be unique for the Advanced Filter to work correctly.
If columns have the same name by default (e.g. where they appear within different column groups), the name by which they appear in the Advanced Filter can be configured using a Header Value Getter and checking for location === 'advancedFilter'.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'gold',
headerValueGetter: params => params.location === 'advancedFilter' ? 'Gold 1' : 'Gold',
},
{
field: 'gold',
headerValueGetter: params => params.location === 'advancedFilter' ? 'Gold 2' : 'Gold',
},
];The following example demonstrates the column properties involved:
- The Age column is not available in the filter as
filter = false. - The Sport column is not available in the filter by default as hidden columns are excluded.
- After clicking Include Hidden Columns, the Sport column is available in the filter.
- The Group column does not appear in the filter, but its underlying column - Country - always appears.
- The Athlete column has Filter Params defined, so that it only shows the
containsoption and is case sensitive. - The Gold, Silver and Bronze columns in the Medals (-) column group have a
headerValueGetterdefined and use thelocationproperty to have a different name in the filter (with a(-)suffix).
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
HeaderValueGetterParams,
ModuleRegistry,
NumberFilterModule,
TextFilterModule,
ValueGetterParams,
enableDevValidations,
} from "ag-grid-community";
import {
AdvancedFilterModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
} from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
TextFilterModule,
NumberFilterModule,
AdvancedFilterModule,
ClientSideRowModelModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
]);
import { IOlympicData } from "./interfaces";
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular],
template: `<div class="example-wrapper">
<div class="example-header">
<button
id="includeHiddenColumns"
(click)="onIncludeHiddenColumnsToggled()"
>
Include Hidden Columns
</button>
</div>
<ag-grid-angular
style="width: 100%; height: 100%;"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[groupDefaultExpanded]="groupDefaultExpanded"
[enableAdvancedFilter]="true"
[rowData]="rowData"
(gridReady)="onGridReady($event)"
/>
</div> `,
})
export class AppComponent {
private gridApi!: GridApi<IOlympicData>;
columnDefs: (ColDef | ColGroupDef)[] = [
{
field: "athlete",
filterParams: {
caseSensitive: true,
filterOptions: ["contains"],
},
},
{ field: "country", rowGroup: true, hide: true },
{ field: "sport", hide: true },
{ field: "age", minWidth: 100, filter: false },
{
headerName: "Medals (+)",
children: [
{ field: "gold", minWidth: 100 },
{ field: "silver", minWidth: 100 },
{ field: "bronze", minWidth: 100 },
],
},
{
headerName: "Medals (-)",
children: [
{
field: "gold",
headerValueGetter: (
params: HeaderValueGetterParams<IOlympicData, number>,
) => (params.location === "advancedFilter" ? "Gold (-)" : "Gold"),
valueGetter: valueGetter,
cellDataType: "number",
minWidth: 100,
},
{
field: "silver",
headerValueGetter: (
params: HeaderValueGetterParams<IOlympicData, number>,
) => (params.location === "advancedFilter" ? "Silver (-)" : "Silver"),
valueGetter: valueGetter,
cellDataType: "number",
minWidth: 100,
},
{
field: "bronze",
headerValueGetter: (
params: HeaderValueGetterParams<IOlympicData, number>,
) => (params.location === "advancedFilter" ? "Bronze (-)" : "Bronze"),
valueGetter: valueGetter,
cellDataType: "number",
minWidth: 100,
},
],
},
];
defaultColDef: ColDef = {
flex: 1,
minWidth: 180,
filter: true,
};
groupDefaultExpanded = 1;
rowData!: IOlympicData[];
constructor(private http: HttpClient) {}
onIncludeHiddenColumnsToggled() {
includeHiddenColumns = !includeHiddenColumns;
this.gridApi.setGridOption(
"includeHiddenColumnsInAdvancedFilter",
includeHiddenColumns,
);
document.querySelector("#includeHiddenColumns")!.textContent =
`${includeHiddenColumns ? "Exclude" : "Include"} Hidden Columns`;
}
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));
}
}
function valueGetter(params: ValueGetterParams<IOlympicData, number>) {
return params.data ? params.data[params.colDef.field!] * -1 : null;
}
let includeHiddenColumns = false;
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
.example-header {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 13px;
margin-bottom: 5px;
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
export interface IOlympicData {
athlete: string,
age: number,
country: string,
year: number,
date: string,
sport: string,
gold: number,
silver: number,
bronze: number,
total: number
} Cell Data Type Handling Copy Link
All of the Cell Data Types are supported in the Advanced Filter. The behaviour of each is described below.
- Text - The value in the input is compared against the cell value before any Value Formatters are applied (similar to the Text Filter). To change the value being compared against, a Filter Value Getter can be used.
- Number - The value in the input is compared against the cell value (like in the Number Filter). A column pairing a
numberParserwith anumberFormatterhas its operands read and displayed in its own format, so custom formats such as thousands separators are accepted. Either one on its own leaves the operand as a plain number: the grid only reads a format it can also write. A format containing a space is quoted in the expression, so[Value] = "1 234 567"is read as one operand. A format the parser does not read back as the same number is shown as a plain number instead. - BigInt - The value in the input is parsed as a
bigint(decimal integer syntax only, optional trailingn) and compared against the cell value (like in the BigInt Filter). A column'sbigintParseris used here too, so custom formats such as hexadecimal are also accepted, and itsbigintFormatteris used to display a stored operand in the filter expression and the Filter Builder. - Boolean - No values are displayed for booleans as the filter option is used instead.
- Date and Date Time - The value in the input is converted to a
Datevia the Value Parser. - Date String and Date Time String - The value in the input is converted to a
Dateusing the Value Parser and the Date Parser. This is compared against the cell values, which are also converted using the Date Parser. - Object - The value in the input is compared against the values returned by the Filter Value Getter if one is provided. Otherwise, the cell values are converted using the Value Formatter.
Filter Parameters Copy Link
Certain properties can be set by using colDef.filterParams.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'athlete',
filterParams: {
// perform case sensitive search
caseSensitive: true,
// limit options to `contains` only
filterOptions: ['contains'],
}
}
];For all Cell Data Types, the available filter options can be set via filterOptions.
The available options are as follows:
| Option Name | Option Key | Cell Data Type |
|---|---|---|
| contains | contains | text, object |
| does not contain | notContains | text, object |
| equals | equals | text, object |
| = | equals | number, bigint, date, dateString, dateTime, dateTimeString |
| does not equal | notEqual | text, object |
| != | notEqual | number, bigint, date, dateString, dateTime, dateTimeString |
| begins with | startsWith | text, object |
| ends with | endsWith | text, object |
| is blank | blank | text, number, bigint, boolean, date, dateString, dateTime, dateTimeString, object |
| is not blank | notBlank | text, number, bigint, boolean, date, dateString, dateTime, dateTimeString, object |
| > | greaterThan | number, bigint, date, dateString, dateTime, dateTimeString |
| >= | greaterThanOrEqual | number, bigint, date, dateString, dateTime, dateTimeString |
| < | lessThan | number, bigint, date, dateString, dateTime, dateTimeString |
| <= | lessThanOrEqual | number, bigint, date, dateString, dateTime, dateTimeString |
| is between | inRange | number, bigint, date, dateString, dateTime, dateTimeString |
| is true | true | boolean |
| is false | false | boolean |
| is any of | isAnyOf | column enables a Set Filter* |
| is none of | isNoneOf | column enables a Set Filter* |
* Offered where the column enables a Set Filter. Other columns can opt in — see Enabling and Disabling the Set Options.
is between takes two values, written as a comma-separated pair: [Age] is between (21, 38). The range is exclusive of both ends unless inRangeInclusive = true is set, exactly as it is in the Number Filter and the Date Filter.
The two values are validated against each other, as the column filters validate the pair of inputs they show for a range: the first must be below the second, or equal to it where inRangeInclusive = true is set. A range whose values are in the wrong order is invalid and is not applied.
For text and object Cell Data Types, caseSensitive = true can be set to enable case sensitivity.
Text is compared the way the column's Text Filter compares it, so the same condition matches the same rows in both:
textFormatterformats the cell value and the operand before they are compared, to substitute accented characters for example. It takes the place of the lower-casing the grid does by default, socaseSensitiveno longer has any effect and a formatter that should ignore case has to lower-case the text itself.textMatcherdecides the comparison itself. It is called forcontains,does not contain,equals,does not equal,begins withandends with, but not foris blankoris not blank.trimInputremoves leading and trailing whitespace from the operand. An operand of only whitespace is left as it was entered.
textFormatter and textMatcher are both told which filter is calling them: params.source is 'advancedFilter' here and 'columnFilter' when the column's own filter is comparing, so one callback can behave differently for each.
All three are read from the column's Text Filter. On a Multi Filter column they come from its Text Filter child, as they do for the Multi Filter itself. On a Set Filter column, filterParams.textFormatter formats the list of values shown in the filter instead, and is not used to compare text here.
trimInput applies wherever the operand is set, including a model set through setAdvancedFilterModel, so getAdvancedFilterModel returns the trimmed value, and the Filter Builder shows the trimmed operand. The column filter trims the model it applies in the same way.
For number, date, dateString, dateTime and dateTimeString Cell Data Types, the following properties can be set to include blank values for the relevant options:
includeBlanksInEquals = trueincludeBlanksInNotEqual = trueincludeBlanksInLessThan = trueincludeBlanksInGreaterThan = trueincludeBlanksInRange = true
For date, dateString, dateTime and dateTimeString Cell Data Types, the Date Filter's comparator also decides the column's comparisons here, including the relative date options below. This is how a column whose cells carry a time is compared by date alone. The comparator is given the cell value as the column holds it, and isValidDate gates every comparison alongside it:
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'date',
cellDataType: 'date',
filter: 'agDateColumnFilter',
filterParams: {
// ignore the time the cell carries, so `[Date] = 24/08/2008` matches the whole day
comparator: (filterLocalDateAtMidnight, cellValue) => {
const cellDate = new Date(cellValue);
cellDate.setHours(0, 0, 0, 0);
return cellDate.getTime() - filterLocalDateAtMidnight.getTime();
},
},
},
];It applies equally where the Date Filter is a child of a Multi Filter. A custom filter component's filterParams are its own. A Set Filter column's comparator orders its values instead, so it is not read as a date comparison there, but an isValidDate set on such a column still gates the comparisons above.
These settings only apply when using the Client-Side Row Model. You need to implement support for these in your server-side filtering logic when using the Server-Side Row Model.
Relative Date Options Copy Link
date, dateString, dateTime and dateTimeString columns also support the Date Filter's built-in relative date options, under names of their own. As in the Date Filter, none of them is offered by default: a column opts in by naming them in filterOptions.
<ag-grid-angular
[columnDefs]="columnDefs"
/* other grid options ... */ />
this.columnDefs = [
{
field: 'date',
cellDataType: 'date',
filterParams: {
filterOptions: ['equals', 'thisYear', 'lastYear'],
},
},
];The Advanced Filter names each of them as a phrase, where the Date Filter names it as a label:
| Option Name | Option Key |
|---|---|
| is yesterday | yesterday |
| is today | today |
| is tomorrow | tomorrow |
| is in last 7 days | last7Days |
| is in last week | lastWeek |
| is in this week | thisWeek |
| is in next week | nextWeek |
| is in last 30 days | last30Days |
| is in last month | lastMonth |
| is in this month | thisMonth |
| is in next month | nextMonth |
| is in last 90 days | last90Days |
| is in last quarter | lastQuarter |
| is in this quarter | thisQuarter |
| is in next quarter | nextQuarter |
| is in last year | lastYear |
| is in this year | thisYear |
| is in year to date | yearToDate |
| is in next year | nextYear |
| is in last 6 months | last6Months |
| is in last 12 months | last12Months |
| is in last 24 months | last24Months |
They take no value, so an expression is the column and the option alone — [Date] is in last year — and the filter model holds only the option key:
const advancedFilterModel = { filterType: 'date', colId: 'date', type: 'lastYear' };Relative date options do not take a value, so they cannot be used as bounds for is between. To cover consecutive relative dates, combine the options with OR, for example: [Date] is yesterday OR [Date] is today OR [Date] is tomorrow.
Relative date options remain relative to the current date rather than being converted to fixed dates. This means a saved filter model retains the same relative meaning whenever it is restored. With the Server-Side Row Model, the option key is sent to the server without date values, consistent with the Date Filter — see Preset Date Range Filters.
The following example demonstrates the built-in range and relative date options:
- The Age column offers
is between, which it and every other Number column do by default. - The Date column narrows its options to
=,is between,is in last 7 days,is in last 30 days,is in this year,is in last yearandis in last 24 months.
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
DateFilterModule,
GridApi,
GridOptions,
GridReadyEvent,
IDateFilterParams,
ModuleRegistry,
NumberFilterModule,
TextFilterModule,
enableDevValidations,
} from "ag-grid-community";
import {
AdvancedFilterModule,
ColumnMenuModule,
ContextMenuModule,
} from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
TextFilterModule,
NumberFilterModule,
DateFilterModule,
AdvancedFilterModule,
ClientSideRowModelModule,
ColumnMenuModule,
ContextMenuModule,
]);
interface IRow {
athlete: string;
age: number;
sport: string;
date: string;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular],
template: `<ag-grid-angular
style="width: 100%; height: 100%;"
[rowData]="rowData"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[enableAdvancedFilter]="true"
/> `,
})
export class AppComponent {
rowData: IRow[] | null = [
{ athlete: "Michael Phelps", age: 23, sport: "Swimming", date: daysAgo(0) },
{
athlete: "Natalie Coughlin",
age: 25,
sport: "Swimming",
date: daysAgo(3),
},
{
athlete: "Aleksey Nemov",
age: 24,
sport: "Gymnastics",
date: daysAgo(20),
},
{ athlete: "Alicia Coutts", age: 24, sport: "Swimming", date: daysAgo(75) },
{
athlete: "Missy Franklin",
age: 17,
sport: "Swimming",
date: daysAgo(200),
},
{ athlete: "Ryan Lochte", age: 27, sport: "Swimming", date: daysAgo(400) },
{
athlete: "Allison Schmitt",
age: 22,
sport: "Swimming",
date: daysAgo(600),
},
{ athlete: "Ian Thorpe", age: 17, sport: "Swimming", date: daysAgo(900) },
{ athlete: "Dara Torres", age: 33, sport: "Swimming", date: daysAgo(1500) },
];
columnDefs: ColDef[] = [
{ field: "athlete", filter: "agTextColumnFilter" },
{ field: "age", minWidth: 120, filter: "agNumberColumnFilter" },
{ field: "sport", filter: "agTextColumnFilter" },
{
field: "date",
filter: "agDateColumnFilter",
filterParams: dateFilterParams,
},
];
defaultColDef: ColDef = {
flex: 1,
minWidth: 150,
};
}
/** The `yyyy-mm-dd` of a Date (String) column, so the data means something relative to whenever it is read. */
function daysAgo(days: number): string {
const date = new Date();
date.setDate(date.getDate() - days);
const month = String(date.getMonth() + 1).padStart(2, "0");
return `${date.getFullYear()}-${month}-${String(date.getDate()).padStart(2, "0")}`;
}
const dateFilterParams: IDateFilterParams = {
filterOptions: [
"equals",
"inRange",
"last7Days",
"last30Days",
"thisYear",
"lastYear",
"last24Months",
],
};
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
Set Filters Copy Link
A column with a Set Filter gains the is any of and is none of options, in addition to everything its Cell Data Type already offers. Both take a list of values:
[Country] is any of ["Australia", "Italy"]
[Country] is none of ["Australia", "Italy"]In the following example, Country uses a Set Filter with a cellRenderer that adds flags, Athlete formats its values through filterParams.valueFormatter, and Date is a Tree List. Sport and Gold use Text and Number Filters, so they do not offer the set options:
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { AgGridAngular } from "ag-grid-angular";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ISetFilterParams,
ModuleRegistry,
NumberFilterModule,
TextFilterModule,
ValueFormatterParams,
enableDevValidations,
} from "ag-grid-community";
import {
AdvancedFilterModule,
ColumnMenuModule,
ContextMenuModule,
SetFilterModule,
} from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
TextFilterModule,
NumberFilterModule,
SetFilterModule,
AdvancedFilterModule,
ClientSideRowModelModule,
ColumnMenuModule,
ContextMenuModule,
]);
import { CountryCellRenderer } from "./country-cell-renderer.component";
interface IOlympicDataTypes extends IOlympicData {
dateObject: Date;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular, CountryCellRenderer],
template: `<ag-grid-angular
style="width: 100%; height: 100%;"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[enableAdvancedFilter]="true"
[rowData]="rowData"
(gridReady)="onGridReady($event)"
/> `,
})
export class AppComponent {
columnDefs: ColDef[] = [
{
field: "country",
cellRenderer: CountryCellRenderer,
filter: "agSetColumnFilter",
filterParams: {
cellRenderer: CountryCellRenderer,
} as ISetFilterParams,
},
{
field: "athlete",
filter: "agSetColumnFilter",
filterParams: {
valueFormatter: ({
value,
}: ValueFormatterParams<IOlympicDataTypes, string>) =>
value == null ? "(Blanks)" : value.toUpperCase(),
},
},
{
field: "dateObject",
headerName: "Date",
filter: "agSetColumnFilter",
filterParams: {
treeList: true,
},
},
{ field: "sport", filter: "agTextColumnFilter" },
{ field: "gold", filter: "agNumberColumnFilter" },
];
defaultColDef: ColDef = {
flex: 1,
minWidth: 150,
};
rowData!: IOlympicDataTypes[];
constructor(private http: HttpClient) {}
onGridReady(params: GridReadyEvent<IOlympicDataTypes>) {
this.http
.get<
IOlympicDataTypes[]
>("https://www.ag-grid.com/example-assets/olympic-winners.json")
.subscribe(
(data) =>
(this.rowData = data.map((row) => {
// The Tree List groups a date by year, month and day, which needs a real Date.
const [day, month, year] = row.date.split("/");
return {
...row,
dateObject: new Date(
Number(year),
Number(month) - 1,
Number(day),
),
};
})),
);
}
}
export const COUNTRY_CODES: Record<string, string> = {
Afghanistan: 'af',
Algeria: 'dz',
Argentina: 'ar',
Armenia: 'am',
Australia: 'au',
Austria: 'at',
Azerbaijan: 'az',
Bahamas: 'bs',
Bahrain: 'bh',
Barbados: 'bb',
Belarus: 'by',
Belgium: 'be',
Botswana: 'bw',
Brazil: 'br',
Bulgaria: 'bg',
Cameroon: 'cm',
Canada: 'ca',
Chile: 'cl',
China: 'cn',
'Chinese Taipei': 'tw',
Colombia: 'co',
'Costa Rica': 'cr',
Croatia: 'hr',
Cuba: 'cu',
Cyprus: 'cy',
'Czech Republic': 'cz',
Denmark: 'dk',
'Dominican Republic': 'do',
Ecuador: 'ec',
Egypt: 'eg',
Eritrea: 'er',
Estonia: 'ee',
Ethiopia: 'et',
Finland: 'fi',
France: 'fr',
Gabon: 'ga',
Georgia: 'ge',
Germany: 'de',
'Great Britain': 'gb',
Greece: 'gr',
Grenada: 'gd',
Guatemala: 'gt',
'Hong Kong': 'hk',
Hungary: 'hu',
Iceland: 'is',
India: 'in',
Indonesia: 'id',
Iran: 'ir',
Ireland: 'ie',
Israel: 'il',
Italy: 'it',
Jamaica: 'jm',
Japan: 'jp',
Kazakhstan: 'kz',
Kenya: 'ke',
Kuwait: 'kw',
Kyrgyzstan: 'kg',
Latvia: 'lv',
Lithuania: 'lt',
Macedonia: 'mk',
Malaysia: 'my',
Mauritius: 'mu',
Mexico: 'mx',
Moldova: 'md',
Mongolia: 'mn',
Montenegro: 'me',
Morocco: 'ma',
Mozambique: 'mz',
Netherlands: 'nl',
'New Zealand': 'nz',
Nigeria: 'ng',
'North Korea': 'kp',
Norway: 'no',
Panama: 'pa',
Paraguay: 'py',
Poland: 'pl',
Portugal: 'pt',
'Puerto Rico': 'pr',
Qatar: 'qa',
Romania: 'ro',
Russia: 'ru',
'Saudi Arabia': 'sa',
Serbia: 'rs',
'Serbia and Montenegro': 'rs',
Singapore: 'sg',
Slovakia: 'sk',
Slovenia: 'si',
'South Africa': 'za',
'South Korea': 'kr',
Spain: 'es',
'Sri Lanka': 'lk',
Sudan: 'sd',
Sweden: 'se',
Switzerland: 'ch',
Syria: 'sy',
Tajikistan: 'tj',
Thailand: 'th',
Togo: 'tg',
'Trinidad and Tobago': 'tt',
Tunisia: 'tn',
Turkey: 'tr',
Uganda: 'ug',
Ukraine: 'ua',
'United Arab Emirates': 'ae',
'United States': 'us',
Uruguay: 'uy',
Uzbekistan: 'uz',
Venezuela: 've',
Vietnam: 'vn',
Zimbabwe: 'zw',
};
import { Component, signal } from '@angular/core';
import type { ICellRendererAngularComp } from 'ag-grid-angular';
import type { ICellRendererParams } from 'ag-grid-community';
import { COUNTRY_CODES } from './countryCodes';
@Component({
standalone: true,
template: `<div>
@if (flagCode()) {
<img
class="flag"
border="0"
width="15"
height="10"
src="https://flags.fmcdn.net/data/flags/mini/{{ flagCode() }}.png"
/>
}
{{ textValue() }}
</div>`,
})
export class CountryCellRenderer implements ICellRendererAngularComp {
textValue = signal<string | undefined>(undefined);
flagCode = signal<string | undefined>(undefined);
agInit(params: ICellRendererParams): void {
this.textValue.set(params.value ?? '');
this.flagCode.set(params.value ? COUNTRY_CODES[params.value] : undefined);
}
refresh() {
return false;
}
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
Writing the Value List Copy Link
Typing inside the list suggests the column's Set Filter values, with no opening quote required. Selecting one writes it quoted and ready for the next; values already in the list are not suggested again, and deleting one returns it to the list. In the Advanced Filter Builder the value pill opens the column's own Set Filter.
The square brackets are part of the grammar: a list written without them cannot be applied. Quotes, on the other hand, are only needed where a value would otherwise be read as something else. A value containing , or ], or beginning with a quote, is one such: typed bare, those characters end the value, close the list, or open a quoted one. Choose such a value from the suggestions, which writes it quoted, or open a quote before typing it, after which they are all ordinary and the suggestions still narrow as you type. A value written without quotes may contain spaces, and is trimmed:
[Country] is any of [New Zealand, Italy]Blank values are offered as (Blanks), the name the Set Filter gives them. The model stores null for it.
[Country] is any of ["(Blanks)", Italy] Reusing the Set Filter Configuration Copy Link
The column's Set Filter configuration is reused, so an expression matches the same rows as the equivalent Set Filter selection, and its filterParams (such as a cellRenderer, valueFormatter or treeList) apply to the suggested values too. A Multi Filter column uses the filterParams of its Set Filter child.
Values are displayed and matched as the Set Filter displays them. With filterParams.valueFormatter, the formatted text is shown and typed, while the filter model still stores the underlying keys. To store formatted values in the model instead, use colDef.filterValueGetter. Where two keys format to the same text, the first keeps that text and the rest are written as their key.
A filterParams.values callback may be called more than once for the same column, as the Advanced Filter resolves values separately from the column filter. Matching runs under the Client-Side Row Model only; with the Server-Side Row Model the option is sent to the server in the filter model.
Tree List Values Copy Link
With treeList enabled, a value is the whole path to a leaf, its segments separated by >. The › the suggestions are drawn with is read as a separator too:
[Location] is any of ["Europe > Italy"]The suggestions are every path in the column as one flat list, parent segments de-emphasised: typing searches every path, and choosing one writes it in full.
A path can also be written a segment at a time, ["Europe" > "Italy"], which is what a segment containing a separator of its own needs. Both spellings name the same path, and the suggestions write whichever one reads back.
Data Updates Copy Link
Advanced Filter expressions are the source of truth, so changes to the row data never rewrite them. An expression naming a value the data no longer holds is reported against that value and cannot be applied, while an expression already applied keeps its model and keeps filtering.
Enabling and Disabling the Set Options Copy Link
By default, is any of and is none of are offered only on columns using a Set Filter. Setting filterOptions overrides this, as the list then defines exactly which options the column offers:
- Include
isAnyOforisNoneOfin the list to offer them on a column with any other filter type. - Leave them out of the list to remove them from a Set Filter column.
const gridOptions = {
columnDefs: [
// A Set Filter column offers the Set Options as well as those of its Cell Data Type.
{ field: 'country', filter: 'agSetColumnFilter' },
// A Number Filter includes Set Options via filterOptions.
{
field: 'age',
filter: 'agNumberColumnFilter',
filterParams: {
filterOptions: ['greaterThan', 'lessThan', 'isAnyOf', 'isNoneOf'],
},
},
// A Set Filter column that does not include the Set Options, just its filterOptions
{
field: 'sport',
filter: 'agSetColumnFilter',
filterParams: {
filterOptions: ['contains', 'equals'],
},
},
],
};A column with a filter other than the Set Filter keeps that filter and its filterParams unchanged. Its values are offered unconfigured, apart from colDef.keyCreator and colDef.filterValueGetter.
The SetFilterModule must be registered. Without it, naming either option in filterOptions reports a missing module and the column falls back to its default options.
Row Grouping, Aggregation and Pivoting Copy Link
When Row Grouping, group columns will not appear in the Advanced Filter. The underlying columns will always appear, even if hidden.
The Advanced Filter will only work on leaf-level rows when using Aggregation. The groupAggFiltering property will be ignored.
When Pivoting, Pivot Result Columns will not appear in the Advanced Filter. However, primary columns (including underlying group and pivot columns) will be shown in the Advanced Filter.