# Basic Form Customization

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 the system.

# Overview

Menus, forms, form field groups and form fields are all stored in the database. They can be maintained in the UI, or written as CSV seed data and imported with the system. This document explains how to configure each of them in the order "menu → form → field group → field", and ends with a complete set of CSV examples.

# Definition

The menu on the left side of the UI is rendered from DynamicMenu objects and is maintained in the UI via System Config > UI > Menus. The left side of the page shows the menu tree; click a node and the right side shows the edit form of that menu, where you can save it, delete it, or create a new menu under it:

The properties of a menu are:

Property Description
Parent menu (parent) Empty means a top-level menu
Name (name) Required, unique within the tenant, cannot be changed after creation. CSV import uses it to locate the menu
Type (type) Menu type, see below
Label (label) Required, the text displayed on the menu
Icon (icon) antd icon name, see below
Form (form) When the type is FORM, the form opened when the menu is clicked
Link (link) The address when the type is INTERNAL_LINK / EXTERNAL_LINK
Display sequence (displaySequence) Smaller values come first
Access requirement (accessRequirement) Visibility requirement; the value is the name of an access requirement such as USER, DEVELOPER or ADMIN. This field is not shown in the UI and can only be set via CSV

Translation of menu labels

When the sidebar displays a menu, it uses the label as the key to look up a translation in the menu translation namespace (maintained in System Config > Localization > Translations). So the menu tree above shows the original label, while the sidebar shows the translated text.

# Association with Forms

The association between a menu and a form is stored on the menu: edit the menu, set its type to FORM, and select the form to open in "Form". The form itself has no "owning menu" field.

# Visibility

Whether a menu is displayed is determined jointly by the accessRequirement of the menu and of the form:

  • FORM menus: if the menu has an accessRequirement, the system first checks whether the current user meets it; it then checks the accessRequirement of the associated form (a form without one is satisfied by everyone). The menu is displayed only if both checks pass. Therefore form menus usually do not need their own accessRequirement; let the form decide.
  • Menu groups, internal links and external links: must have an accessRequirement. Without one, no user (including administrators) can see the menu.
  • A menu group is displayed only when it has at least one visible child menu.

WARNING

The menu edit UI has no "Access requirement" field. A menu group or link menu created in the UI has no accessRequirement, so after saving it will not appear in anyone's sidebar. Import such menus via CSV and fill in the accessRequirement.name column (see Menu Definition CSV File).

# Types

The menu types currently supported are:

  • MENU_GROUP menu group: contains child menus; nest menu groups to build multi-level menus
  • FORM form: opens the associated "Form" when clicked; for form definitions see the Forms section
  • INTERNAL_LINK internal link, EXTERNAL_LINK external link: the menu address is taken from the link property. An internal link whose link is empty is not displayed

# Icons

Menu icons use antd icons. Fill in the icon component name (e.g. UserOutlined) without the <> part. For the list of icons, see Ant Design Icons (opens new window)

# Forms

# Definition

Custom forms are stored in DynamicForm objects and are maintained in the UI via System Config > Forms > Forms. The figure below creates a list form that shows only locked users:

The properties of a form are:

Property Description
Type (type) Required, see Form Types
Name (name) Required, unique within the tenant, cannot be changed after creation. Menus, fields and field groups all reference the form by it
Label (label) The title of the form displayed on the page
Description (description) Description
Object type (objectType) The domain object displayed by the form
Extend information (extInfo) Extended properties in JSON format, see Form extInfo Support
Form Hook (formHook) Form-level customization dynamic logic, used for field default values, field linkage, visibility, read-only, required, etc. See Form Customization (Form Hook)
Form Hook trigger fields (formHookTriggerFields) Comma-separated field names; when the value of any of these fields changes in the UI, the Form Hook is executed again
Data Hook (dataHook) Data-level customization dynamic logic, used to transform the data returned for lists and details
Access requirement (accessRequirement) The range of users who can use the form; when not set, all users can use it

TIP

