How to Build a Master-Detail Form in Oracle APEX

How to Build a Master-Detail Form in Oracle APEX

A master-detail form is one of the most common UI patterns in business applications. It shows a parent record (the master) — like an order header — alongside its related child records (the detail) — like the order line items. When the user changes the master record, the detail automatically refreshes.

Oracle APEX makes building master-detail forms straightforward. In this guide, we walk through creating a master-detail page, linking the components correctly, and applying the refinements that turn a basic setup into a professional screen.

Understanding the Master-Detail Pattern

The master-detail pattern models a one-to-many database relationship:

  • Master: One record — the parent (e.g., ORDER, PROJECT, INVOICE)
  • Detail: Many related records — the children (e.g., ORDER_LINES, PROJECT_TASKS, INVOICE_ITEMS)

The link between them is a foreign key: the detail table has a column (like ORDER_ID) that references the master table’s primary key.

Method 1: Using the Create Page Wizard

The fastest way to create a master-detail page in APEX is the Create Page wizard:

  1. In App Builder, click Create Page
  2. Select Form as the page type
  3. Choose Master Detail Form
  4. Select your master table (e.g., ORDERS) and its primary key column
  5. Select your detail table (e.g., ORDER_LINES) and identify the foreign key column linking it to the master
  6. Choose which columns to display in the master form and in the detail Interactive Grid
  7. Configure the page name and navigation settings
  8. Click Finish

APEX generates a complete master-detail page with:

  • A form region at the top for the master record (ORDER header)
  • An Interactive Grid below for the detail records (ORDER_LINES)
  • Save, Cancel, and Delete buttons wired up correctly
  • Automatic linking between master and detail

Understanding What the Wizard Generates

Once the page is created, it is worth understanding how it is wired together:

Master Region: A standard Form region bound to the ORDERS table. It has page items like P10_ORDER_ID, P10_CUSTOMER_ID, P10_ORDER_DATE, P10_STATUS. The P10_ORDER_ID item stores the current master record’s primary key.

Detail Region (Interactive Grid): An Interactive Grid bound to ORDER_LINES. Its SQL source is something like:

SELECT line_id, order_id, product_id, product_name, quantity, unit_price,
       quantity * unit_price AS line_total
FROM   order_lines
WHERE  order_id = :P10_ORDER_ID

The :P10_ORDER_ID bind variable links the detail grid to the currently displayed master record. When the master record changes, the grid re-queries with the new order ID.

Method 2: Building It Manually for Full Control

For more control over layout and behavior, build the master-detail page manually:

Step 1: Create the Master Form

  1. Create a new blank page
  2. Add a Form region and set the Table/View Owner to your schema, Table Name to your master table
  3. In the form region settings, configure the primary key column
  4. The form generates items for each column — arrange them as needed in Page Designer

Step 2: Add the Detail Interactive Grid

  1. Add a new region below the master form
  2. Set the region type to Interactive Grid
  3. In the SQL Query, reference the master primary key item as a bind variable:
SELECT line_id, order_id, product_id, quantity, unit_price,
       quantity * unit_price AS line_total
FROM   order_lines
WHERE  order_id = :P10_ORDER_ID
  1. Set the Interactive Grid’s Primary Key column to LINE_ID
  2. In the Interactive Grid attributes, set Editable to Yes

Step 3: Link Master to Detail with a Dynamic Action

When the user navigates to a different master record (or when the page loads with a specific order ID), the detail grid needs to refresh. Create a Dynamic Action:

  • Event: Page Load
  • True Action: Refresh → Selection Type: Region → select your detail grid region

This ensures the detail grid always shows records for the current master record.

Configuring the Detail Grid: Key Settings

In the Interactive Grid attributes, configure these for a professional master-detail experience:

SettingRecommended ValueReason
EditableYesAllows inline editing of line items
Add RowYesUsers can add new line items directly
Delete RowYesUsers can mark rows for deletion
Save ReportNo (for detail)Keep detail grid standardized
Pagination TypeRow RangesClear navigation for many line items

Handling the Foreign Key in the Detail Grid

When a user adds a new row to the detail grid, the ORDER_ID column needs to be automatically populated with the current master’s ID. Do this by:

  1. In the detail grid’s ORDER_ID column settings, set the column as Hidden (users should not edit it)
  2. Set the Default Value for the ORDER_ID column to :P10_ORDER_ID

Now every new row the user adds automatically gets the correct order ID — they never have to enter it manually.

The Save Flow

APEX handles the save order automatically for master-detail pages:

  1. Master form processes first — the ORDER record is inserted or updated
  2. If inserting a new master record, APEX retrieves the new primary key
  3. Detail grid processes next — ORDER_LINES records are inserted/updated/deleted using the master’s primary key

This order dependency is critical: you cannot insert a line item without a valid order ID. APEX’s page processing order (controlled by process sequence) handles this correctly when the page is generated by the wizard. If building manually, ensure your form process runs before the Interactive Grid process.

Adding Calculated Totals

A common requirement is showing a total at the bottom of the detail grid. Two approaches:

Interactive Grid aggregation: In the column attributes for your LINE_TOTAL column, enable Aggregation and select SUM. An automatic total row appears at the bottom of the grid.

Master form total item: Add a display-only item (P10_ORDER_TOTAL) to the master form and refresh it using a Dynamic Action when the grid data changes:

-- Dynamic Action → Execute Server-side Code after grid save
SELECT NVL(SUM(quantity * unit_price), 0)
INTO :P10_ORDER_TOTAL
FROM order_lines
WHERE order_id = :P10_ORDER_ID;

Navigation Between Master Records

For applications where users browse through multiple master records, add a separate Interactive Report page listing all orders. Link each row to the master-detail page passing the ORDER_ID as a URL parameter:

-- Link column in the orders list report:
-- URL: f?p=&APP_ID.:10:&SESSION.::NO::P10_ORDER_ID:#ORDER_ID#
-- This navigates to page 10 and sets P10_ORDER_ID to the selected order's ID

Common Mistakes and Solutions

Detail grid shows all records, not just current master’s: Check that the detail grid SQL uses the correct bind variable (:P10_ORDER_ID matching the actual page item name) and that the item is not NULL when the page loads.

New detail rows insert without foreign key: Set the ORDER_ID column default value to the master’s primary key item. Make the column hidden in the grid.

Master saves but detail changes are lost: Verify the Interactive Grid save process runs after the master form process. Check process sequence in Page Designer.

Conclusion

Master-detail forms are a foundational APEX pattern that appears in virtually every business application. Whether you use the wizard for speed or build manually for control, the key is understanding the link between master and detail: the primary key item in the master form drives the WHERE clause in the detail grid, and the save processes run in the correct dependency order.

Once you build your first master-detail page and understand how the pieces fit together, you will be able to assemble variations — different detail types, multiple detail grids, or multi-level hierarchies — with confidence. It is one of the most satisfying patterns to build cleanly.

Previous