The UI Schema defines how to render a dynamic form — the layout structure, controls, conditional visibility rules, and custom options. It follows the JSON Forms UI Schema specification.
Structure
A UI Schema is a tree of elements . Each element has a type that determines how it behaves:
Layouts — Container elements that organize other elements
Controls — Elements that render input fields bound to schema properties
{
"type" : "VerticalLayout" ,
"elements" : [
{
"type" : "Control" ,
"scope" : "#/properties/firstName" ,
"label" : "First Name"
},
{
"type" : "Control" ,
"scope" : "#/properties/lastName" ,
"label" : "Last Name"
}
]
}
Layouts
Layouts organize controls and other layouts into a visual structure.
VerticalLayout
Arranges elements vertically, one below the other.
{
"type" : "VerticalLayout" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/firstName" },
{ "type" : "Control" , "scope" : "#/properties/lastName" }
]
}
HorizontalLayout
Arranges elements horizontally, side by side.
{
"type" : "HorizontalLayout" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/firstName" },
{ "type" : "Control" , "scope" : "#/properties/lastName" }
]
}
Group
Groups related controls together with an optional label.
{
"type" : "Group" ,
"label" : "Personal Information" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/firstName" },
{ "type" : "Control" , "scope" : "#/properties/lastName" }
]
}
Categorization
Organizes content into tabs or wizard-style steps. A Categorization contains multiple Category elements, each representing a step in the form.
{
"type" : "Categorization" ,
"elements" : [
{
"type" : "Category" ,
"label" : "Personal Info" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/personalInfo/properties/firstName" },
{ "type" : "Control" , "scope" : "#/properties/personalInfo/properties/lastName" }
]
},
{
"type" : "Category" ,
"label" : "Contact Info" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/contactInfo/properties/email" },
{ "type" : "Control" , "scope" : "#/properties/contactInfo/properties/phone" }
]
}
]
}
Categories correspond to steps in the schema. Each Category typically maps to a root-level schema property, enabling progressive disclosure as users complete each step.
ListWithDetail
Renders an array as a master-detail view — a list of items on one side and a detail form for the selected item.
{
"type" : "ListWithDetail" ,
"scope" : "#/properties/addresses" ,
"options" : {
"detail" : {
"type" : "VerticalLayout" ,
"elements" : [
{ "type" : "Control" , "scope" : "#/properties/street" },
{ "type" : "Control" , "scope" : "#/properties/city" }
]
}
}
}
Controls
Controls render input fields and bind them to schema properties.
Control
The Control element renders an input based on the schema type at the specified scope.
{
"type" : "Control" ,
"scope" : "#/properties/email" ,
"label" : "Email Address"
}
Property Description scopeJSON Pointer to the schema property (e.g., #/properties/email) labelDisplay label for the control (optional — derived from schema if omitted) optionsCustom options to modify control behavior
The renderer automatically selects the appropriate input type based on the schema:
Schema Type Rendered As stringText input string + format: "date"Date picker string + enumDropdown/select numberNumber input booleanCheckbox or toggle arrayList with add/remove
Rules
Rules control the visibility and enabled state of elements based on data conditions.
{
"type" : "Control" ,
"scope" : "#/properties/employerName" ,
"rule" : {
"effect" : "SHOW" ,
"condition" : {
"scope" : "#/properties/employmentStatus" ,
"schema" : { "const" : "employed" }
}
}
}
Effects
Effect Description SHOWShow the element when condition is true, hide otherwise HIDEHide the element when condition is true, show otherwise ENABLEEnable the element when condition is true, disable otherwise DISABLEDisable the element when condition is true, enable otherwise
Conditions
A condition specifies a scope (the property to evaluate) and a schema that the value must match.
{
"condition" : {
"scope" : "#/properties/country" ,
"schema" : { "enum" : [ "US" , "CA" ] }
}
}
Common condition patterns:
Pattern Schema Equals a value { "const": "value" }One of many values { "enum": ["a", "b", "c"] }Not empty { "minLength": 1 }
Options
The options property on controls allows you to customize behavior. These are standard JSON Forms options .
Array options
Options for array controls:
Option Description showSortButtonsShows buttons to reorder items elementLabelPropProperty to use as the label for each item in a list disableAddPrevents adding new items (renderer-specific) disableRemovePrevents removing items (renderer-specific)
{
"type" : "Control" ,
"scope" : "#/properties/documents" ,
"options" : {
"elementLabelProp" : "name" ,
"showSortButtons" : true
}
}
readonly
Renders the control as read-only.
{
"type" : "Control" ,
"scope" : "#/properties/accountId" ,
"options" : {
"readonly" : true
}
}
detail
For ListWithDetail layouts, specifies the UI Schema for the detail view.
{
"type" : "ListWithDetail" ,
"scope" : "#/properties/items" ,
"options" : {
"detail" : {
"type" : "VerticalLayout" ,
"elements" : [ ... ]
}
}
}
Custom options
The Enterprise API Suite extends JSON Forms with custom options for specific use cases.
dataSource
Specifies a data source for populating select options dynamically. You can optionally filter values using exclude.
{
"type" : "Control" ,
"scope" : "#/properties/country" ,
"options" : {
"dataSource" : "countries" ,
"exclude" : {
"restrictions" : [
{
"scope" : "citizenship"
}
]
}
}
}
Property Description dataSourceThe data source to fetch options from (e.g., "countries") exclude.restrictionsArray of restrictions to filter values from the data source exclude.restrictions[].scopeThe restriction scope (e.g., citizenship, residence, geolocation, phone)
Next steps
Rendering Implementation guidance and best practices.