The create form in the UI contains only "Type, Name, Label, Description, Object type, Extend information". Form Hook, Form Hook trigger fields, Data Hook and access requirement must be set via CSV. Click "Update" in the form list, and the edit dialog also lists the fields and field groups of the form as sub-tables.

The title of the create and edit dialogs is taken in the following order (for a page opened from a menu, the title shows the menu name):

  1. The form's label
  2. domainTitle in extInfo
  3. The translation of the associated object name (domainTitle translation namespace)

# Form Types

Form types are stored in DynamicFormType objects; the system ships with 24 types. The current frontend provides renderers for only some of them. If you attach a type without a renderer to a menu, the page only shows Unknown form <type name>.

Type Purpose Current frontend
LIST Object list page Supported
CREATE Object create form Supported
UPDATE Object edit form Supported
FINDER The search area above a list; can also be attached to a menu on its own Supported
DOMAIN Domain object form Supported
DEFAULT General form that renders a set of inputs according to the field definitions Supported
MASTER_DETAIL_LIST Master-detail structure with a tree on the left and a form on the right, see Master-Detail Form Definition Supported
TREE_LIST Tree list Supported
DASHBOARD Dashboard, see Dashboard Supported
AMIS Page described by an AMIS Schema, see AMIS Forms Supported
ACTION Parameter form of an object action Supported
IFRAME Embedded page, address taken from url in extInfo Supported
SUB_TABLE Form used by a sub-table, referenced by name through the sub-table field's displayForm and rendered as a list Sub-table only
INLINE_DISPLAY Same as above; used for inline details in older versions Sub-table only
INLINE_EDITABLE_DISPLAY Same as above; used for inline editable details in older versions Sub-table only
DELETE Delete confirmation form Not implemented
INLINE_FULL_TEXT_SEARCH_LIST Inline full-text search results Not implemented
FULL_TEXT_SEARCH_LIST Full-text search results Not implemented
RELATED_DETAIL_LIST Related detail list Not implemented
CARD_LIST Card list Not implemented
DYNAMIC_FRAME Dynamic frame Not implemented
WIZARD Wizard, removed as of 1.0 (use Form Hook for multi-step data collection) Removed
GANTT Gantt chart, removed as of 1.0 Removed
GANTT_TOOLTIP Gantt chart detail card, removed as of 1.0 Removed

TIP

The three "Sub-table only" types have no renderer of their own: once a sub-table field finds its form by name, it always renders it as a list, regardless of the form type. Frontend plugins can register custom renderers for any form type through FrontendPluginManifest.forms.

# AMIS Forms

The platform includes the AMIS (opens new window) low-code frontend framework as one of its form renderers. For a form of type AMIS, the AMIS Schema is stored in the amis property of the form's extInfo.

# Capabilities

  • Visual editing: when you open the page of an AMIS form and the current user has permission to modify that form, a floating edit button (tooltip "edit") appears on the page. Click it to enter the AMIS visual editor; on save, the Schema is written back to the amis property of the form's extInfo
  • Page data: when the page opens, it calls GET /form/data/{formId}, which executes the form's Data Hook; the returned object becomes the data of the AMIS page and can be referenced in the Schema with ${fieldName}. When no Data Hook is configured, the page data is empty
  • Unified authentication: data requests issued by AMIS components go through the platform's unified request channel and carry the login credentials automatically

# Enabling

  1. Create a form in System Config > Forms > Forms and select AMIS as the type
  2. Attach the form to a menu of type FORM
  3. Open the page from the menu, click the floating edit button to design the page, and save

# Example

The Schema below displays the two values customerCount and vipCount returned by the Data Hook:

{
  "type": "page",
  "title": "客户概况",
  "body": [
    { "type": "tpl", "tpl": "客户总数:${customerCount},其中 VIP 客户 ${vipCount} 个" }
  ]
}
1
2
3
4
5
6
7

# Form Field Groups

On the create and edit UI of an object, form fields can be displayed in collapsible field groups.

# Definition

Field groups are stored in DynamicFormGroup objects and can be viewed in the UI via System Config > Forms > Field Groups (the figure below hides columns such as Help text and Display sequence so that the Icon column is fully visible):

