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
APPLYrules.
π‘ 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β
| Rule | Behavior when condition is true | Behavior when condition is false |
|---|---|---|
SHOW | Shows the element | Hides the element |
HIDE | Hides the element | Shows the element |
ENABLE | Enables the element | Disables the element |
DISABLE | Disables the element | Enables the element |
APPLY | Dynamically patches UI properties (labels, options, etc.) | No changes applied |
In a nutshell:
- Use rules to make forms dynamic and context-aware.
SHOW,HIDE,ENABLE, andDISABLEcontrol visibility and state,- while
APPLYlets 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:
constfor equality checksenum,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.optionsto 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
scopepaths match the JSON Schema.