Lattice Grid Buy a licence

demo D64

Grouping

One level, then several, surviving sort, filter and reload

columns.group(['region'])

Building…
Loading a live grid…

The configuration

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

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

<script type="module">
  import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/modules/htmx.esm.js';

  const grid = createGrid(document.getElementById('grid'), {
    rowKey: 'id',
    selection: 'multiple',
    // Each group heading names the reduction it carries, so the cost heading
    // shows the sum of the rows folded beneath it, not only the column name.
    showTotalInHeader: true,
    toolPanel: {
      side: 'left',
      panels: ['columns', 'filters', 'views', 'quick'],
      actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
      exportName: 'lattice-demo',
    },
    // Two levels of grouping: account, then service inside it.
    columns: [
      { field: 'account', title: 'Account', filter: { type: 'set' }, group: { enabled: true, index: 0 } },
      { field: 'service', title: 'Service', filter: { type: 'set' }, group: { enabled: true, index: 1 } },
      { 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
  });
</script>

Grouping rows by column value in a JavaScript data grid

Row grouping collapses a flat table into a hierarchy: pick one or more columns and every distinct value in the first becomes a collapsible band containing the rows that share it, with a second column nesting a further level inside each band. A developer reaches for this whenever a dataset reads better organised by category than sorted alphabetically, such as orders grouped by region then by sales rep, or log entries grouped by service then by severity. This demo builds that hierarchy through columns.group(['region']), an ordered array of field names that regroups the current row set to match; a longer array adds levels, an empty array flattens the grid back to its original rows. The grouping survives everything else done to the data afterwards: sorting re-sorts rows within each group rather than breaking the hierarchy apart, filtering removes rows from their groups without collapsing empty ones unexpectedly, and a reload rebuilds the same group structure rather than resetting it. Group bands render as their own row type with aria-expanded reflecting collapsed state, so a screen reader announces whether a band is open before reading into its members. Collapsing a group detaches its rows from the render list rather than hiding them with CSS, keeping scroll height tied to what is actually visible.

How do you group rows by column in a JavaScript data grid?

Call columns.group() with an array of field names in the order you want the hierarchy nested, for example columns.group(['region', 'rep']) for region then sales rep within each region. The grid rebuilds its row structure around those values immediately, and calling columns.group([]) removes the grouping and returns to the flat row list.