WARNING

In the current version, clicking Create, Update or Details on the "Field Groups" page opens a dialog that stays in the loading state and cannot be edited. You can "Update" a form in System Config > Forms > Forms and view its existing groups in the "Form Field groups" sub-table of the edit dialog; to add or modify groups, import them via CSV.

A form that contains field groups is displayed as follows (Development > Schedules > Create, with the "Logics" group collapsed):

TIP

The current frontend displays the field group's label as-is, without translation, which is why the built-in group names in the screenshot above are in English even in the Chinese UI. For your own field groups, write the label directly in the language your users read. The field label "Start date" in the screenshot is likewise untranslated UI text in the Chinese UI and has nothing to do with field groups.

The properties of a field group are:

Property Description
Name (name) Required, unique within the same form, cannot be changed after creation
Label (label) Required, the group title
Display sequence (displaySequence) Smaller values come first
Help text (helpText) Help text of the group
Icon (icon) antd icon name, see Icons
Form (form) Required, cannot be changed after creation

A field is placed into a group through its own "Group" property.

WARNING

The current version cannot hide an entire field group dynamically: field groups returned by the API carry no display state, and Form Customization (Form Hook) can only control the visibility of individual fields. Even if a Form Hook hides every field in a group, the group title is still displayed.

# Naming Conventions

Field group names only need to be unique within the same form. To make them easy to recognize in CSV, name them <form type>_<object name>_<group name>, e.g. c_customers_basic for the basic information group of the customer create form, and u_customers_basic for that of the edit form.

# Form Fields

# Definition

Form fields are stored in DynamicFormField objects and are maintained in the UI via System Config > Forms > Fields (the figure below omits the blank area below the Extend information editor):

The properties of a field are:

Property Description
Form (form) Required
Group (group) The group the field belongs to; can be empty
Field type (fieldType) Required, STATIC_FIELD (static field) or TRANSIENT_FIELD (transient field)
Field name (fieldName) Required. For a static field it must be an existing field name on the associated object
Label (label) Required
Help text (helpText) Help text displayed next to the field
Decides (decides) Comma-separated field names, used in older versions to "refresh other fields after this field changes". Not effective in the current version (the /column/refresh/{domainName} endpoint requested by the frontend does not exist); for field linkage use the form's Form Hook trigger fields
Display Type (displayType) Control type, free text; see Display Controls for values. When empty, the control is chosen automatically from the type of the object field
Nullable (nullable) Whether the field can be empty in the form
Extend information (extInfo) Extended properties in JSON format, see Form Field extInfo Support
Display sequence (displaySequence) Required, smaller values come first
Editable (editable) Only effective for transient fields. It is not shown in the UI and can only be set via CSV. To make a static field read-only, set editable (create form) or updatable (edit form) to false in meta of extInfo

TIP

In the screenshot, the Static field option in the "Field type" dropdown and the field label Decides appear in English because they are not translated in the Chinese UI.

Depending on the form type, the field definitions control the following:

  • List page: which columns are displayed, their order and display controls
  • Search (FINDER) form: which search conditions are displayed, their order and display controls
  • Create and edit forms: which fields are displayed, their order, whether they are required, help text, display controls and group

# Display Controls

displayType is free text, and the backend performs only one conversion: if the value is a control name from an older version (such as Sub table or Single file), it is converted to the corresponding key (subTable, file); all other values are passed to the frontend unchanged. If the frontend cannot find a matching control, the field position shows Unsupported displayType: xxx.

The control keys supported by the current frontend are:

key Control
id Identifier
string Single-line text
text Multi-line text
password Password
integer, int, long Integer
decimal Decimal
percentage Percentage
currency Currency
date Date
dateRange Date range
datetime Date and time
zonedDatetime Date and time with time zone
boolean Switch
enum Enum dropdown
httpMethod HTTP method (enum dropdown)
valueSelect Value select
link Link; use link in extInfo to set the display text and how it opens
progress Progress bar
icon Icon
treeSelect Tree select
roles Roles
code Code editor
json JSON editor
markdown Markdown editor
stacktrace Stack trace
functionEditor Function editor
file Single file
fileList Multiple files
image Image
video Video
object Single object select
objects Multiple object select
genericObject, genericObjects Read-only display of objects of any type
array List of one-to-many associated objects
subTable Sub-table, see Advanced Field Controls
relativeSubTable Sub-table displayed by association path, see Advanced Field Controls
authentication Read-only display of user information (such as the creator)
popOverSteps Step status
lineChart Line chart
tableChart Table chart

