Skip to main content

Advanced UI schema

This page covers dynamic behavior in UI schema, explaining how to make forms react to user input using rules and conditions.

You’ll learn how to:

  • Show or hide elements conditionally.
  • Enable or disable fields dynamically.
  • Patch labels and options using APPLY rules.

πŸ’‘ If you’re new to UI schema, start with Designing the UI schema.

Rules overview​

Rules let you change the form layout or behavior based on data entered by the user.
They’re attached to any UI schema element through the rule property.

Supported effects​

RuleBehavior when condition is trueBehavior when condition is false
SHOWShows the elementHides the element
HIDEHides the elementShows the element
ENABLEEnables the elementDisables the element
DISABLEDisables the elementEnables the element
APPLYDynamically patches UI properties (labels, options, etc.)No changes applied

In a nutshell:

  • Use rules to make forms dynamic and context-aware.
  • SHOW, HIDE, ENABLE, and DISABLE control visibility and state,
  • while APPLY lets you adjust labels, options, and other UI properties on the fly.

Visibility effect (SHOW / HIDE)​

Use these rules to control whether a field or section is visible based on form data.
This is useful for revealing optional sections, toggles, or advanced settings.

{
"type": "Control",
"scope": "#/properties/ssn",
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#/properties/country",
"schema": { "const": "USA" }
}
}
}

State effect (ENABLE / DISABLE)​

These rules control whether a field is editable depending on user input or permissions.
They are often used to lock or unlock inputs dynamically.

{
"type": "Control",
"scope": "#/properties/comments",
"rule": {
"effect": "ENABLE",
"condition": {
"scope": "#/properties/allowComments",
"schema": { "const": true }
}
}
}

APPLY rules​

APPLY rules dynamically modify UI schema properties based on conditions. This rule lets you patch UI schema properties (like label, options, or enabled), depending on form state.

Conditions​

Conditions define when a rule is triggered. You can express simple or complex logic depending on your needs.

Schema condition (most common)​

Validates a field value against a JSON Schema snippet.

{
"scope": "#/properties/country",
"schema": { "const": "USA" }
}

Use:

  • const for equality checks
  • enum, minimum, pattern, etc., for more advanced validation

Logical conditions (AND / OR)​

Combine multiple checks to express advanced logic.

{
"type": "AND",
"conditions": [
{ "scope": "#/properties/isVIP", "schema": { "const": true } },
{ "scope": "#/properties/orders", "schema": { "minimum": 10 } }
]
}
{
"type": "OR",
"conditions": [
{ "scope": "#/properties/tier", "schema": { "const": "gold" } },
{ "scope": "#/properties/tier", "schema": { "const": "platinum" } }
]
}

APPLY rule examples​

Single outcome (basic APPLY rule)​

{
"type": "Control",
"scope": "#/properties/quantity",
"rule": {
"effect": "APPLY",
"condition": {
"scope": "#/properties/inStock",
"schema": { "const": false }
},
"outcome": {
"enabled": false,
"label": "Quantity (Out of stock)"
}
}
}

Multi-case outcomes​

Evaluate multiple cases in order; the first match wins.
Provide a final fallback case without condition.

{
"type": "Control",
"scope": "#/properties/field",
"rule": {
"effect": "APPLY",
"cases": [
{
"condition": {
"scope": "#/properties/mode",
"schema": { "const": "basic" }
},
"outcome": {
"label": "Basic Field",
"options": { "multi": false }
}
},
{
"condition": {
"scope": "#/properties/mode",
"schema": { "const": "advanced" }
},
"outcome": {
"label": "Advanced Field",
"options": { "multi": true }
}
},
{
"outcome": {
"label": "Default Field"
}
}
]
}
}

Complex condition with logical operators​

{
"type": "Control",
"scope": "#/properties/discount",
"rule": {
"effect": "APPLY",
"condition": {
"type": "OR",
"conditions": [
{
"scope": "#/properties/isVIP",
"schema": { "const": true }
},
{
"type": "AND",
"conditions": [
{
"scope": "#/properties/orderCount",
"schema": { "minimum": 10 }
},
{
"scope": "#/properties/totalSpent",
"schema": { "minimum": 1000 }
}
]
}
]
},
"outcome": {
"options": {
"showUnfocusedDescription": true
}
}
}
}

Dynamic options (unset or override)​

{
"type": "Control",
"scope": "#/properties/password",
"options": { "format": "password" },
"rule": {
"effect": "APPLY",
"condition": {
"scope": "#/properties/showPassword",
"schema": { "const": true }
},
"outcome": { "options": { "format": null } }
}
}

πŸ’‘ Use outcome.options to tweak how a control renders without duplicating elements.

Common dynamic patterns​

Here are some frequent use cases for rules.

Show a section when a toggle is on​

{
"type": "Group",
"label": "Delivery settings",
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#/properties/delivery",
"schema": { "const": true }
}
},
"elements": [
{ "type": "Control", "scope": "#/properties/address" },
{ "type": "Control", "scope": "#/properties/window" }
]
}

Enable a field only for admins​

{
"type": "Control",
"scope": "#/properties/limit",
"rule": {
"effect": "ENABLE",
"condition": {
"scope": "#/properties/isAdmin",
"schema": { "const": true }
}
}
}

Change a label based on selection​

{
"type": "Control",
"scope": "#/properties/name",
"rule": {
"effect": "APPLY",
"cases": [
{
"condition": {
"scope": "#/properties/type",
"schema": { "const": "person" }
},
"outcome": { "label": "Full name" }
},
{
"condition": {
"scope": "#/properties/type",
"schema": { "const": "company" }
},
"outcome": { "label": "Company name" }
},
{ "outcome": { "label": "Name" } }
]
}
}

Adjust options based on other data​

{
"type": "Control",
"scope": "#/properties/region",
"rule": {
"effect": "APPLY",
"condition": {
"scope": "#/properties/country",
"schema": { "enum": ["US", "CA"] }
},
"outcome": {
"options": { "placeholder": "Pick a region (US/CA)" }
}
}
}

Troubleshooting and tips​

  • Rules are evaluated in order from top to bottom within each layout.
  • Use function-based conditions only for exceptional edge cases.
  • If rules don’t seem to apply, confirm that your scope paths match the JSON Schema.