demo D79
A detail pane beside the list
The detail renders into your own element, one record at a time
detail: { target: '#pane' }
The configuration
<script>
import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.esm.min.js';
import createLatticeAction from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/modules/svelte.esm.min.js';
const lattice = createLatticeAction({ createGrid });
// The detail host. It is declared before the grid in the markup below, so the
// bound element exists by the time the grid mounts and reads it; the getter on
// target is what defers that read to then rather than to script init.
let detailEl;
const config = {
rowKey: 'id',
selection: 'single',
toolPanel: {
side: 'left',
panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
exportName: 'lattice-demo',
},
detail: {
// The detail renders into the pane beside the list, and exactly one row is
// open at a time: opening a second closes the first, and the list's own row
// count never changes.
get target() { return detailEl; },
rows: (row) => row.data.ports,
config: {
rowKey: 'port',
autoHeight: true,
columns: [
{ field: 'port', title: 'Port', layout: { width: 140 } },
{ field: 'vlan', title: 'VLAN', type: 'number', layout: { width: 100 } },
{ field: 'speed', title: 'Speed', type: 'number', format: { suffix: ' Gb' }, layout: { width: 110 } },
{
field: 'state', title: 'State', layout: { width: 130 },
cell: { decoration: 'dot', variant: { map: { up: 'success', down: 'danger', 'admin down': 'neutral' } } },
},
{ field: 'peer', title: 'Peer AS' },
],
},
},
columns: [
{ field: 'circuit', title: 'Circuit', layout: { width: 160 } },
{ field: 'customer', title: 'Customer', filter: { type: 'set' } },
{ field: 'portCount', title: 'Ports', type: 'number', layout: { width: 100 } },
{ field: 'charge', title: 'Monthly charge', type: 'number', format: { style: 'currency', currency: 'GBP', decimals: 0 }, layout: { width: 170 } },
],
rows, // circuits, each carrying its own ports array
};
</script>
<svelte:head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.min.css">
</svelte:head>
<div style="display: flex; gap: 1rem; align-items: stretch">
<div bind:this={detailEl} style="order: 2; flex: 1 1 22rem; min-width: 20rem; height: 540px"></div>
<div use:lattice={config} style="order: 1; flex: 1 1 24rem; height: 540px"></div>
</div>
Rendering a detail pane for the selected row
A detail pane shows the full record for whichever row is currently selected, drawn into an element you own rather than into a row that expands inline. A developer reaches for this over an inline detail row when the record has more fields than fit the grid’s columns, when the detail needs its own layout separate from the tabular one, or when the list and the detail are meant to sit side by side. Lattice Grid wires this up with detail: { target: '#pane' }, naming the element the current row’s data should render into; selecting a different row swaps the content of that target without touching the row list, so scroll position and any open branches in the tree stay put. Because this is a JavaScript data grid built around row-level updates rather than full re-renders, moving selection only re-renders the pane, not the grid body. The pane receives the row’s data as a plain object, so what appears inside it, from a field list to a nested form, is up to the markup supplied at the target. Selection moves with the keyboard, and the target element updates in place so assistive technology tracking that region announces the new content rather than losing focus context on every change.
How do I show a detail view for the selected row in a JavaScript data grid?
Set detail: { target: '#pane' } on the grid configuration, pointing at the element the detail should render into. Lattice Grid pushes the selected row’s data into that target whenever selection changes, leaving the markup and layout of the pane entirely up to you rather than constraining it to an inline expanding row.