CxJS

Grouping

Grid supports grouping records by one or more fields with aggregation and custom footers.

<Grid
  controller={PageController}
  records={m.records}
  style="height: 500px"
  scrollable
  border
  grouping={[{ key: {}, showFooter: true }, "continent"]}
  columns={[
    {
      header: "Name",
      field: "fullName",
      aggregate: "count",
      footer: tpl(m.$group.fullName, "{0} people"),
    },
    {
      header: "Browser",
      field: "browser",
      aggregate: "distinct",
      aggregateAlias: "browsers",
      footer: tpl(m.$group.browsers, "{0} browsers"),
    },
    {
      header: "OS",
      field: "os",
      aggregate: "distinct",
      footer: tpl(m.$group.os, "{0} OS"),
    },
    {
      header: "Visits",
      field: "visits",
      align: "right",
      aggregate: "sum",
    },
  ]}
  recordAlias={m.$record}
/>
NameBrowserOSVisits
Asia
Frank WilsonEdgeWindows37
Grace LeeChromemacOS42
2 people2 browsers2 OS79
Europe
Carol WhiteChromeLinux28
David BrownSafarimacOS51
Eva GreenChromeWindows19
3 people2 browsers3 OS98
North America
Alice JohnsonChromeWindows45
Bob SmithFirefoxmacOS32
Henry TaylorSafarimacOS25
3 people3 browsers2 OS102
8 people4 browsers3 OS279

Records are grouped by continent with aggregate calculations shown in the footer.

Basic Grouping

Use the grouping property to group records by a field:

<Grid
  records={m.records}
  grouping="continent"
  columns={[
    { header: "Name", field: "fullName" },
    { header: "Continent", field: "continent" },
  ]}
/>

Multi-Level Grouping

Pass an array for multiple grouping levels. The first level with an empty key groups all records (useful for totals):

grouping={[
  { key: {}, showFooter: true },  // Total row
  "continent"                      // Group by continent
]}

Aggregation

Configure aggregates on columns to calculate values per group:

columns={[
  {
    header: "Name",
    field: "fullName",
    aggregate: "count",
    footer: tpl(m.$group.fullName, "{0} people"),
  },
  {
    header: "Visits",
    field: "visits",
    aggregate: "sum",
  },
]}

Aggregate Functions

FunctionDescription
countCount non-null values
sumSum numeric values
avgAverage of numeric values
minMinimum value
maxMaximum value
distinctCount unique values

Aggregate Alias

Use aggregateAlias to give the aggregate a custom name in $group:

{
  header: "Browser",
  field: "browser",
  aggregate: "distinct",
  aggregateAlias: "browsers",
  footer: tpl(m.$group.browsers, "{0} browsers"),
}

Group Captions

Use showCaption: true in the grouping configuration to display a caption row for each group. Define caption on columns to customize what appears in the caption row:

<Grid
  controller={PageController}
  records={m.records}
  style="height: 500px"
  scrollable
  fixedFooter
  grouping={[
    { key: {}, showFooter: true },
    { key: { continent: { bind: "$record.continent" } }, showCaption: true },
  ]}
  columns={[
    {
      header: "Name",
      field: "fullName",
      aggregate: "count",
      footer: tpl(m.$group.fullName, "{0} people"),
      caption: tpl(m.$group.continent, m.$group.fullName, "{0} ({1} people)"),
    },
    {
      header: "Browser",
      field: "browser",
      aggregate: "distinct",
      aggregateAlias: "browsers",
      footer: tpl(m.$group.browsers, "{0} browsers"),
      caption: tpl(m.$group.browsers, "{0} browsers"),
    },
    {
      header: "Visits",
      field: "visits",
      align: "right",
      aggregate: "sum",
      caption: m.$group.visits,
    },
  ]}
  recordAlias={m.$record}
/>
grouping={[{ key: { continent: { bind: "$record.continent" } }, showCaption: true }]}
columns={[
  {
    header: "Name",
    field: "fullName",
    aggregate: "count",
    caption: tpl(m.$group.continent, m.$group.fullName, "{0} ({1} people)"),
  },
  // ...
]}

Group Data

The $group object contains:

PropertyDescription
$nameGroup name/label
$levelNesting level (0 for deepest)
$recordsRecords in the group
$keySerialized group key
[field]Aggregate value for each field

Grouping Configuration

PropertyTypeDescription
keyobjectFields to group by. Empty object groups all records.
showHeaderbooleanShow group header row.
showFooterbooleanShow group footer row.
showCaptionbooleanShow group caption.
captionStringPropCaption template.
textStringPropGroup name template.

See also: Dynamic Grouping, GroupAdapter