Skip to main content

Build a master-detail screen

PRO
Pro preview

This feature is part of FD Components Pro, which is documented as a preview and is not publicly available yet. See Editions and Availability.

In FDC Pro, the master-detail relationship belongs to the detail dataset. The master dataset remains independent, while the detail dataset declares which master fields constrain which detail fields.

1. Create the master dataset​

final customers = FdcDataSet(
fields: const [
FdcIntegerField(name: 'customer_id', isKey: true),
FdcStringField(name: 'company', size: 120),
],
adapter: customerAdapter,
);

2. Create the detail dataset​

final orders = FdcDataSet(
fields: const [
FdcIntegerField(name: 'order_id', isKey: true),
FdcIntegerField(name: 'customer_id'),
FdcDateField(name: 'order_date'),
FdcDecimalField(name: 'amount', precision: 18, scale: 2),
],
adapter: orderAdapter,
masterDataSet: customers,
masterRelation: const [
FdcMasterDetailRelation(
masterField: 'customer_id',
detailField: 'customer_id',
),
],
);

The relation can contain multiple mappings for composite relationships.

3. Open both datasets​

await customers.open();
await orders.open();

When the current master record changes, the detail dataset refreshes its effective query using the master relation.

4. Bind two grids​

Column(
children: [
Expanded(
child: FdcProGrid(
dataSet: customers,
columns: customerColumns,
),
),
Expanded(
child: FdcProGrid(
dataSet: orders,
columns: orderColumns,
),
),
],
)

The grid is not responsible for master-detail synchronization. The relationship stays at the dataset layer and therefore also works with standalone editors or custom UI.

User filters still compose normally​

A user filter on the detail dataset is combined with the master relation constraint rather than replacing it.

await orders.filter.set(const [
FdcDataSetFilter(
fieldName: 'status',
operator: FdcFilterOperator.equals,
value: 'open',
),
]);

The active master relation remains in effect.

Design rule​

Keep the adapter unaware of master-detail semantics. It should receive an ordinary effective query containing the filters that need to be executed.

This keeps Memory, SQLite, JSON/REST, and custom adapters compatible with the same dataset-level relationship model.