Conditional Logic
Show, hide, or disable form sections and gate delivery actions with conditions evaluated in the browser and again on the server.
Conditional Logic extends Forms in two places:
- a Conditional Logic block controls a group of fields; and
- an Execute if section can gate individual form and integration actions.
Both use the same rule builder: choose whether All or Any rules must match, then choose a source field, operator, and comparison value.
Forms is required
Without XPAC Forms, this add-on registers neither its block nor its editor and submission hooks.
Conditional form sections
Insert a Conditional Logic block inside a form and place the fields or content it should control inside the block.
Choose Show, Hide, or Disable, then choose All or Any.
Test both matching and non-matching paths, including leaving optional sources empty.
| Appearance | When the rule matches | When it does not match |
|---|---|---|
| Show | Section is visible and enabled. | Section is hidden and its controls are disabled. |
| Hide | Section is hidden and its controls are disabled. | Section is visible and enabled. |
| Disable | Section remains visible but its controls are disabled. | Section remains visible and enabled. |
Disabled or hidden controls are removed from validation and from the accepted submission. Their answers do not reach entries, notifications, or integrations. Nested conditional sections are resolved repeatedly to a stable result rather than being limited to a fixed nesting depth.
Conditional sections start with visibility: hidden and are revealed only after
their rule is evaluated, avoiding a flash of protected content. The runtime uses
Forms' per-form lifecycle, so a complete form inserted after page startup receives
the same behavior as an initial form.
A condition is not an authorization boundary
Rule names, operators, and comparison values are serialized into published form markup so the browser can react immediately. A visitor can inspect them. Never put a password, private token, permission decision, or other secret into a condition. Enforce authorization in server-side application code.
Password and confirmation controls are not offered as condition sources. A legacy or externally written condition that names one is treated as unresolvable in both the browser and server; the credential is never compared with a value stored in form content or settings.
Comparisons
| Operator | Behaviour |
|---|---|
| is / is not | Case-insensitive scalar equality; choice groups match selected values. |
| greater / greater or equal | Numeric comparison. |
| lower / lower or equal | Numeric comparison. |
| contains | Substring match for text, or selected-value membership for a multi-value answer. |
| starts with / ends with | Case-insensitive text prefix or suffix. |
For numbers, use numeric fields and values. For checkboxes, radio groups, and selects, choose one of the field's actual option values. An optional field that is present in the form but unanswered remains a resolvable empty answer on the server, so browser and server use the same rule inputs.
Gate an action
Action settings contributed by Forms and its integration add-ons gain an Execute if section. It can gate notification emails, redirects, messages, provider updates, Webhooks, Zapier, Submission to Post, UserAuth operations, and other actions that use the Forms action-status filter.
An action with no condition follows its normal enabled status. A valid condition must match before that one action runs; sibling actions and entry storage are independent.
Keep the add-on active while gated actions exist
The condition is evaluated by this add-on. If Conditional Logic is deactivated, other add-ons no longer receive its status filter and their enabled actions run without that gate. Treat the plugin as a runtime dependency of every form that uses action conditions.
Stale and malformed rules
The editor shows a warning when a saved dependency points to a renamed or deleted field, or to a provider block whose plugin is inactive. Repair the rule before publishing.
At runtime:
- an unresolvable rule is non-matching;
- an All group fails when any dependency is unresolvable;
- an Any group may still match another resolvable dependency;
- an action condition with malformed rows or an invalid relation returns disabled;
- malformed JSON or shape on one conditional block hides and disables that block without preventing other form sections from initializing.
For a Show section, non-matching means hidden. For Hide or Disable, non-matching leaves the section usable. This preserves the configured appearance semantics while preventing a broken rule from unexpectedly executing a gated action.
When a visible field is removed by an outer condition, its name becomes unavailable to every later nested pass and action check. Conditional Logic and Multi-Step Form also keep independent disable ownership, so making one condition visible cannot re-enable a field that a skipped step still owns.
Provider values
Some add-ons expose a provider value rather than a normal form field. For example, User Targeting can expose the resolved visitor country. Those values appear in the same rule builder when their provider is active and publishes both browser and server data. If the provider disappears, the dependency becomes unresolvable and the editor warns.
Stored shape
The block stores appearance, relation, and dependencies:
{
"appearance": "show",
"relation": "and",
"dependencies": [
{
"name": "plan",
"operator": "=",
"value": "business"
}
]
}An action stores the same condition object without appearance:
{
"condition": {
"relation": "and",
"dependencies": [
{ "name": "plan", "operator": "=", "value": "business" }
]
}
}The server re-evaluates wrapper visibility during
xpac_forms_initialize_submission and gates actions through
xpac_forms_action_item_status. xpac_forms_submission_invisible_blocks can add
field names that another Forms extension has made unavailable; callbacks must be
idempotent because nested conditions can require multiple passes.
The front end exposes form.xpacForm.condition.check() and
form.xpacForm.condition.initializeField() for add-ons that use the same runtime
comparison rules.