5.2: Building Card, List & Document Pages

Key Takeaways

  • Card pages organize complex entity attributes across collapsible FastTabs (group containers), with field visibility prioritized by the Importance property (Promoted, Standard, Additional).
  • List pages display multi-record collections inside a repeater control, offering filtering, search, sorting, column personalization, and drilldown navigation to master entities via CardPageId.
  • Processing multi-row selections in List page actions requires calling CurrPage.SetSelectionFilter(RecordVar) to transfer the user's active UI selection into a temporary filter buffer before executing FindSet().
  • Document pages implement the transactional master-detail design pattern by embedding a ListPart subform within a master Card header, linked via SubPageLink.
  • Setting UpdatePropagation = Both on embedded subpage parts is mandatory to trigger parent header recalculations, FlowField updates, and total refreshes whenever child lines are inserted, modified, or deleted.
Last updated: August 2026

5.2 Building Card, List & Document Pages

Card, List, and Document pages represent the core tripartite pattern of Business Central's operational user interface. Master entities (such as Customers, Vendors, and Items) use Card pages for deep attribute editing and List pages for multi-record browsing and batch actions. Complex business transactions (such as Sales Orders, Purchase Invoices, and Assembly Orders) use Document pages that combine a master header with an embedded line item subform. Mastering these patterns is essential for the MB-820 exam.


1. Designing Card Pages & FastTab Mechanics

A Card page (PageType = Card) is designed for viewing and editing a single record from a table. The layout is divided into collapsible sections called FastTabs, declared using group() containers inside area(Content).

The Importance Property and Summary Headers

Users can collapse and expand FastTabs to manage screen space. The Importance property on fields controls their display behavior:

  • Promoted: The field is displayed when the FastTab is expanded. Crucially, when the FastTab is collapsed, the field's value is promoted into the FastTab summary header bar, allowing users to inspect key values without expanding the tab.
  • Standard (Default): The field is displayed when the FastTab is expanded, but its value does not appear in the collapsed header summary.
  • Additional: The field is hidden by default behind a Show more link when the FastTab is expanded. This declutters the interface for secondary fields that are rarely modified.
group(General)
{
    Caption = 'General';
    field("No."; Rec."No.")
    {
        ApplicationArea = All;
        Importance = Promoted; // Shown in header when FastTab is collapsed
    }
    field(Name; Rec.Name)
    {
        ApplicationArea = All;
        Importance = Promoted;
    }
    field("Search Name"; Rec."Search Name")
    {
        ApplicationArea = All;
        Importance = Additional; // Hidden behind 'Show more'
    }
}
Loading diagram...
Master-Detail Document Page Data Synchronization Architecture

2. Building List Pages: Repeaters, Selection Filters, and Drilldowns

List pages present records in a tabular grid using a repeater() container. In addition to basic viewing, list pages provide data navigation and multi-record action handling.

The CardPageId Property

Setting CardPageId = "Customer Card"; on a List page establishes a direct link between the list view and the master entity card. When the user double-clicks a row or triggers the standard Edit / View action, the Business Central Web Client automatically opens the assigned Card page for the selected record.

Multi-Select Action Processing Pattern

When an action on a List page needs to process multiple rows selected by the user (via multi-select checkboxes), simply looping through Rec will only process the active cursor record. Developers must call CurrPage.SetSelectionFilter() to copy the user's active UI selection into a record variable buffer:

actions
{
    area(Processing)
    {
        action(CertifyEquipmentBatch)
        {
            ApplicationArea = All;
            Caption = 'Certify Selected';
            Image = Certificate;
            ToolTip = 'Applies compliance certification to all selected equipment items.';

            trigger OnAction()
            var
                SelectedEquipment: Record "Equipment Item";
                MaintMgmt: Codeunit "Equipment Maintenance Mgmt";
            begin
                // Copy the user's active UI multi-selection into the record buffer
                CurrPage.SetSelectionFilter(SelectedEquipment);
                
                // Iterate through the filtered selection
                if SelectedEquipment.FindSet() then
                    repeat
                        MaintMgmt.CertifySingleItem(SelectedEquipment);
                    until SelectedEquipment.Next() = 0;
            end;
        }
    }
}

Exam Trap: Calling CurrPage.SetSelectionFilter(Rec) modifies the filter set on the page's active Rec. Best practice is to pass a separate record variable (e.g., SelectedEquipment) so the page's UI view remains unaffected.

3. Building Master-Detail Document Pages and Subforms

