Skip to main content
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"
}
PropertyDescription
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 TypeRendered 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

EffectDescription
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:
PatternSchema
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:
OptionDescription
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"
        }
      ]
    }
  }
}
PropertyDescription
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