Lattice Grid Buy a licence

demo D65

Group footers

A closing total per group

groupFooter: true

Building…
Loading a live grid…

The configuration

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.js"></script>

<div id="grid" style="height: 540px"></div>

<script>
  const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
    rowKey: 'id',
    /*
     * A closing row per group, carrying the same totals as the group's own
     * heading. It is a real display row: with ten accounts the grid holds
     * 10,010 rows instead of 10,000, and the footer's cost matches the
     * account's own sum to the penny.
     *
     * Two things about it in 1.4.0 are worth knowing before you turn it on.
     * The footer row carries no class of its own, so a theme cannot style it
     * apart from the group heading it repeats, and its leaf count renders as
     * (0) rather than the number of rows it is summing.
     */
    groupFooter: true,
    grandTotalRow: 'bottom',
    toolPanel: {
      side: 'left',
      panels: ['columns', 'filters', 'views', 'quick'],
      actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
      exportName: 'lattice-demo',
    },
    columns: [
      { field: 'account', title: 'Account', filter: { type: 'set' }, group: { enabled: true, index: 0 } },
      { field: 'service', title: 'Service', filter: { type: 'set' } },
      { field: 'resource', title: 'Resource', layout: { flex: 1, min: 200, max: 320 } },
      { field: 'environment', title: 'Env', filter: { type: 'set' },
        cell: { decoration: 'pill', variant: { map: {
          prod: 'danger', 'prod-2': 'danger', 'definitely-prod': 'danger',
          staging: 'warning', untagged: 'warning', test: 'info',
          dev: 'success', 'not-prod': 'neutral',
        } } } },
      { field: 'cost', title: 'Monthly cost', type: 'number', layout: { width: 170 },
        format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum' },
    ],
    rows,  // cloud cost rows, one object per resource
  });
</script>

Closing each group with its own subtotal row

A group footer is a row pinned to the bottom of a grouped section that carries a subtotal for that group alone, distinct from the grand total for the whole dataset. A developer reaches for it whenever rows are grouped by something meaningful, such as region, account or order, and each of those groups needs its own closing figure sitting directly under the rows it summarises, rather than forcing a reader to scroll to a single total at the foot of the grid and do the subtraction themselves. Lattice Grid turns this on with groupFooter: true, set once on the grouping configuration, and every group in the JavaScript data grid then renders its own footer row using the same aggregation functions already defined for the column, so a sum on “Revenue” produces a per-group sum without a second calculation being written anywhere. The footer row for a collapsed group stays visible even when its child rows are folded away, so the subtotal remains on screen as a running reference while the reader works through other groups. Because the figure is drawn from the same aggregate state the grid already tracks for that group, expanding or collapsing groups, or scrolling past them in a virtualised list, does not trigger a recalculation, only a repaint of the row already in position.

How do I show a subtotal for each group in a data grid?

Set groupFooter: true on the grouping configuration. Lattice Grid then renders a footer row at the close of every group, using the same aggregation function already assigned to each column, so a sum, average or count defined for the column applies per group without a separate configuration step. The row stays pinned to its group and remains visible when that group is collapsed.