A Document page represents a master-detail business transaction (e.g., Sales Order, Purchase Invoice). It is constructed by declaring a Card page on the header table (e.g., Sales Header) and embedding a ListPart page for the lines (e.g., Sales Line) inside area(Content).

SubPageLink and AutoSplitKey Mechanics

To link the lines to the active header, the part() declaration defines SubPageLink:

  • SubPageLink = "Document Type" = field("Document Type"), "Document No." = field("No.");
  • When the subpage is rendered, the NST automatically applies this filter to the child Sales Line table.
  • When the user creates a new line in the subform, the platform automatically initializes the Document Type and Document No. fields on the child line record.

To enable automatic line numbering without requiring manual line number entry, the ListPart page defines AutoSplitKey = true;:

  • The line table's primary key must end with an Integer line number field (e.g., Document Type, Document No., Line No.).
  • When the user inserts a row between lines 10000 and 20000, AutoSplitKey automatically assigns 15000 to the new line's Line No..

Synchronizing Header Totals: UpdatePropagation = Both

In transactional documents, the header card frequently displays summary FlowFields (such as Total Amount Excl. VAT, Total VAT, and Total Amount Incl. VAT).

  • By default, changes in a subpage (ListPart) do not notify the parent header page to recalculate.
  • To force the parent header to re-execute its OnAfterGetCurrRecord trigger, recalculate FlowFields, and update footer totals whenever a line is inserted, modified, or deleted, developers must set UpdatePropagation = Both; on the subpage part definition.

4. Complete Master-Detail AL Implementation

// 1. MASTER HEADER DOCUMENT PAGE
page 50110 "Equipment Rental Order"
{
    PageType = Document;
    SourceTable = "Rental Header";
    Caption = 'Equipment Rental Order';
    RefreshOnActivate = true;

    layout
    {
        area(Content)
        {
            group(General)
            {
                Caption = 'General';
                field("No."; Rec."No.")
                {
                    ApplicationArea = All;
                    Importance = Promoted;
                    ToolTip = 'Specifies the rental order number.';
                }
                field("Customer No."; Rec."Customer No.")
                {
                    ApplicationArea = All;
                    Importance = Promoted;
                    ToolTip = 'Specifies the renting customer.';
                }
                field("Order Date"; Rec."Order Date")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the date of the agreement.';
                }
            }
            part(Lines; "Rental Order Subform")
            {
                ApplicationArea = All;
                SubPageLink = "Document No." = field("No.");
                // Ensures header totals update immediately when lines change
                UpdatePropagation = Both;
            }
            group(Totals)
            {
                Caption = 'Rental Totals';
                field("Total Order Amount"; Rec."Total Order Amount")
                {
                    ApplicationArea = All;
                    Importance = Promoted;
                    Editable = false;
                    ToolTip = 'Specifies the aggregated total of all rental lines.';
                }
            }
        }
    }
}

// 2. CHILD LISTPART SUBFORM PAGE
page 50111 "Rental Order Subform"
{
    PageType = ListPart;
    SourceTable = "Rental Line";
    Caption = 'Lines';
    AutoSplitKey = true;
    DelayedInsert = true;

    layout
    {
        area(Content)
        {
            repeater(Group)
            {
                field("Equipment No."; Rec."Equipment No.")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the equipment being rented.';
                }
                field(Description; Rec.Description)
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the equipment description.';
                }
                field("Daily Rate"; Rec."Daily Rate")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the price per rental day.';
                }
                field("Rental Days"; Rec."Rental Days")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the number of rental duration days.';
                }
                field("Line Amount"; Rec."Line Amount")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the total line amount.';
                }
            }
        }
    }
}
Test Your Knowledge

A developer configures a FastTab on a Customer Card page and sets Importance = Promoted on the 'Credit Limit (LCY)' field and Importance = Additional on the 'Tax Liable' field. What visual behavior occurs in the Web Client when the user interacts with this page?

A
B
C
D
Test Your Knowledge

An action on an Item List page is programmed to export selected items to an external warehouse system. When a user selects five rows using checkboxes and runs the action, only the active single row is exported. How should the developer modify the action trigger code to process all five selected items?

A
B
C
D
Test Your Knowledge

On a custom Sales Order document page, line totals on the header FastTab fail to update automatically when a user modifies the 'Quantity' or 'Unit Price' on a line in the subform. The user must manually press F5 to see updated header totals. Which property configuration resolves this issue?

A
B
C
D