Master-detail
Since 0.1.0-alpha.20Static server-side rendering: no circuit, no WebAssembly.
A row's detail
Use DetailTemplate for what a row opens under it, across the grid, with ItemKey to keep open rows by. Each row gets a button in a column of its own, and the header's opens them all. Open rows are in the address, as ?detail=1004, so this works on a static page with no script; bind OpenDetails to keep them in the component. Only open rows draw the detail, so a grid in it loads its rows when it's opened. Give a nested grid its own QueryPrefix, or every row's grid would share one sort and page. With an ItemsProvider, it asks for a row's lines only when the row opens.
Preview
| Order | Customer | Status | Total | |
|---|---|---|---|---|
| 1001 | Margaret Hamilton | Failed | $66.25 | |
| 1002 | Katherine Johnson | Refunded | $108.00 | |
| 1003 | Grace Hopper | Pending | $149.75 | |
| 1004 | Barbara Liskov | Paid | $191.50 | |
| 1005 | Linus Torvalds | Failed | $233.25 |
Code
Rows = IzzyBlazor.Site.Examples.Table.Orders
@* Each row's button opens its lines under it, in a grid of their own. Open rows are in the address,
so this works on a static page with no script, and the lines are drawn only for open rows. *@
<DataGrid Items="Rows.All" PageSize="5" Caption="Orders with their lines" QueryPrefix="orders-" Grow
ItemKey="o => o.Number.ToString()" RowLabel="(o => $"Order {o.Number}")">
<ChildContent>
<PropertyColumn Property="o => o.Number" Title="Order" Align="CellAlign.Start" Width="6.Rem" />
<PropertyColumn Property="o => o.Customer" Sortable />
<PropertyColumn Property="o => o.Status" />
<PropertyColumn Property="o => o.Total" Format="C" Width="9.Rem" />
</ChildContent>
<DetailTemplate>
@* Its own prefix, so each order's lines keep their own sort. The title is what the grid's caption
already says, so it's for the eye only. *@
<Stack Gap="2">
<TextBlock Size="TextSize.Sm" Weight="FontWeight.Semibold" aria-hidden="true">Lines of order context.Number</TextBlock>
<DataGrid Items="OrderLines.For(context.Number)" Caption="($"Lines of order {context.Number}")"
QueryPrefix="($"lines{context.Number}-")" Size="ControlSize.Sm" Bordered="false">
<PropertyColumn Property="l => l.Product" Sortable />
<PropertyColumn Property="l => l.Quantity" Title="Qty" Width="5.Rem" />
<PropertyColumn Property="l => l.Price" Format="C" Width="7.Rem" />
<PropertyColumn Property="l => l.Amount" Format="C" Width="8.Rem" Aggregate="DataAggregate.Sum" AggregateLabel="" />
</DataGrid>
</Stack>
</DetailTemplate>
</DataGrid>Details in groups
In a grouped grid, a row's detail sits under it, inside its group, with the button one level in from the group's. SingleDetail keeps one open at a time, and ItemHasDetail leaves the button off rows with nothing to show. DetailsOpen starts every row open instead.
Preview
| Details | Order | Customer | Total | |
|---|---|---|---|---|
| Status: Paid (5) | ||||
| 1004 | Barbara Liskov | $191.50 | ||
| 1008 | Margaret Hamilton | $358.50 | ||
| 1012 | Linus Torvalds | $65.50 | ||
| 1016 | Katherine Johnson | $232.50 | ||
| 1020 | Alan Turing | $399.50 | ||
| Status: Pending (6) | ||||
| 1003 | Grace Hopper | $149.75 | ||
| 1007 | Ada Lovelace | $316.75 | ||
| 1011 | Barbara Liskov | $483.75 | ||
| 1015 | Margaret Hamilton | $190.75 | ||
| 1019 | Linus Torvalds | $357.75 | ||
| 1023 | Katherine Johnson | $64.75 | ||
Code
Rows = IzzyBlazor.Site.Examples.Table.Orders
Status = IzzyBlazor.Site.Examples.Table.OrderStatus
@* In groups, a row's detail sits under it, one level in. One opens at a time, and a refunded order
has none. *@
<DataGrid Items="Rows.All" PageSize="2" Caption="Orders in groups with details" QueryPrefix="summary-" Grow
ItemKey="o => o.Number.ToString()" RowLabel="(o => $"Order {o.Number}")"
InitialGroup="status" GroupsOpen SingleDetail ItemHasDetail="o => o.Status != Status.Refunded">
<ChildContent>
<PropertyColumn Property="o => o.Number" Title="Order" Align="CellAlign.Start" Width="6.Rem" />
<PropertyColumn Property="o => o.Customer" />
<PropertyColumn Property="o => o.Status" />
<PropertyColumn Property="o => o.Total" Format="C" Width="9.Rem" />
</ChildContent>
<DetailTemplate>
<DescriptionList Columns="3" Size="ControlSize.Sm">
<DescriptionItem Term="Placed">context.Date.ToString("MMMM d")</DescriptionItem>
<DescriptionItem Term="Lines">OrderLines.For(context.Number).Count</DescriptionItem>
<DescriptionItem Term="Items">OrderLines.For(context.Number).Sum(l => l.Quantity)</DescriptionItem>
</DescriptionList>
</DetailTemplate>
</DataGrid>