Skip to content

Conditional logic

Phase 7 evaluates the same show/hide and action rules on the server (ConditionEngine) and in the browser (assets/frontend/js/form.js).

Disabled or empty groups are always true: the field stays visible and the action runs.

Group shape

Field and action conditions is an object, not a list:

json
{
  "enabled": false,
  "effect": "show",
  "logic": "all",
  "rules": [
    {
      "id": "rule_a1b2c3d4",
      "field": "kind",
      "operator": "is",
      "value": "business"
    }
  ]
}
  • effect: show | hide — fields only. Actions ignore effect; matches() means “run this action”.
  • logic: all | any
  • Rule IDs are stable (rule_ + 8 hex)
  • A legacy list of {field, operator, value} rules is normalized to an enabled show / all group

Operators

IDNeeds value
isyes
is_notyes
containsyes
not_containsyes
starts_withyes
ends_withyes
is_emptyno
is_not_emptyno
greater_thanyes
less_thanyes

String compares are case-insensitive. greater_than / less_than require numeric values. Unknown operators never match. Add-ons can append catalogue entries with ad_form_condition_operators.

Evaluation

  1. Fields are walked in definition order.
  2. Rules whose field equals the current field key are skipped (no self-reference).
  3. Hidden fields count as empty for later rules (cascade).
  4. Submit fields are always visible.
  5. Hidden fields skip required validation and are omitted from the stored payload and submission_meta.
  6. ActionRunner skips an action when matches() is false (debug log, not a failure).

Frontend

Enabled groups are serialized on the wrap as data-conditions. Required fields keep data-required="1" even when hidden so JS can restore required after they become visible.

Hidden wraps get class is-conditionally-hidden and the hidden attribute. Controls are disabled so classic POST drops them. AJAX collectValues(form, true) skips hidden wraps.

PHP

  • Dingfelder\AdForm\Conditions\ConditionEngineInterface
  • Dingfelder\AdForm\Conditions\ConditionEngine
  • Dingfelder\AdForm\REST\ConditionsController

SubmitService, ActionRunner and FormRenderer take an optional ConditionEngineInterface (constructor signatures stay compatible). The container injects the engine.

REST catalogue: GET /wp-json/ad-form/v1/conditions (capability edit_ad_form_forms).

Digitale Lösungen. Persönlich. Zukunftssicher.