Filtering can be configured to impact aggregate values in the grid.
Ignore Filters when Aggregating Copy Link
When using Filters and Aggregations together, the aggregated values reflect only the rows which have passed the filter. This can be changed to instead ignore applied filters by using the suppressAggFilteredOnly grid option.
"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
AutoGroupColumnDef,
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
NumberFilterModule,
TextFilterModule,
UseGroupTotalRow,
enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
const modules = [
NumberFilterModule,
ClientSideRowModelModule,
RowGroupingModule,
TextFilterModule,
];
const GridExample = () => {
const gridRef = useRef<AgGridReact>(null);
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "country", rowGroup: true, hide: true },
{ field: "year", rowGroup: true, hide: true },
{ field: "sport", filter: "agTextColumnFilter", floatingFilter: true },
{ field: "gold", aggFunc: "sum" },
{ field: "silver", aggFunc: "sum" },
{ field: "bronze", aggFunc: "sum" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
minWidth: 150,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
minWidth: 300,
};
}, []);
const onGridReady = useCallback((params: GridReadyEvent) => {
params.api.setFilterModel({
sport: {
type: "contains",
filter: "Swimming",
},
});
}, []);
const { data, loading } = useFetchJson<any>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
const toggleProperty = useCallback(() => {
const enable = document.querySelector<HTMLInputElement>(
"#suppressAggFilteredOnly",
)!.checked;
gridRef.current!.api.setGridOption("suppressAggFilteredOnly", enable);
}, []);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div className="example-wrapper">
<div className="example-header">
<label>
<span>suppressAggFilteredOnly:</span>
<input
id="suppressAggFilteredOnly"
type="checkbox"
onChange={toggleProperty}
/>
</label>
</div>
<div style={gridStyle}>
<AgGridReact
ref={gridRef}
rowData={data}
loading={loading}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
groupTotalRow={"bottom"}
onGridReady={onGridReady}
/>
</div>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.example-header {
margin-bottom: 10px;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
// StrictMode runs this effect twice: drop the superseded run's response rather than applying both.
let cancelled = false;
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
if (cancelled) {
return;
}
setData(data);
setLoading(false);
};
fetchData();
return () => {
cancelled = true;
};
}, [url, limit]);
return { data, loading };
}; The example above demonstrates the impact of the suppressAggFilteredOnly grid option. This can be enabled as shown:
const suppressAggFilteredOnly = true;
<AgGridReact suppressAggFilteredOnly={suppressAggFilteredOnly} /> Filtering for Aggregated Values Copy Link
The grid only applies filters to leaf level rows, this can be toggled to instead also apply filtering to group rows by enabling the groupAggFiltering grid option, allowing filters to also apply against the aggregated values.
"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
AutoGroupColumnDef,
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
IsRowFilterable,
ModuleRegistry,
NumberFilterModule,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
SetFilterModule,
} from "ag-grid-enterprise";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
const modules = [
ClientSideRowModelModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
SetFilterModule,
NumberFilterModule,
];
const GridExample = () => {
const gridRef = useRef<AgGridReact>(null);
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "country", rowGroup: true, hide: true },
{ field: "year" },
{ field: "total", aggFunc: "sum", filter: "agNumberColumnFilter" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
floatingFilter: true,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
field: "athlete",
};
}, []);
const onGridReady = useCallback((params: GridReadyEvent) => {
document.querySelector<HTMLInputElement>("#groupAggFiltering")!.checked =
true;
params.api.setFilterModel({
total: {
type: "contains",
filter: "192",
},
});
}, []);
const { data, loading } = useFetchJson<any>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
const toggleProperty = useCallback(() => {
const enable =
document.querySelector<HTMLInputElement>("#groupAggFiltering")!.checked;
gridRef.current!.api.setGridOption("groupAggFiltering", enable);
}, []);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div className="example-wrapper">
<div className="example-header">
<label>
<span>groupAggFiltering:</span>
<input
id="groupAggFiltering"
type="checkbox"
onChange={toggleProperty}
/>
</label>
</div>
<div style={gridStyle}>
<AgGridReact
ref={gridRef}
rowData={data}
loading={loading}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
groupDefaultExpanded={-1}
groupAggFiltering={true}
onGridReady={onGridReady}
/>
</div>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
.example-header {
margin-bottom: 10px;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
// StrictMode runs this effect twice: drop the superseded run's response rather than applying both.
let cancelled = false;
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
if (cancelled) {
return;
}
setData(data);
setLoading(false);
};
fetchData();
return () => {
cancelled = true;
};
}, [url, limit]);
return { data, loading };
}; Take note of the following while using groupAggFiltering:
- When a group row passes a filter, it also includes all of its descendent rows in the filtered results.
- The
suppressAggFilteredOnlygrid option will be implicitly enabled. - Set Filters will only work with leaf rows.
The following configuration demonstrates how to enable group aggregation filtering:
const groupAggFiltering = true;
<AgGridReact groupAggFiltering={groupAggFiltering} /> Configure by Callback Copy Link
When filtering for aggregated values the filter applies to all group rows by default. This can be configured more granularly by instead providing the groupAggFiltering grid option with a callback function.
The example below demonstrates a grid configured to apply filters only to aggregated values, and not the leaf rows:
"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
AutoGroupColumnDef,
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
IsRowFilterable,
ModuleRegistry,
NumberFilterModule,
TextFilterModule,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
} from "ag-grid-enterprise";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
const modules = [
TextFilterModule,
ClientSideRowModelModule,
ColumnMenuModule,
ContextMenuModule,
RowGroupingModule,
NumberFilterModule,
];
const GridExample = () => {
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "country", rowGroup: true, hide: true },
{ field: "year" },
{ field: "total", aggFunc: "sum", filter: "agNumberColumnFilter" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
flex: 1,
floatingFilter: true,
};
}, []);
const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
return {
field: "athlete",
};
}, []);
const groupAggFiltering = useMemo<boolean | IsRowFilterable>(() => {
return (params) => !!params.node.group;
}, []);
const { data, loading } = useFetchJson<any>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div style={gridStyle}>
<AgGridReact
rowData={data}
loading={loading}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
autoGroupColumnDef={autoGroupColumnDef}
groupDefaultExpanded={-1}
groupAggFiltering={groupAggFiltering}
/>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
// StrictMode runs this effect twice: drop the superseded run's response rather than applying both.
let cancelled = false;
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
if (cancelled) {
return;
}
setData(data);
setLoading(false);
};
fetchData();
return () => {
cancelled = true;
};
}, [url, limit]);
return { data, loading };
}; The configuration below demonstrates how to only apply test filters against group rows, and not leaf rows:
const groupAggFiltering = (params) => !!params.node.group;
<AgGridReact groupAggFiltering={groupAggFiltering} />