Set up skip logic and derivations
A form doesn’t have to show every field to everyone all the time. Skip logic (display conditions) shows a field or section only when it is relevant, and derivations (auto-fill) fill computed fields by themselves — with no manual entry. Both are set up in the CRF builder and live in the design version together with the forms.
Who and when
Section titled “Who and when”Data manager — the study designer (Study Builder) or the data
manager with the “edit a design version” permission (studyversion.update). The
logic takes effect after another person approves and publishes the version.
The task comes up while building a form: when some questions are needed only for a particular answer (“If yes — specify”) or a value is computed from others (BMI from height and weight).
Before you start
Section titled “Before you start”- The design version is a Draft.
- The controlling fields already exist in the same form: a display condition reads only the
fields of its own form. A derivation’s source fields may also be on another form — the formula
then reads them with a
ref(…)reference within the same visit. - The derivation’s target field is not marked Required and is not inside a log (a repeating section).
Show a field by condition
Section titled “Show a field by condition”-
In the builder, select the field or section that should not always be shown.
-
In the Properties inspector find Display condition (by default “Always visible — no condition”) and click + Add condition.
-
Build the condition from “field — condition — compare with” rows; for date fields the conditions read as words (is before · is not after · is after · is not before), and you can compare with a field of the form too. Write a complex condition as a formula in Advanced mode (formula), for example:
PREGNANT == 'Y' -
Make sure the condition shows “Expression is valid”. True — the element is visible, false — hidden. The field gets a condition marker in the form structure.
Make a field computed
Section titled “Make a field computed”-
In the builder, open the form and go to the Logic tab.
-
In the Auto-filled fields block click Add derivation.
-
Choose the Target field — it becomes computed: the value is filled in automatically and manual entry is closed.
-
Write the Expression; a field can be inserted from the Insert a field list (a field of another form is inserted as a
ref(…)reference within the same visit). For example, BMI:round(num(WEIGHT) / (num(HEIGHT) * num(HEIGHT)), 1) -
Make sure the expression shows “Expression is valid” and click Create.
An existing derivation is edited in place — clicking it opens the editor. Check conditions and formulas in the preview: there they work as in real entry, but nothing is saved.
What happens
Section titled “What happens”- The change is saved in the draft and written to the audit trail (“Field updated”, “Derivation created” in the design change log).
- After the version is published, during entry:
- conditions recalculate instantly, without saving; a hidden field does not count as unfilled — it doesn’t prevent completing the form, and the “field is required” check does not fire on it; a hidden section hides all its fields;
- a computed field carries the auto-filled marker, is closed to manual entry and recalculates as soon as the source fields are entered; while the sources are empty, it is empty.
- If a field becomes hidden while it already holds a value, the value stays, and the coordinator sees the “Hidden by a condition but holds a value” warning and a Clear (with a reason) button.
- Recalculating a computed field is a data change: SDV verification on it is reset, and the signatures covering it become Invalidated and need re-signing.
If it doesn’t work
Section titled “If it doesn’t work”- “Display conditions may only use fields of this form — ref() is not available here” — a display condition does not read other forms; move the controlling question into this form.
- “A condition cannot reference the field itself” — the controlling field must be a different one.
- “A condition cannot depend on the blinded field” — a blinded field cannot control visibility: that would reveal its value.
- ““…” already has a formula” — a target field can have only one derivation; edit the existing one.
- “The formulas reference each other in a circle” — break the cycle between the computed fields.
- “A log field cannot be filled by a formula” / ““…” is inside a log” — formulas don’t work with fields of repeating sections.
- ““…” is marked required” — untick Required on the target field: nobody fills it by hand.
- “The formula reads a blinded field, so “…” must be blinded too” — mark the target field Blinded (value is masked).
- A 422 response on entry and the value is not accepted — the server rejects writes to a field hidden by a condition or to a computed field. This is expected: change the controlling answer or the source fields.
More details
Section titled “More details”Why a hidden value is not deleted automatically
Section titled “Why a hidden value is not deleted automatically”Skip logic never silently deletes data. If a value was entered and then the answer in the controlling field changed so the field became hidden, the value stays in the database. From there a person decides: Clear (with a reason) — with a mandatory reason, an audit-trail entry and the usual consequences of a data edit; or the coordinator restores the controlling answer — and the field is visible again together with its value.
Editing the sources recalculates the result
Section titled “Editing the sources recalculates the result”If a source value is corrected, the system recalculates the computed field. The recalculated value is a data change like any other: SDV verification on it is reset, and signatures covering the value are invalidated and need re-signing. Editing the source value itself, as usual, requires a reason for change.
The expression language: a quick reference
Section titled “The expression language: a quick reference”Display conditions, derivations and edit checks are
written in one compact expression language. Fields are addressed by data name (OID);
comparisons (==, !=, <, <=, >, >=), arithmetic (+, -, *, /) and the
connectives and / or / not are available.
| Function | What it does |
|---|---|
is_empty(x) |
true if the field is empty |
num(x) |
the field’s numeric value |
days_between(a, b) |
the number of days between two dates |
round(x, n) |
rounding to n decimals |
ref('FORM', 'FIELD') |
the value of a field on another form |
ref('VISIT', 'FORM', 'FIELD') |
the same, pinned to a visit — for cross-form checks |
ref() is available in edit checks and derivations; a display condition reads only the fields of
its own form.
The meaning of “true” depends on where the expression is used:
| Where it is used | True means |
|---|---|
| Edit check | a violation — the check fired (block or query) |
| Display condition | the element is visible |
| Derivation | not a condition but a formula — its result goes into the target field |
The editor in the builder checks the expression as you type: under the box you immediately see “Expression is valid” or the specific error, and the list of fields the expression depends on. Expressions with errors won’t pass submission for review either.