Lattice Grid Buy a licence

demo D130

Header context menu in htmx

Right-click a heading. The menu, not the rendering

header:contextmenu

This grid opens a menu on right-clicking a heading, for actions on the whole column: sort, pin, hide and group. It puts column-level operations where a reader looks for them, separate from the per-cell menu, so acting on a column is one click away.

Building…
Loading a live grid…

This is the htmx version. A server-rendered table is upgraded in place, so the page is readable before any script runs and gains the full grid when the module loads, which suits a progressively enhanced app.

The configuration

<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">

<!-- A real, server-rendered table: readable with JavaScript off. data-field on
     each header names the column that cell becomes, and data-id on each row is
     the key the grid carries it under. -->
<table id="header-context-menu-table" data-lattice-grid>
  <thead>
    <tr>
      <th data-field="service">Service</th>
      <th data-field="team">Team</th>
      <th data-field="owner">Owner</th>
      <th data-field="headcount">Headcount</th>
      <th data-field="monthlyCost">Monthly cost</th>
      <th data-field="budget">Budget</th>
    </tr>
  </thead>
  <tbody>
    <tr data-id="1"><td>svc-00001</td><td>Search</td><td>k.yilmaz</td><td>2</td><td>37920.55</td><td>20036</td></tr>
    <tr data-id="2"><td>svc-00002</td><td>Mobile</td><td>m.svensson</td><td>2</td><td>30070.04</td><td>56591.85</td></tr>
    <tr data-id="3"><td>svc-00003</td><td>Identity</td><td>j.okafor</td><td>1</td><td>36278.48</td><td>8543.17</td></tr>
    <!-- the rest of the rows, rendered by your server -->
  </tbody>
</table>

<script type="module">
  import { hydrateTable } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/htmx.esm.min.js';

  // The markup carries the rows; a server-rendered table's column types are
  // declared in the config hydrateTable takes. The grid replaces the table
  // where it stood.
  const grid = hydrateTable(document.getElementById('header-context-menu-table'), {
    selection: 'multiple',
    toolPanel: {
      side: 'left',
      panels: ['columns', 'filters', 'views', 'quick'],
      actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
      exportName: 'lattice-demo',
    },
    // Right-click a heading for its menu of column actions. The Team column
    // carries lockVisible, so the entry that would hide it stays disabled.
    columns: [
      { field: 'service', title: 'Service', layout: { pin: 'start', width: 160 } },
      { field: 'team', title: 'Team', layout: { width: 130, lockVisible: true }, filter: { type: 'set' } },
      { field: 'owner', title: 'Owner', filter: { type: 'set' } },
      { field: 'headcount', title: 'Headcount', type: 'number', total: 'sum' },
      { field: 'monthlyCost', title: 'Monthly cost', type: 'number',
        format: { style: 'currency', currency: 'USD' }, total: 'sum' },
      { field: 'budget', title: 'Budget', type: 'number',
        format: { style: 'currency', currency: 'USD' }, total: 'sum' },
    ],
  });
</script>

Right-clicking a column heading for a menu of column-level actions

A context menu attached to the header row gives a user a place to act on a column as a whole, separate from the cell context menu that acts on a single value. Sorting, pinning, hiding, and grouping are the operations that belong here: they change the shape of the table rather than the content of a record, and putting them behind a right-click keeps the header free of icon clutter. Any JavaScript data grid with a dense set of columns benefits from this split, since a toolbar button for every column operation would not fit above a wide table, while a menu scoped to the column under the pointer scales to however many columns are configured.

Lattice Grid exposes the interaction through the header:contextmenu event, fired with the column definition and the triggering event, so a host application can build its own menu contents, filter which actions appear per column, or suppress the menu on columns marked non-configurable. The default menu closes on outside click, on Escape, and after an item is chosen, returning focus to the header cell that opened it. It is reachable without a mouse: the context-menu key and Shift+F10 open it on a focused header, and the menu itself is a role="menu" with arrow-key navigation between items.

How do you open a column’s context menu without a mouse?

Focus the column header with Tab or the arrow keys, then press the keyboard context-menu key or Shift+F10. Lattice Grid opens the same menu a right-click would, positioned against the focused header cell, with arrow-key navigation between items and Escape to dismiss it.