Conditional Logic
Control field visibility dynamically based on user responses using enableWhen conditions. This powerful feature allows you to create adaptive forms that show only relevant questions.
Basic Concept
Fields with enableWhen are hidden by default and only appear when their conditions are met.
{
"id": "needs_followup",
"fieldType": "radio",
"question": "Do you need follow up?",
"options": [
{ "id": "needs_followup-option", "value": "Yes" },
{ "id": "needs_followup-option-2", "value": "No" }
]
},
{
"id": "follow_up",
"fieldType": "longtext",
"question": "Please provide more details",
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "needs_followup",
"operator": "equals",
"value": "needs_followup-option"
}
]
}
}
In this example, the follow_up field only appears when needs_followup equals the Yes option id ("needs_followup-option").
Structure
"enableWhen": {
"logic": "AND" | "OR",
"conditions": [
{
"targetId": "<field id>",
"operator": "equals" | "contains" | "includes" | "greaterThan" | "lessThan" | "greaterThanOrEqual" | "lessThanOrEqual",
"value": "<comparison value>"
}
]
}
Logic Types
AND: All conditions must be trueOR: At least one condition must be true
Operators
For fields with options (e.g. radio, dropdown, boolean, check, multiselectdropdown), comparisons are done against the selected option id (the id inside the option object).
| Operator | Description | Works With |
|---|---|---|
equals | Exact match | Text fields (exact string match), selection fields (option id match) |
contains | Substring match (case-insensitive, word-boundary aware) | Text fields |
includes | Array contains value (string compare) | check, multiselectdropdown, ranking |
greaterThan | Numeric comparison > | Expression fields with numeric display formats |
lessThan | Numeric comparison < | Expression fields with numeric display formats |
greaterThanOrEqual | Numeric comparison >= | Expression fields with numeric display formats |
lessThanOrEqual | Numeric comparison <= | Expression fields with numeric display formats |
Note: Numeric operators (greaterThan, lessThan, etc.) only work with expression fields that have numeric displayFormat (currency, percentage, or number).
Examples
Simple Yes/No Condition
Show field when user selects "Yes":
{
"id": "has_insurance",
"fieldType": "radio",
"question": "Do you have health insurance?",
"options": [
{ "id": "has_insurance-option", "value": "Yes" },
{ "id": "has_insurance-option-2", "value": "No" }
]
},
{
"id": "insurance_provider",
"fieldType": "text",
"question": "Insurance provider name",
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "has_insurance",
"operator": "equals",
"value": "has_insurance-option"
}
]
}
}
Multiple Conditions (AND)
Show field when ALL conditions are met:
{
"id": "birth_year",
"fieldType": "text",
"question": "Year of birth"
},
{
"id": "age_years",
"fieldType": "expression",
"label": "Age (years)",
"displayFormat": "number",
"expression": "2024 - {birth_year}"
},
{
"id": "has_guardian",
"fieldType": "radio",
"question": "Do you have a legal guardian?",
"options": [
{ "id": "has_guardian-option", "value": "Yes" },
{ "id": "has_guardian-option-2", "value": "No" }
]
},
{
"id": "emergency_contact",
"fieldType": "text",
"question": "Emergency contact number",
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "age_years",
"operator": "lessThan",
"value": "18"
},
{
"targetId": "has_guardian",
"operator": "equals",
"value": "has_guardian-option"
}
]
}
}
This field appears only when age < 18 AND has_guardian = "Yes".
Multiple Conditions (OR)
Show field when ANY condition is met:
{
"id": "has_disability",
"fieldType": "radio",
"question": "Do you have a disability?",
"options": [
{ "id": "has_disability-option", "value": "Yes" },
{ "id": "has_disability-option-2", "value": "No" }
]
},
{
"id": "birth_year",
"fieldType": "text",
"question": "Year of birth"
},
{
"id": "age_years",
"fieldType": "expression",
"label": "Age (years)",
"displayFormat": "number",
"expression": "2024 - {birth_year}"
},
{
"id": "pregnant",
"fieldType": "radio",
"question": "Are you currently pregnant?",
"options": [
{ "id": "pregnant-option", "value": "Yes" },
{ "id": "pregnant-option-2", "value": "No" }
]
},
{
"id": "special_accommodations",
"fieldType": "longtext",
"question": "Describe your accessibility needs",
"enableWhen": {
"logic": "OR",
"conditions": [
{
"targetId": "has_disability",
"operator": "equals",
"value": "has_disability-option"
},
{
"targetId": "age_years",
"operator": "greaterThan",
"value": "65"
},
{
"targetId": "pregnant",
"operator": "equals",
"value": "pregnant-option"
}
]
}
}
This field appears if has_disability = "Yes" OR age > 65 OR pregnant = "Yes".
Numeric Range Conditions
Show field based on calculated values:
{
"fieldType": "text",
"id": "height_in",
"question": "Height (inches)",
"answer": ""
},
{
"fieldType": "text",
"id": "weight_lb",
"question": "Weight (lb)",
"answer": ""
},
{
"fieldType": "expression",
"id": "bmi",
"label": "BMI",
"expression": "({weight_lb} / ({height_in} * {height_in})) * 703",
"displayFormat": "number",
"decimalPlaces": 1,
"sampleDataFields": [],
"answer": ""
},
{
"fieldType": "html",
"id": "bmi_advice_overweight",
"htmlContent": "<p>Consider consulting a healthcare provider.</p>",
"iframeHeight": 90,
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "bmi",
"operator": "greaterThanOrEqual",
"value": "25"
},
{
"targetId": "bmi",
"operator": "lessThan",
"value": "30"
}
]
}
}
Shows when BMI is between 25 and 30.
Multi-Select Conditions
Check if a specific option is selected in a multi-select field:
{
"id": "allergies",
"fieldType": "check",
"question": "Which allergies apply?",
"options": [
{ "id": "allergies-option", "value": "Food" },
{ "id": "allergies-option-2", "value": "Medication" },
{ "id": "allergies-option-3", "value": "Other" }
]
},
{
"id": "allergy_details",
"fieldType": "longtext",
"question": "Describe your allergies",
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "allergies",
"operator": "includes",
"value": "allergies-option"
}
]
}
}
Shows when the Food option is selected.
Expression Field Conditions
Use calculated field results in conditions:
{
"id": "birth_year",
"fieldType": "text",
"question": "Year of birth",
"answer": ""
},
{
"id": "calculated_age",
"fieldType": "expression",
"label": "Your age",
"expression": "2024 - {birth_year}",
"displayFormat": "number",
"decimalPlaces": 2,
"sampleDataFields": [],
"answer": ""
},
{
"fieldType": "boolean",
"id": "adult_consent",
"question": "I consent to adult terms",
"options": [
{
"id": "boolean-option",
"value": "Yes"
},
{
"id": "boolean-option-1",
"value": "No"
}
],
"selected": null,
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "calculated_age",
"operator": "greaterThanOrEqual",
"value": "18"
}
]
}
}
Note: numeric comparisons (greaterThan, lessThan, etc.) only run against expression fields with a numeric displayFormat.
Complex Nested Logic
For complex scenarios, combine multiple conditions:
{
"id": "birth_year",
"fieldType": "text",
"question": "Year of birth"
},
{
"id": "age_years",
"fieldType": "expression",
"label": "Age (years)",
"displayFormat": "number",
"expression": "2024 - {birth_year}"
},
{
"id": "has_chronic_condition",
"fieldType": "radio",
"question": "Do you have a chronic condition?",
"options": [
{ "id": "has_chronic_condition-option", "value": "Yes" },
{ "id": "has_chronic_condition-option-2", "value": "No" }
]
},
{
"id": "has_medication_allergies",
"fieldType": "radio",
"question": "Do you have medication allergies?",
"options": [
{ "id": "has_medication_allergies-option", "value": "Yes" },
{ "id": "has_medication_allergies-option-2", "value": "No" }
]
},
{
"id": "prescription_info",
"fieldType": "longtext",
"question": "List your current prescriptions",
"enableWhen": {
"logic": "OR",
"conditions": [
{
"targetId": "age_years",
"operator": "greaterThan",
"value": "50"
},
{
"targetId": "has_chronic_condition",
"operator": "equals",
"value": "has_chronic_condition-option"
}
]
}
},
{
"id": "medication_allergies",
"fieldType": "longtext",
"question": "List any medication allergies",
"enableWhen": {
"logic": "AND",
"conditions": [
{
"targetId": "has_medication_allergies",
"operator": "equals",
"value": "has_medication_allergies-option"
}
]
}
}
Best Practices
1. Keep Logic Simple
Prefer straightforward conditions when you can—they’re easier to test and debug. Complex logic is fully supported, but it’s harder to maintain.
// Example: Clear and simple
"enableWhen": {
"logic": "AND",
"conditions": [
{ "targetId": "<field id>", "operator": "equals", "value": "<comparison value>" }
]
}
// Example: More complex (still supported)
"enableWhen": {
"logic": "OR",
"conditions": [
{ "targetId": "<field id>", "operator": "equals", "value": "<comparison value>" },
{ "targetId": "<field id>", "operator": "greaterThan", "value": "<comparison value>" },
{ "targetId": "<field id>", "operator": "contains", "value": "<comparison value>" },
{ "targetId": "<field id>", "operator": "lessThan", "value": "<comparison value>" }
]
}
2. Avoid Circular Dependencies
Don't create conditions that reference each other:
// ❌ Circular dependency
{
"id": "field_a",
"enableWhen": {
"conditions": [{ "targetId": "field_b", "operator": "equals", "value": "yes" }]
}
},
{
"id": "field_b",
"enableWhen": {
"conditions": [{ "targetId": "field_a", "operator": "equals", "value": "yes" }]
}
}
3. Test All Paths
Ensure all conditional paths work as expected in preview mode.
4. Provide Context
If you want to explain why something appeared, place an html field near it with explanatory text.
5. Use Appropriate Operators
Choose operators that match your data type:
- String values: Use
equals(exact) orcontains(case-insensitive word match) - Numbers: Use comparison operators (
greaterThan,lessThan, etc.) on numeric expression fields - Multi-select: Use
includes
Negative operators like notEquals / notContains are not currently supported.
Common Patterns
Age-Based Questions
{
"id": "birth_year",
"fieldType": "text",
"question": "Year of birth"
},
{
"id": "age_years",
"fieldType": "expression",
"label": "Age (years)",
"displayFormat": "number",
"expression": "2024 - {birth_year}"
},
{
"id": "pediatric_questions",
"enableWhen": {
"logic": "AND",
"conditions": [
{ "targetId": "age_years", "operator": "lessThan", "value": "18" }
]
}
}
Follow-Up Questions
{
"id": "symptoms",
"fieldType": "check",
"options": [
{ "id": "symptoms-option", "value": "Cough" },
{ "id": "symptoms-option-2", "value": "Fever" }
]
},
{
"id": "symptom_duration",
"question": "How long have you had these symptoms?",
"enableWhen": {
"logic": "AND",
"conditions": [
{ "targetId": "symptoms", "operator": "includes", "value": "symptoms-option" }
]
}
}
Conditional Disclaimers
{
"id": "risk_score",
"fieldType": "expression",
"label": "Risk score",
"displayFormat": "number",
"expression": "8"
},
{
"id": "risk_warning",
"fieldType": "html",
"htmlContent": "<div class='warning'>High risk detected...</div>",
"enableWhen": {
"logic": "OR",
"conditions": [
{ "targetId": "risk_score", "operator": "greaterThan", "value": "7" }
]
}
}
Debugging Tips
- Use Preview Mode: Test conditions in the editor's preview mode
- Check Field IDs: Ensure
targetIdmatches exactly (case-sensitive) - Verify Values:
equalsmatches exactly (selection fields compare option ids).containsis case-insensitive. - Start Simple: Build complex logic incrementally
Next Steps
- Field Types - Learn about all field types
- Expression Fields - Calculated fields for conditions
- Schema Format - Complete schema format