Dynamic Grouping
Grid supports dynamic grouping where users can select which fields to group by at runtime.
<div controller={PageController}>
<div class="mb-4 flex items-center gap-2">
<span>Group by:</span>
<LookupField
records={m.grouping}
options={m.groupableFields}
multiple
style="width: 300px"
/>
</div>
<Grid
records={m.records}
style="height: 500px"
scrollable
groupingParams={m.grouping}
fixedFooter
onGetGrouping={(groupingParams: GroupOption[]) => [
{ key: {}, showFooter: true },
...(groupingParams || []).map((x) => x.id),
]}
columns={[
{
header: "Name",
field: "fullName",
aggregate: "count",
footer: tpl(m.$group.fullName, "{0} people"),
},
{
header: "Continent",
field: "continent",
aggregate: "distinct",
aggregateAlias: "continents",
footer: tpl(m.$group.continents, "{0} continents"),
},
{
header: "Browser",
field: "browser",
aggregate: "distinct",
aggregateAlias: "browsers",
footer: tpl(m.$group.browsers, "{0} browsers"),
},
{
header: "Visits",
field: "visits",
align: "right",
aggregate: "sum",
},
]}
recordAlias={m.$record}
/>
</div> Group by:
Use the lookup field to select grouping fields. The grid updates automatically.
Using groupingParams
Bind grouping parameters to the store and use onGetGrouping to convert them to a grouping configuration:
<Grid
records={m.records}
scrollable
fixedFooter
groupingParams={m.grouping}
onGetGrouping={(groupingParams) => [
{ key: {}, showFooter: true },
...(groupingParams || []).map((x) => x.id),
]}
columns={[...]}
/>
Use fixedFooter to keep the totals row visible at the bottom of the grid while scrolling.
The first element with an empty key creates a total row that aggregates all records.
Configuration
| Property | Type | Description |
|---|---|---|
groupingParams | StructuredProp | Binding for grouping parameters. Changes trigger onGetGrouping. |
onGetGrouping | function | Callback that returns grouping configuration from params. |
See also: Grouping, GroupAdapter