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
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.min.css">
<style>
#grid > div { height: 540px; }
</style>
<div id="app"></div>
<script type="module">
import * as Vue from 'https://esm.sh/vue@3';
import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.27.0/modules/vue.esm.min.js';
const LatticeGrid = createLatticeGrid({ vue: Vue, createGrid });
Vue.createApp({
components: { LatticeGrid },
data() {
// Built once the pane element exists, which is why the config is set in
// mounted() and the grid waits for it with v-if.
return { config: null };
},
mounted() {
this.config = {
rowKey: 'id',
selection: 'single',
toolPanel: {
side: 'left',
panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
exportName: 'lattice-demo',
},
detail: {
// Selecting a row draws its detail into the pane beside the list.
// Exactly one row is open at a time and the list's own row count
// never changes.
target: this.$refs.detail,
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
};
},
template: `
<div style="display: flex; gap: 1rem; align-items: stretch">
<div id="grid" style="flex: 1 1 24rem"><lattice-grid v-if="config" v-bind="config" /></div>
<div ref="detail" style="flex: 1 1 22rem; min-width: 20rem; height: 540px"></div>
</div>
`,
}).mount('#app');
</script>
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.