WARNING

Array with details, Array Inline, Multiple select, Object multiple select, Tags, Tag list, Static field, Updated ids, Series, Cron expression, Object ids, Document, Grouped grand child, Url, Entity Attributes and Comments from older versions of the documentation have no corresponding control in the current frontend; using them shows Unsupported displayType. Frontend plugins can register more controls through FrontendPluginManifest.fields.

# Transient Fields

A transient field is a field that does not exist on the object and is not saved to the database; set the field type to TRANSIENT_FIELD to create one. For transient fields:

  • The display type (displayType) must be filled in, otherwise saving fails with an error
  • The field value is entered by the user in the UI or provided by a Form Hook or Data Hook; the platform does not compute it
  • In extInfo you can use domainName to specify an object type (used with the object and objects controls to select objects of that type), or enumClass to specify an enum class (used with the enum control to generate dropdown options)
  • The "Editable" (editable) property controls whether the field is read-only

Transient fields are most often used in ACTION parameter forms. For example, in the parameter form of the built-in action that adds users to a group in batch, the user field is a transient field whose displayType is objects and whose extInfo is {"domainName": "User"}.

During development, it is recommended to keep the definitions of menus, forms, field groups and fields in CSV files and import them with the system as seed data, so that the system reads and updates these definitions automatically on startup. For importing seed data, see Data Import.

# Real System Usage Examples

Using the Customers object from the Quick Start tutorial as an example, the following is a set of CSV files for menus, forms, field groups and fields. The headers match the system's built-in seed data; columns whose names end with (*) are used to find and update existing records, and lines starting with ; are comments.

parent.name,label,icon,link,type,displaySequence,name(*),form.name,accessRequirement.name

; Top-level menu group: a menu group must have an accessRequirement, otherwise nobody can see it
NULL,客户管理,TeamOutlined,,MENU_GROUP,10,CRM,,USER

; Form menus: no accessRequirement; visibility is determined by the associated form
CRM,客户,UserOutlined,,FORM,1,Customers,List of customers,
CRM,VIP 客户,CrownOutlined,,FORM,2,VIP customers,List of VIP customers,
1
2
3
4
5
6
7
8
  • name(*) is the unique identifier of the menu; parent.name references the name of the parent menu, and NULL means a top-level menu
  • form.name references the name of the form; this is where the association between menu and form is established
  • accessRequirement.name is the name of an access requirement; the system ships with USER, DEVELOPER and ADMIN

TIP

Menus or fields with a smaller displaySequence are displayed first

# Form Definition CSV File

name(*),label,description,objectType.shortName(*),type.name(*),formHook.name,formHookTriggerFields,dataHook.name,extInfo,accessRequirement.name

List of customers,客户,,Customers,LIST,,,,,USER
List of VIP customers,VIP 客户,只显示 VIP 分组的客户,Customers,LIST,,,,"{""listForm"": {""searchConditions"": {""group"": {""columnKey"": ""group"", ""matchMode"": ""="", ""value"": ""VIP""}}}}",USER
Create customer,新建客户,,Customers,CREATE,customer_form_hook,group,,,USER
Update customer,编辑客户,,Customers,UPDATE,customer_form_hook,group,,,USER
Find customers,,,Customers,FINDER,,,,,USER
1
2
3
4
5
6
7
  • For type.name values, see Form Types
  • List of VIP customers sets a default filter condition in extInfo so that only customers in the VIP group are listed
  • The create and edit forms configure a Form Hook (customer_form_hook, which must be created in dynamic logic beforehand) and the trigger field group: when the customer group changes, the Form Hook is executed again
  • accessRequirement.name is USER, meaning all logged-in users can use these forms

