Conditional logic allows fields to be shown or hidden based on the values of other fields. Rules are stored as JSON in the conditional_logic column on wp_formforge_forms. PRO feature.
JSON Format (grouped — recommended)
The in-builder UI emits grouped rules — one entry per target field, with multiple conditions plus an AND/OR match mode:
[
{
"target": "f3",
"action": "show",
"match": "all",
"rules": [
{ "source": "f1", "operator": "equals", "value": "Business" },
{ "source": "f2", "operator": "greater_than", "value": "1000000" }
]
}
]JSON Format (flat — legacy)
The earlier flat shape is still accepted by both the JS runtime and the PHP server-side gate. Each entry is a single rule with its target inline:
[
{ "target": "f3", "action": "show", "source": "f1", "operator": "equals", "value": "Business" }
]This shape is what AI Insight split_form actions and pre-r3 REST imports produced. The in-builder editor normalizes it to the grouped shape on first edit, but legacy data continues to evaluate correctly without migration.
Entry Properties
| Property | Type | Description | |
|---|---|---|---|
target | string | Field ID to show/hide (e.g. "f3") | |
action | "show" | "hide" | show displays the field when the conditions pass; hide does the opposite |
match | "all" | "any" | AND vs OR across rules. Only used when rules is an array. Defaults to "all" |
rules | array | List of condition objects (grouped shape) | |
source / operator / value | strings | Inline rule fields (flat legacy shape) |
Condition Operators
| Operator | Description | Notes |
|---|---|---|
equals | Value equals the specified value | Case-sensitive string compare |
not_equals | Value does not equal the specified value | |
contains | Value contains the specified substring | |
not_contains | Value does not contain the specified substring | |
greater_than | Numeric value > specified value | Returns false if either side is non-numeric |
less_than | Numeric value < specified value | Returns false if either side is non-numeric |
is_empty | Value is empty | Value box ignored |
is_not_empty | Value is not empty | Value box ignored. Legacy alias not_empty is also accepted |
For multi-value inputs (multi-select, multi-checkbox) the source value is joined with newlines before evaluation, so contains checks work intuitively across selected options.
Frontend Runtime
assets/js/frontend.js reads the JSON from a block emitted by the renderer, then attaches change/input listeners on every input inside the form’s wrapper. Show/hide is applied by toggling data-hidden="true|false" on the wrapper div; CSS rules in frontend.css translate that to display:none.
Targets are located by data-field-id="" on the wrapper div, which class-field-types.php::render emits for every field. Sources are located by name="formforge_field_".
Server-Side Gate
includes/class-form-handler.php::compute_hidden_fields() runs the same evaluation against the POST payload before validation. Fields the rules say should be hidden are skipped from required-checking, sanitization, and the saved submission row — the visitor never knows the field existed, and a tampered or non-browser client cannot bypass it by simply posting a value.
The frontend data-hidden attribute is not trusted; only the JSON rules + the posted source values determine what the server treats as hidden.
—