Skip to content
IzzyBlazor 0.1.0-alpha.20

Enter all results ↑ ↓ move Esc close

Master-detail

Since 0.1.0-alpha.20
Open a row's detail under it, such as its lines in a grid of their own.

Static 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

Orders with their lines
OrderCustomer StatusTotal
1001Margaret HamiltonFailed$66.25
1002Katherine JohnsonRefunded$108.00
1003Grace HopperPending$149.75
1004Barbara LiskovPaid$191.50
1005Linus TorvaldsFailed$233.25

Code

MasterDetail.razor
@using 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

Orders in groups with details
DetailsOrderCustomerTotal
Status: Paid (5)
1004Barbara Liskov$191.50
1008Margaret Hamilton$358.50
1012Linus Torvalds$65.50
1016Katherine Johnson$232.50
1020Alan Turing$399.50
Status: Pending (6)
1003Grace Hopper$149.75
1007Ada Lovelace$316.75
1011Barbara Liskov$483.75
1015Margaret Hamilton$190.75
1019Linus Torvalds$357.75
1023Katherine Johnson$64.75

Code

GroupedDetail.razor
@using Rows = IzzyBlazor.Site.Examples.Table.Orders
@using 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>

Connection lost

Rejoining the server…