Master-Detail (Enterprise)

Master-detail in apex-grid-enterprise renders a nested grid of related rows beneath each expanded master row. Setting the masterDetail config wires up the grid's row expansion automatically (creating, caching, and populating the child grids), so you don't hand-write a detailTemplate.

Basic setup

import 'apex-grid-enterprise/define';

const grid = document.createElement('apex-grid-enterprise');
grid.columns = orderColumns;
grid.data = orders;

grid.masterDetail = {
  columns: [
    { key: 'sku', headerText: 'SKU' },
    { key: 'qty', headerText: 'Qty' },
    { key: 'price', headerText: 'Price' },
  ],
  getDetailData: (order) => order.lineItems,
};

document.body.appendChild(grid);

Each expanded order row now shows a nested grid of its line items.

MasterDetailConfig

FieldTypeDescription
columnsColumnConfiguration[] or (row) => ColumnConfiguration[]Detail-grid columns; a function lets each master row have its own columns
getDetailData(row) => C[] | Promise<C[]>Returns the detail rows for a master row; may be async
detailTag'apex-grid' | 'apex-grid-enterprise'Which element to render the detail grid as (default 'apex-grid')
detailHeightnumber | stringHeight of the detail region
isExpandable(row) => booleanWhether a given master row can expand
configureDetail(grid, context) => voidHook to configure each detail grid instance after creation

Async detail data

getDetailData can return a promise, so detail rows can be fetched on demand when a master row expands:

grid.masterDetail = {
  columns: lineItemColumns,
  getDetailData: async (order) => {
    const res = await fetch(`/api/orders/${order.id}/items`);
    return res.json();
  },
  detailHeight: 240,
};

Per-row expandability

Use isExpandable to hide the expander on rows with no detail:

grid.masterDetail = {
  columns: lineItemColumns,
  getDetailData: (order) => order.lineItems,
  isExpandable: (order) => order.lineItemCount > 0,
};

Enterprise detail grids

Set detailTag: 'apex-grid-enterprise' to make each detail grid itself an enterprise grid (so detail grids can group, aggregate, etc.). Use configureDetail to set up each instance:

grid.masterDetail = {
  columns: lineItemColumns,
  getDetailData: (order) => order.lineItems,
  detailTag: 'apex-grid-enterprise',
  configureDetail: (detailGrid, context) => {
    detailGrid.aggregations = { price: ['sum'] };
  },
};

The configureDetail context provides the master data (the row) and its rowIndex.

Refreshing a detail

When the underlying detail data changes, invalidate a single master row's cached detail:

grid.refreshDetail(order);

Turning it off

Set masterDetail back to null to turn master-detail off: rows stop being expandable and the expansion config the grid had before is restored, unless the app set a new one in the meantime (from 0.8). A getDetailData that rejects or throws shows an empty detail and asks again the next time that detail is shown.

Events from nested grids

A detail grid renders inside one of the master grid's rows, so its events cross the master's body on their way out. From 3.6 the master ignores them: clicks, Space selection, Ctrl+Z and pointer drags in a nested grid no longer drive the outer one. Your own listeners on the master can make the same check with ownsEvent:

grid.addEventListener('click', (event) => {
  if (!grid.ownsEvent(event)) return // came from a detail grid
  // ...
});

Relationship to manual expansion

masterDetail configures the grid's expansion automatically and overrides any manual expansion/detailTemplate you set. For fully custom expansion content without nested grids, use the community row expansion feature instead.

React example

import { useEffect, useRef } from 'react'
import 'apex-grid-enterprise/define'

export default function MasterDetailGrid() {
  const ref = useRef<any>(null)

  useEffect(() => {
    const grid = ref.current
    grid.columns = orderColumns
    grid.data = orders
    grid.masterDetail = {
      columns: lineItemColumns,
      getDetailData: (order: any) => order.lineItems,
      detailHeight: 220,
    }
  }, [])

  return <apex-grid-enterprise ref={ref} style={{ height: 520 }} />
}