Skip to main content

Rules Reference

A rule attaches to any UI schema element and conditionally changes how Prismatic displays that element based on other values in the form. Rules are how you build dynamic, responsive forms - hiding fields that don't apply, disabling inputs until a prerequisite is set, or stepping a wizard forward as the customer makes choices.

Rule shape

Add a rule property to any UI schema element:

Rule shape
{
"rule": {
"effect": "HIDE" | "SHOW" | "ENABLE" | "DISABLE",
"condition": {
"scope": "<JSON Pointer>",
"schema": { /* JSON Schema */ }
}
}
}

The rule evaluates the condition against the current form data. If the condition passes, the effect applies to the element.

Effects

EffectApplied when condition passes
SHOWThe element is displayed
HIDEThe element is hidden
ENABLEThe element is interactive
DISABLEThe element is visible but not editable

SHOW and HIDE are logical opposites. Use whichever reads most clearly - typically SHOW for the inclusion case ("show when a checkbox is checked") and HIDE for the exclusion case ("hide when a country is selected").

Condition

A condition consists of a scope - a JSON Pointer into the form's data - and a schema that the referenced data must match for the condition to pass.

scope

Use JSON Pointer syntax to reference another property in the form:

"scope": "#/properties/enableBidirectionalSync"

Use scope: "#" to reference the entire form data object. This is useful when your condition needs to check multiple properties at once with allOf, anyOf, or required.

schema

Any JSON Schema the referenced value must satisfy. Every JSON Schema keyword you'd use for field validation works here too.

Common patterns:

Exact value match:

condition.schema with const
{
"scope": "#/properties/country",
"schema": { "const": "United States" }
}

One of several values:

condition.schema with enum
{
"scope": "#/properties/region",
"schema": { "enum": ["EU", "EMEA"] }
}

Negation:

condition.schema with not
{
"scope": "#/properties/country",
"schema": {
"not": { "const": "United States" }
}
}

Numeric range:

condition.schema with minimum
{
"scope": "#/properties/quantity",
"schema": { "minimum": 10 }
}

Required property at the form root:

condition.schema with required
{
"scope": "#",
"schema": { "required": ["apiKey"] }
}

failWhenUndefined

By default, if the scope resolves to undefined (the customer hasn't filled that field in), the condition passes. Set failWhenUndefined: true on the condition to invert that behavior - the condition fails when the referenced value is missing:

failWhenUndefined
{
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#/properties/country",
"schema": { "const": "Canada" },
"failWhenUndefined": true
}
}
}

Use failWhenUndefined: true when a field should stay hidden until the customer has actively made a selection.

Rules on layout elements

Rules work on any UI schema element, not just controls. Attaching a rule to a Group, Category, or other layout hides or disables the entire subtree:

Hiding a whole group
{
"type": "Group",
"label": "Currency Configuration",
"elements": [
{ "type": "Control", "scope": "#/properties/currency" },
{ "type": "Control", "scope": "#/properties/exchangeRate" }
],
"rule": {
"effect": "HIDE",
"condition": {
"scope": "#/properties/country",
"schema": { "const": "United States" }
}
}
}

Complete example

Here's the pattern from Using JSON Forms broken out. The convertToUSD toggle appears only when the country is not "United States":

Conditional toggle
{
"type": "Control",
"scope": "#/properties/convertToUSD",
"options": { "toggle": true },
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#/properties/country",
"schema": {
"not": { "const": "United States" }
}
}
}
}

Patterns and tips

Show when a checkbox is checked

{
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#/properties/enableAdvanced",
"schema": { "const": true }
}
}
}

Disable until a required field has a value

{
"rule": {
"effect": "DISABLE",
"condition": {
"scope": "#/properties/apiKey",
"schema": { "type": "string", "minLength": 1 },
"failWhenUndefined": true
}
}
}

Because the effect is DISABLE, the field stays enabled while the condition fails (missing apiKey) and becomes disabled once the condition passes. Invert the effect if you want the opposite:

{
"rule": {
"effect": "ENABLE",
"condition": {
"scope": "#/properties/apiKey",
"schema": { "type": "string", "minLength": 1 },
"failWhenUndefined": true
}
}
}

Chain multiple conditions with allOf

condition.schema accepts the full JSON Schema vocabulary, so you can combine checks:

{
"rule": {
"effect": "SHOW",
"condition": {
"scope": "#",
"schema": {
"allOf": [
{ "properties": { "country": { "const": "Canada" } } },
{ "properties": { "taxExempt": { "const": false } } }
]
}
}
}
}

When rules aren't enough

Rules handle declarative visibility and enablement well, but they can't run arbitrary logic, make network calls, or produce error messages with custom text. When you need those, use a validator data source to inspect the form's output and return a follow-up JSON Forms config variable with the rules (and errors) you compute in code.