Skip to main content

Conditional fields

A static dialog asks the user the same questions every time. A conditional dialog asks the right ones depending on what the user has already typed — show Bank details only when Payment method is bank_transfer, require Reason only when Status is cancelled, lock Account number in edit mode but allow editing in add mode.

Three flags on a column (or per-dialog override on a field) handle this:

FlagWhat it gates
visible_whenWhether the field shows at all. Hidden fields don't bind values at save.
required_whenWhether a value is mandatory.
disabled_whenWhether the field is read-only.

Each is a list of FieldCondition predicates — AND semantics, so every predicate must match for the rule to fire.


The FieldCondition shape

{ field = "STATUS", value = "CANCELLED" }
# or with a list — any matching value triggers the rule
{ field = "PAYMENT_METHOD", value = ["bank_transfer", "sepa"] }
PropertyWhat it does
fieldThe other dialog field whose live value gates this rule. Referenced by its column name (case-insensitive).
valueThe expected value, or a list of values (any one matches).

Multiple conditions in the list = AND. To OR conditions, declare two separate fields with the same conditional rule (or use a single condition with a list of values).


Where to set them

Two layers carry the same flags:

LayerWhen
Column hint (Columns tab)The rule applies to every dialog that surfaces this column. The right default — most fields behave the same across dialogs.
Per-dialog field (Inspector → Conditional rules)The rule applies only to this specific dialog. Use when one dialog needs different behaviour from the column-wide default.

The runtime evaluates the per-field override first; if blank, it falls back to the column-hint setting.


The Inspector's Conditional rules section

When a field is selected in the Dialog builder's canvas, the Inspector's Conditional rules section lets you add predicates for any of the three flags.

Inspector · IBAN · Conditional rulesvisible_when (AND)FieldPAYMENT_METHOD ▾Valuebank_transfer, sepa+ Add conditionrequired_when (AND)FieldPAYMENT_METHOD ▾Valuebank_transfer+ Add conditiondisabled_when (AND)FieldSTATUS ▾ValueLOCKED, ARCHIVED+ Add condition
SectionWhat it does
visible_whenShow the field only when every predicate matches. Empty = fall back to the static hidden flag.
required_whenRequire the field only when every predicate matches. Empty = required decides.
disabled_whenLock the field only when every predicate matches. Empty = disabled decides.

The runtime re-evaluates the rules on every form change — type in PAYMENT_METHOD, the dependent fields appear / disappear / lock without a round-trip.


Worked examples

Show fields conditionally

A Payment dialog with these columns:

  • PAYMENT_METHOD — ENUM dropdown (cash, bank_transfer, sepa, card).
  • IBAN, BIC — only relevant for bank_transfer / sepa.
  • CARD_LAST4 — only relevant for card.

The rules:

Columnvisible_when
IBANfield=PAYMENT_METHOD, value=[bank_transfer, sepa]
BICfield=PAYMENT_METHOD, value=[bank_transfer, sepa]
CARD_LAST4field=PAYMENT_METHOD, value=card

The user picks cashIBAN / BIC / CARD_LAST4 all disappear. Switches to bank_transferIBAN and BIC appear, CARD_LAST4 stays hidden.

Require a reason on cancel

A Subscription dialog where CANCELLATION_REASON should only be required when STATUS = CANCELLED:

Columnrequired_when
CANCELLATION_REASONfield=STATUS, value=CANCELLED

The field is always visible (no visible_when), always editable (no disabled_when), but the Save button refuses to submit until the field has a value if STATUS is CANCELLED. For any other status, an empty CANCELLATION_REASON saves fine.

Lock fields in edit mode for certain rows

A Customer dialog where the TAX_ID should be editable only when the row is being created (not edited):

Columndisabled_when
TAX_ID(rule based on some marker that distinguishes add from edit — typically a row-level flag like IS_FROZEN)

When the row's IS_FROZEN = Y, the TAX_ID field is read-only. Otherwise editable. The form is the same; the behaviour adapts to the row.

For a strict "lock when editing, allow when adding" without a row marker, use the per-tab hide_on_add / hide_on_edit flags or the per-field column-hint disabled (which locks everywhere).

Multi-condition AND

A Invoice dialog where EARLY_PAYMENT_DISCOUNT should be required only when both STATUS = OPEN AND AMOUNT_DUE > 1000:

The first condition is straightforward (STATUS = OPEN). The second isn't — FieldCondition checks equality, not comparison. For numeric thresholds use a normalised flag column (e.g. HIGH_VALUE = Y computed in the read query) and condition on it.

Sometimes the cleanest move is a dictionary rule with a default value that the user can override — let the form compute the discount and treat the field as informational rather than gating its save.


Visible vs hidden — what happens at save

A field hidden by visible_when is excluded from the save payload. The dialog Save sends only the values of currently-visible fields. The hidden field's database column either:

  • Keeps its existing value (UPDATE — the missing field is omitted from the SET clause).
  • Defaults to NULL or its DB default (INSERT — the missing field is omitted from the INSERT column list).

This is the intent of conditional visibility — a field that isn't relevant to the user's choice shouldn't accidentally overwrite the database with stale or default data.

For genuinely hidden-but-required fields (e.g. a :LOGIN_USER bound at save time), use parameter binding on the _post / _put query, not a dialog field.


Validation order

When the user clicks Save, the dialog checks fields in this order:

  1. Visible fields with required = true (or required_when matching) must have a value.
  2. Each field's dictionary rule fires (BOOLEAN, ENUM, LOOKUP, format).
  3. The Save dispatch fires the action chain.

A failing required check shows an inline error on the field, blocks the save, doesn't fire the action chain.


Common pitfalls

MistakeSymptomFix
visible_when references a field not on any dialog tab.The dependent field never appears (the source field's value is undefined, no condition matches).Add the source field to the dialog, or change the condition.
visible_when on a key field.The user adds a row with no key — the INSERT fails.Key fields should never be conditionally hidden. Lock them, don't hide.
required_when matches but visible_when doesn't.The field is required AND hidden — the user can't fill it but the save refuses.Sync the two conditions, or drop the required_when.
Value list with a typo.The rule never matches.Verify the enum values match exactly (case-sensitive).
Condition references the field itself.Infinite loop guard kicks in; the rule is ignored.Conditions reference other fields, never self.

What's next

  • Actions and lifecycle — fire actions when the form loads, saves or is cancelled.
  • Dialog builder — the Visual Builder where you set these rules per field.
  • Columns — set the same rules at the column level for screen-wide defaults.