Form Logic Overview
MQUAD surveys support four kinds of form logic. They look similar — all four are small expressions typed into the question properties panel — but each one does a different job:
| Feature | What it does | Designer location |
|---|---|---|
| Validation | Decides whether an entered answer is acceptable | Validation Rules (Advanced section) |
| Skip Logic | Decides whether a question is shown | Skip Logic (Advanced section) |
| Default Value | Supplies an initial answer when the form starts | Default Value (Advanced section) |
| Auto-Populate / Calculation | Derives an answer from other answers | Calculated Value or Auto-Populate (Advanced section) |
Two of these run once (default values, at form start). Two of them re-run every time a dependency changes (skip logic and calculations). Validation runs every time a value changes.
Tip: Not sure which feature you need? Jump to Choosing the right tool at the end of this page.
Referencing another question
Expressions reference questions by their variable name (the name field),
never by their displayed label.
${age} — the answer to the question named "age"
${visit_date} — the answer to the question named "visit_date"Examples using realistic survey questions:
| Question label | Variable name | Reference |
|---|---|---|
| "What is your date of birth?" | dob | ${dob} |
| "How old are you?" | age | ${age} |
| "Are you currently pregnant?" | pregnant | ${pregnant} |
| "Weight (kg)" | weight_kg | ${weight_kg} |
| "Select your district" | district | ${district} |
| "Visit date" | visit_date | ${visit_date} |
Correct:
${dob}Incorrect:
What is your date of birth?Why the variable name matters
The variable name is the stable identifier used everywhere behind the scenes:
- Translations — the label changes per language, the variable name does not.
- Label edits — you can reword a label without breaking any logic.
- Data exports — exported columns use the variable name.
- Stable calculations — a calculation keeps working even if someone renames the label.
The variable name must start with a letter or underscore and contain only
letters, numbers, and underscores ([a-zA-Z_][a-zA-Z0-9_]*).
Two different reference grammars
MQUAD uses two different reference styles, depending on which feature you are configuring:
| Feature | Reference style | Example |
|---|---|---|
| Validation, Skip Logic, Calculation | ${question_name} | ${age} >= 18 |
| Default Value | #question_name | #country#district |
A default value like #country#res_num concatenates the answers of country
and res_num. The # grammar is only for default values — you cannot use
it in a calculation, and you cannot use ${...} inside a default value.
This is a common source of confusion, so it is called out explicitly in each chapter below.
The current-field value: .
Inside a constraint (validation) expression, the dot . refers to the
current question's own value:
. >= 18means "the answer to this question must be at least 18". The validation
builder generates .-based expressions automatically (e.g. . >= 18,
string-length(.) >= 3). You can also combine . with other questions:
. >= ${min_age}"this answer must be at least the value of question min_age".
Choosing the right tool
| Scenario | Use |
|---|---|
| A question must be answered | Mark it Required in the question properties |
| An answer must be within a range, match a pattern, or satisfy a condition | Validation Rules |
| A question should only appear under certain conditions | Skip Logic |
| A field should start pre-filled (and stay editable) | Default Value |
| A value should be computed from other answers and update when they change | Auto-Populate (on a normal question) |
| A read-only computed result should never be edited | Calculated Value (type = calculate) |
What you'll find in this section
| Page | Covers |
|---|---|
| Validation | Constraints, operators, validation messages |
| Skip Logic | Relevance expressions, conditions, nested logic |
| Default Values | #ref syntax, today, now, system variables |
| Auto-Populate and Calculations | ${ref} syntax and the full function set |
| Expression Reference | Every operator and every built-in function |
| Date and Time Reference | Dates, datetimes, plain times, and the frozen rules |
| Common Recipes | Copy-and-adapt examples for real surveys |
| XLSForm Mapping | How these features map to XLSForm columns |
| Blank and Invalid Values | What happens with null, blank, and bad input |
| Troubleshooting Expressions | Common mistakes and how to fix them |
If you are new to survey logic, start with Validation and Skip Logic, then read Common Recipes for real examples.
