Skip to main content

JEXL in JSON Schema

tSM allows you to embed JEXL expressions directly inside a form’s JSON Schema. This enables dynamic UI behavior — such as hiding fields, making them read-only, or changing layout elements — based on runtime context or form data.

These expressions are evaluated by the form engine at runtime, not during design.

Where Can You Use JEXL in Schema?

JSON FieldPurposeExample
config.hiddenConditionally hide a field or layout${$context.form.type \== 'B2C'}
readonlyMake a field non-editable based on logic${$context.user.role \== 'agent'}
config.collapsibleDynamically collapse/expand a section${$context.form.isAdvanced}
validationMessagesAdd conditional validations${$context.form.age \< 18}
defaultSet dynamic default valueaddTime(now(), 1, 'days')

How It Works

JEXL expressions must be wrapped in ${...} and provided as a string.

"config": {
  "hidden": "${$context.form.customerType != 'B2B'}"
}

The form engine detects the ${...} pattern and evaluates the content using the current runtime context.

Field-Level Example

"email": {
  "type": "string",
  "widget": {
    "type": "text"
  },
  "readonly": "${$context.user.role != 'admin'}",
  "config": {
    "tooltip": "Editable only by admins"
  }
}

This field is read-only unless the user has the admin role.

Layout-Level Example

{
  "type": "layout",
  "widget": { "type": "dtl-fluent-card" },
  "config": {
    "header": "Internal Notes",
    "collapsible": true,
    "hidden": "${!$context.user.hasInternalAccess}"
  },
  "items": ["internalNote"]
}
  • A collapsible card layout
  • Only visible to users with a custom access flag

Validation Rule Example

"discountRate": {
  "type": "number",
  "widget": { "type": "number" },
  "validationMessages": {
    "custom": {
      "expression": "${$context.form.clientType == 'VIP' && ($value < 10 || $value > 50)}",
      "message": "VIP clients must have a discount between 10 and 50"
    }
  }
}

This adds a custom validation message when a VIP client’s discount is outside the allowed range.

Combined Example

"layout": [
  {
    "type": "layout",
    "widget": { "type": "dtl-fluent-columns" },
    "config": {
      "columns": [
        {
          "width": 6,
          "content": ["firstName"],
          "hidden": "${$context.form.userType == 'guest'}"
        },
        {
          "width": 6,
          "content": ["lastName"]
        }
      ]
    }
  }
]

In this example, the left column is hidden when the user is a guest.

Important Notes

  • Always wrap JEXL expressions in ${ ... }
  • The engine only evaluates strings prefixed with ${
  • You can nest expressions in any config object
  • Use the JEXL Debug Console to test values

When to Use It

Use CaseBest Practice
Show/hide fields or layoutsconfig.hidden with JEXL
Disable field inputreadonly based on user or form state
Set initial values dynamicallyUse default with JEXL expression
Advanced layout behaviorsCollapsing or tab logic with context