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);

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 }} />
}