Build conditional question flows
On this page
Conditions decide whether a question appears, a price rule applies or an output message is shown. The same model is used throughout OpenQuoteStack. Begin with one branch and test both outcomes before combining groups.
Reveal stairs when there is no elevator
The Moving template already contains this pattern. In Questions, place the elevator yes/no field before the flights-of-stairs quantity. Select the stairs field and set its visibility to:
Show Flights of stairs
when Elevator available equals NoIn Prices, use the stairs quantity in a per-unit rule. The visibility condition removes stairs from the effective answers when an elevator is available; a hidden numeric answer does not contribute to pricing.
For template authors, the equivalent declarative condition is:
{ "field": "elevator", "op": "equals", "value": false }Use the boolean false, not the string "false". Equality is type-strict.
Combine criteria with AND
Suppose a handling fee applies only when the customer has a piano and no elevator. Add both conditions to an all / AND group:
{
"all": [
{ "field": "piano", "op": "equals", "value": true },
{ "field": "elevator", "op": "equals", "value": false }
]
}A rule condition can refer to any defined field. Field visibility is stricter: it may refer only to preceding questions. Moving a fee later in the rule list does not repair a field's forward visibility reference.
Use OR for alternative matches
For a fee that applies to either of two selected packages, use any / OR:
{
"any": [
{ "field": "package", "op": "equals", "value": "growth" },
{ "field": "package", "op": "equals", "value": "custom" }
]
}The package identifiers must exist in the choice field. The displayed package labels can be translated independently.
Choose the right operator
| Question | Operator | Example |
|---|---|---|
| Exact match | equals / not_equals | Package equals growth |
| Numeric boundary | gt, gte, lt, lte | Distance is at least 50 |
| A selected option | selected / not_selected | Add-ons includes oven |
| Substring or membership | contains / not_contains | A text value contains a term |
| No answer | empty / not_empty | Notes is not empty |
Zero and false are not empty. Empty strings, empty arrays and missing values are empty. Except for empty, missing values do not satisfy operators; not_equals is not a shortcut for “unanswered or different.”
Protect optional formula inputs
A formula referencing an optional field fails when that variable is absent. Guard the formula with the same condition that makes the input available, or make the input required when visible. Do not rely on an absent variable silently becoming zero.
For example, a stairs formula can use elevator equals false as its rule condition. If stairs are visible but optional, add floors not_empty as an AND criterion or supply a valid default. A simpler per-unit rule already skips a missing optional quantity.
Test a small truth table
For the piano/no-elevator fee, test all four combinations:
| Piano | Elevator | Fee applies |
|---|---|---|
| No | No | No |
| No | Yes | No |
| Yes | No | Yes |
| Yes | Yes | No |
Then hide and reveal a numeric question that previously had an answer. Confirm its old hidden answer does not affect the result. Preview validation and the explanation, not only the total.
See the condition contract for exact missing-value and array behavior.