# Form Field Group Definition CSV File

displaySequence,name(*),label,icon,form.name(*),helpText
1,c_customers_basic,基本信息,UserOutlined,Create customer,客户的基本资料
2,c_customers_extra,补充信息,ProfileOutlined,Create customer,
1,u_customers_basic,基本信息,UserOutlined,Update customer,客户的基本资料
2,u_customers_extra,补充信息,ProfileOutlined,Update customer,
1
2
3
4
5

Two groups, "基本信息" (basic information) and "补充信息" (additional information), are defined for the create form and the edit form respectively.

# Form Field Definition CSV File

form.name(*),fieldName(*),label,displaySequence,helpText,fieldType,nullable,group.name,extInfo,displayType,editable

; List
List of customers,name,客户名称,1,,STATIC_FIELD,,,,,
List of customers,companyName,公司,2,,STATIC_FIELD,,,,,
List of customers,group,客户分组,3,,STATIC_FIELD,,,,,
List of VIP customers,name,客户名称,1,,STATIC_FIELD,,,,,
List of VIP customers,companyName,公司,2,,STATIC_FIELD,,,,,

; Create
Create customer,name,客户名称,1,,STATIC_FIELD,,c_customers_basic,,,
Create customer,contactInfo,联系方式,2,手机号或邮箱,STATIC_FIELD,,c_customers_basic,,,
Create customer,group,客户分组,3,,STATIC_FIELD,,c_customers_basic,,,
Create customer,companyName,公司,4,,STATIC_FIELD,Y,c_customers_extra,,,
Create customer,position,职位,5,,STATIC_FIELD,Y,c_customers_extra,,,
Create customer,birthday,生日,6,,STATIC_FIELD,Y,c_customers_extra,,,

; Edit: customer name is read-only
Update customer,name,客户名称,1,,STATIC_FIELD,,u_customers_basic,"{""meta"": {""updatable"": false}}",,
Update customer,contactInfo,联系方式,2,手机号或邮箱,STATIC_FIELD,,u_customers_basic,,,
Update customer,group,客户分组,3,,STATIC_FIELD,,u_customers_basic,,,
Update customer,companyName,公司,4,,STATIC_FIELD,Y,u_customers_extra,,,
Update customer,position,职位,5,,STATIC_FIELD,Y,u_customers_extra,,,
Update customer,birthday,生日,6,,STATIC_FIELD,Y,u_customers_extra,,,

; Search
Find customers,name,客户名称,1,,STATIC_FIELD,,,,,
Find customers,group,客户分组,2,,STATIC_FIELD,,,,,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  • form.name together with fieldName locates a field definition
  • nullable set to Y means the field can be left empty in the form
  • group.name references a field group defined in the previous section and places the field in that group
  • The name field in the edit form is made read-only through meta.updatable in extInfo

# Master-Detail Form Definition

A form of type MASTER_DETAIL_LIST is displayed in a left-right layout, and the layout is fixed:

  • The left side is a tree of the associated object, 500px wide. The object needs a parent field to express the hierarchy; the node title is taken from the object's label field (labelField), and sibling nodes are sorted by displaySequence. When the form has a Data Hook, the tree data is returned by the Data Hook
  • After you click a tree node, the right side shows the object's edit (UPDATE) form with "Save", "Delete" and "Create" buttons; clicking "Create" switches the right side to the create (CREATE) form

The System Config > UI > Menus page is a master-detail form.

Tree node icons

If the object has an icon field whose value is an antd icon name (e.g. SortAscendingOutlined), the icon is displayed in front of the tree node.

The Simple list on the left side from older versions and the detailFormType / detailField / detailUpdatable settings no longer take effect as of 1.0.

# Form extInfo Support

A form's extInfo is a piece of JSON used to customize the form's extended properties. The time placeholders from Dynamic Match Conditions can be used in extInfo; they are replaced before being returned to the frontend.

# Common Properties

