# Advanced Field Controls

Screenshots on this page are taken from the Chinese UI. Menu, field and button names in the text use the English UI labels.

# Target Audience

This document is intended for developers and implementers of this system

# Overview

This document describes some of the advanced field controls in this system, such as how to use the sub-table control.

# Sub-table Control

The sub-table control displays and edits a group of associated objects (one-to-many or many-to-many) in a single field, one associated object per row. The figure below shows the user detail view in Business Config > User, where the "User Groups" sub-table lists the user groups the user belongs to (only the lower half of the detail dialog is captured in the figure):

Sub-table control in the user details

# Definition

When creating a form field, set the field's display type (displayType) to one of the following two values:

displayType Description
subTable Displays the associated objects of a one-to-many or many-to-many field of the current object. The legacy value Sub table is automatically converted to subTable
relativeSubTable Displays a one-to-many field of another object reached from the current object along an association path. The path is written in subTable.relativeNamePath in the field's extInfo; for example, customer.contacts on an order displays the contacts of the order's customer. It can only be displayed on saved objects; in a create form it stays in the loading state

The array display type uses the same list control as the sub-table and is generally used for one-to-many fields in list pages.

TIP

The "Display Control Config (DomainColumnClientSideTypeConfig)" menu has been removed since 1.0 (set displayType directly on the form field instead).

# Display Properties

Sub-table configuration lives in two places:

  1. The extInfo of the sub-table field itself: use displayForm to specify which form the sub-table uses to decide which columns are displayed; the value is the form name. The form is looked up by name regardless of its type and is always rendered as a list; for example, the User Groups sub-table in the user form references UserGroup Sub Table Form For User, a form of type SUB_TABLE. When it is not set, the child object's LIST form is used. The relativeNamePath of relativeSubTable is also written here.
  2. The extInfo of the form that displayForm points to: row operation settings are written in its subTable, including whether rows can be updated, created or deleted (updatable, creatable, deletable), whether rows can be reordered by drag and drop (dragSort), the position of the "Create" button (asc), and whether row-level object actions are provided (enableActions).

Data in a sub-table is generally displayed in descending order of id; when a Data Hook is configured on displayForm, the Data Hook determines the data and its order.

An example:

// 1. extInfo of the sub-table field (form field)
{
  /** Name of the form used by the sub-table (determines which columns are shown); if not set, the LIST form of the child domain is used */
  "displayForm"?: "UserGroup Sub Table Form For User",
  /** Only used by relativeSubTable: path of a one-to-many field starting from the current object, separated by dots */
  "subTable"?: {
    "relativeNamePath"?: "customer.contacts"
  }
}

// 2. extInfo of the form referenced by displayForm (row operation permissions etc. go here, not on the field)
{
  "subTable"?: {
    /** Whether rows can be updated, created and deleted; overrides the defaults once set (updatable by default; for a one-to-many sub-table with mappedBy, rows can only be deleted after the owner object has been saved, and the "Create" button is currently not shown) */
    "updatable"?: true | false,
    "creatable"?: true | false,
    "deletable"?: true | false,
    /** Whether rows can be reordered by drag and drop */
    "dragSort"?: true | false,
    /** When true, the "Create" button is placed at the bottom of the table (top by default); in a drag-sortable sub-table, new rows are also appended to the end */
    "asc"?: true | false,
    /** Provides row-level object actions in the operations column; the operations column is shown even in read-only state */
    "enableActions"?: true | false
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

WARNING

  • updatable, creatable, deletable and similar settings have no effect when written in the extInfo of the sub-table field itself; they must be written on the form that displayForm points to. Some of the system's preset seed data (such as the user and domain class forms) still writes them on the field.
  • The legacy sortBy, keepOrder and searchModal settings no longer take effect since 1.0.
  • In the current version, one-to-many sub-tables with mappedBy (such as the user's User Groups) do not show the "Create" button, so rows cannot be added in the sub-table.

TIP

When sub-table data is saved:

  • When you click "Save" on a sub-table row, that row is immediately created or updated in the database
  • For one-to-many sub-tables with mappedBy, deleting a row takes effect immediately; for other sub-tables, deletions are submitted together when the main object is saved

For action parameter forms, the frontend submits the sub-table data as a property of the form. How the backend handles it depends on the action's custom Core Logic implementation.

Last Updated: 9/24/2026, 2:27:35 PM