Question patterns¶
The vocabulary used in the Type column throughout the questionnaire, plus the notation for conditional logic. Stick to this list — a new answer type means new handling in whatever tool eventually captures responses.
Answer types¶
| Type | Captures | Use when | Maps to |
|---|---|---|---|
Short text |
One line, free form | Names, places, short labels | <input type="text"> |
Long text |
Paragraphs | Anything you want the client to explain | <textarea> |
Number |
Integer or decimal | Counts, durations, reps | <input type="number"> |
Number + unit |
Value plus its unit | Weights and lengths where kg/lb or cm/in both occur | Number field + unit selector |
Yes/No |
Binary | Screening gates and simple facts | Radio pair |
Single choice |
Exactly one of N | Mutually exclusive options | Radio group or dropdown |
Multi-select |
Zero or more of N | Checklists — symptoms, equipment, obstacles | Checkbox group |
Scale 0–10 |
Integer 0–10 | Pain, stress, confidence | Slider or radio row |
Scale 1–5 |
Integer 1–5 | Quality and comfort ratings | Radio row |
Score 0–3 |
Integer 0–3 | Coach-assigned movement screen scores | Radio row |
Date |
Calendar date | Birth dates, targets, signatures | <input type="date">, stored YYYY-MM-DD |
Checkbox |
Single affirmation | Consent statements that must be actively ticked | <input type="checkbox"> |
Signature |
Drawn or typed mark | Waiver sign-off | Signature widget + timestamp |
File upload |
Document or image | Clearance letters, rehab sheets | <input type="file"> |
Repeating group |
N copies of a sub-form | Injury list, surgery list | Repeatable fieldset |
Matrix |
One answer per row, from a shared column set | Digestive symptoms, food frequency, family history | Grid of radio groups |
Calculated |
Derived value | BMI, waist-to-hip ratio | Never entered by hand |
Matrix questions¶
A matrix asks the same question of many items at once. It is the most efficient type on the form and the easiest to get wrong.
Define it with an explicit row list and column list:
health_family_matrix
Columns: Diabetes | Heart disease | Stroke | High blood pressure | ...
Rows: Mother | Father | Sibling | Maternal grandparent | ...
Rules:
- Columns must be exhaustive. Every row needs a truthful answer, including "normal" and "doesn't apply". Without them, clients leave rows blank and you cannot distinguish normal from skipped.
- Rows must be independent. If answering one row changes what another means, they are not matrix rows.
- Never put an urgent item in a matrix. A row that should trigger a referral
gets skimmed past at the same rate as every other row. Pull it out into its
own question — see
sys_gi_urgentin section 3.5, which exists precisely because the source sheet had blood in stool sitting as row 12 of 19. - Cap it at about 20 rows. Past that, accuracy drops as clients start answering by pattern rather than by item. The food frequency grid in section 7.2 exceeds this deliberately and is the exception — it is grouped by food category so the client can move through it in chunks.
- On mobile, a matrix must reflow into one question per row. A grid that scrolls sideways gets random answers.
Rules¶
Field IDs are permanent
Every question has a unique snake_case Field ID. Once a single response
exists, the ID is frozen — reword the question all you like, but never
reuse an ID for a different question and never renumber to tidy up. Prefix
each section's IDs consistently (health_*, inj_*, goal_*, …).
Required means blocking
Yes — submission is blocked without it. Reserve this for safety-critical and legally necessary fields; every required field is a point where someone abandons the form. No — optional. Cond. — required only when its trigger fires.
Conditional logic¶
Written under the table it applies to, in this form:
child_field_id → if parent_field_id = Value
child_field_id → if parent_field_id includes Value
child_field_id → if parent_field_id is not Value
Where several children share one trigger, group them:
Rules:
- A conditional question is hidden, not disabled, until its trigger fires.
- Hidden questions never block submission, whatever their
Req.says. - If a trigger is later unset, clear the child's stored answer — a stale follow-up attached to a retracted Yes is worse than no answer at all.
- Don't nest more than two levels deep. If you need three, the section wants splitting.
Multi-select conventions¶
- Always include an explicit escape option — None of these, Not currently, Prefer not to say. A blank multi-select is ambiguous: it can mean "none apply" or "I skipped this", and for screening questions that difference matters.
- Escape options are mutually exclusive with every other option: selecting None of these clears the rest.
- Where a list ends in Other, pair it with a conditional
*_othershort text field.
Sensitive questions¶
Questions touching disordered eating, mental health, pregnancy, substance use and body image follow extra rules:
- Always offer Prefer not to say.
- Never mark them required.
- Never chain an interrogating follow-up inside the form — a positive answer is a prompt for a conversation or a referral, not for more questions.
- Flag them in the page with a
!!! dangeradmonition explaining the handling, as in section 7.7.
Writing the questions¶
- One thing per question. "Do you have knee or hip pain?" cannot be answered by someone with only knee pain.
- Plain language over clinical terms — "pain in your chest", not "angina".
- Avoid leading wording. "How much do you drink?" beats "You don't drink much, do you?"
- Give ranges rather than exact numbers where precision isn't real. Nobody knows their weekly step count to three digits.
- Put the burden on the form, not the client: if you can derive it, calculate it instead of asking.