{
    /** Form title. Used only when the form's label (display name) is empty; if both are empty, the translated domain name is shown */
    "domainTitle"?: string;
    /** Whether the fields of the form are laid out horizontally (label and input on the same line) */
    "horizontal"?: boolean;
}
1
2
3
4
5

# LIST Form Properties

{
    /** Data refresh mode. Only realtime currently takes effect: the list subscribes to data changes and refreshes in real time; any other value is the same as not setting it */
    "dataRefreshMode"?: "realtime";

    /** Name of the create form used when clicking the "Create" button at the top right of the list; if not set, the CREATE form of the domain is used */
    "createFormName"?: string;

    /** Name of the update form used when clicking the row "Update" link; if not set, the UPDATE form of the domain is used */
    "updateFormName"?: string;

    /** Name of the finder form used by the search panel above the list; if not set, the FINDER form of the domain is used */
    "finderFormName"?: string;

    "listForm"?: {
      /** Whether to hide the search panel above the list */
      "disableSearchPanel"?: boolean;
      /** Default filter conditions, in the same format as dynamic filter conditions; a condition on the same key entered by the user in the search panel overrides the one here */
      "searchConditions"?: {
        "fieldName": {
          "columnKey": "fieldName",
          "matchMode": "=",
          "value": xxx
        }
      };
    };

    /** Whether inline editing refreshes other columns according to the form field's decides (decides does not take effect in the current version) */
    "enableRefreshColumn"?: boolean;

    /** Width of the operations column, default 120 */
    "operationsColumnWidth"?: number;

    /** Overrides the button permissions of the list; only affects whether buttons are shown, the backend still checks domain permissions; create set to false hides the "Create" button */
    "permissions"?: {
      "create"?: boolean;
      "view"?: boolean;
      "update"?: boolean;
      "delete"?: boolean;
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# Default Filter Conditions

A list form can set default filter conditions through listForm.searchConditions in extInfo; users cannot see these conditions in the UI. The condition format is the same as the conditions of Dynamic Filter:

// The default filter conditions of a list form go into extInfo.listForm.searchConditions
{
  "listForm": {
    "searchConditions" : {
      // key is the column name: status
      "status": {
        // The target column to filter
        "columnKey": "status",
        // Match rule: equals
        "matchMode": "=",
        // Target value to match: SUCCESS
        "value": "SUCCESS"
      },
      // key is the column name: type
      "type": {
        // The target column to filter, same as the key in the previous line
        "columnKey": "type",
        // Match rule of the filter: isOneOf (is one of the values)
        "matchMode": "isOneOf",
        // Target values of the filter: [FINDER, UPDATE]
        "value": [
          "FINDER",
          "UPDATE"
        ]
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

WARNING

  • Default filter conditions are only appended when the frontend requests list data; if the user enters a condition on the same field in the search area, it overrides the condition here. The list on the right side of a TREE_LIST and lists embedded as sub-tables do not read this setting. It is not an access control mechanism; to restrict data access, use object permissions or a Data Hook
  • conditions written at the top level of extInfo in older versions no longer takes effect as of 1.0 and must be rewritten into listForm.searchConditions

# TREE_LIST Form Properties

A TREE_LIST form shows a tree on the left and a list on the right; clicking a tree node filters the list by that node. treeTable.domainFilterField must be configured, otherwise the page only shows domainFilterField is not defined:

{
  "treeTable": {
    // Field name on the list object that points to the tree object; the field must be a field of this form;
    // the type of the tree object is determined by the associated type of this field
    "domainFilterField": "category",
    // Optional: field names on the tree object, displayed as search conditions above the tree;
    // the tree is loaded by these fields (equality match) only after all of them are filled in
    "treeFilterFields": ["catalog"]
  }
}
1
2
3
4
5
6
7
8
9
10

# IFRAME Form Properties

{
  // Address of the embedded page
  "url": "https://example.com/report"
}
1
2
3
4

# MASTER_DETAIL_LIST Form Properties

{
  /** MASTER_DETAIL_LIST forms currently have no configurable extInfo properties. */
  /** The left side is always the object tree, and the right side is always the UPDATE / CREATE form of that object. */
  /** The legacy detailFormType, detailField and detailUpdatable properties no longer take effect. */
}
1
2
3
4

# DASHBOARD Form Properties

{
  /** DASHBOARD forms currently have no configurable extInfo properties; the legacy refreshInterval no longer takes effect. */
}
1
2

# Form Field extInfo Support

A form field's extInfo is also a piece of JSON, used to customize the field's extended properties.

# Common Properties

The extended properties that can be used in the extInfo of fields of all types are as follows

{
  // Hides the field label and shows only the control itself
  "hideLabel"?: boolean;

  // CSS styles of the field label and of the read-only value, e.g. {"color": "#cf1322"}
  "labelStyle"?: object;
  "valueStyle"?: object;

  // meta overrides the metadata of the form field generated automatically by the system, or supplements some properties such as title, dataIndex, editable, updatable, elementType, etc.
  // At runtime, the system overrides or supplements the automatically generated metadata of the form field with the properties in meta
  "meta"?: {
      // Field name
      "key": string;
      // Field display name
      "title": string;
      // Name of the field in the form; should be the same as key
      "dataIndex": string;
      // Whether the field is editable in create forms; false renders it read-only
      "editable"?: boolean;
      // Whether the field is editable in update forms; false renders it read-only
      "updatable"?: boolean;
      ...
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Numeric Fields

The integer, int, long and decimal controls support the following properties (suffix only applies to these controls; percentage always shows %, and currency does not read suffix):

{
  // Minimum and maximum values; an error is shown when exceeded
  "min": 0,
  "max": 100,
  // Unit displayed after the input box
  "suffix": "元"
}
1
2
3
4
5
6
7

# file Field

{
  /** The file, fileList, image and video controls currently do not read extInfo. */
  /** The legacy accept, maxSizeMB, maxCount and totalMaxSizeMB properties no longer take effect. */
}
1
2
3

# code Field

When displayType is a code-type control such as code, json or markdown, the following extInfo sets the syntax highlighting language

{
  /** Syntax highlighting language used when the code editor control is shown */
  /** If not set, the field's display type (code, json, markdown, etc.) is used */
  "codeLanguage"?: "css" | "javascript" | "markdown" | "groovy" .....,
}
1
2
3
4

# object Field

For object select controls (object, objects), the following extInfo can be used:

{
    /** Filter conditions for the candidate options
     * When the control loads, the first 20 records matching these conditions are queried as the default options; the conditions are also applied to keyword search
     */
    "defaultOptionsCondition"?: {
        "fieldName" : {
            /** Value to match */
            "value": xxxx,
            /** Name of the field to match; supports dot (.) notation to reference a field of an associated object
             * e.g. organization.name refers to the name field of the organization field
             */
            "columnKey": "xxx",
            /** Match rule */
            "matchMode": matchMode
        }
    },
    /** Maximum number of candidates returned by keyword search, default 20 */
    "objectOptionsLimit"?: number,
    /** Shows "Create" and "Edit" buttons at the bottom of the dropdown for creating the associated object directly. In the current version only "Create" of the single-select control works */
    "enableObjectOperations"?: boolean,
    /** Query conditions for the default field values of the create form opened by the "Create" button above; each key is the name of an object-type field of the associated domain, and the first matching record is used */
    "createFormDefaultValueConditions"?: {
        "fieldName": { "columnKey": "xxx", "matchMode": "=", "value": xxx }
    },
    /** Overrides the properties of fields in the create form above, e.g. {"owner": {"disabled": true}} */
    "overwriteCreateFormFieldProps"?: object
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# One-to-Many Object Field

When displayType is array (a one-to-many object field), the following extInfo defines how the associated list is displayed

{
  /** Name of the form used to display the list of associated objects; if not set, the LIST form of the associated domain is used */
  "displayForm"?: "Form used to display the list of objects"
}
1
2
3

# Sub-table Field

For the configuration when displayType is subTable or relativeSubTable, see Advanced Field Controls

// 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
Last Updated: 9/24/2026, 2:27:35 PM