What this is, and who it is for
A check is a rule a field applies to its own value: required, a minimum, a pattern, a normal range, a date limit. Checks are set on the field in the builder, frozen into the version, and run in two places that must agree: in the browser as the person types, and on the server when the record is saved, where they decide what is stored, what is refused and what opens a query. This page lists every check, how to set it, and the three things a failing check can do. Checks that look across fields or visits are not these; they are rules.
Where to find it
Study → Build → Forms → a form → Open builder → select a field → Validation (and, for the normal range, the Normal range block on the same tab). A check of a table column is set in the column's Edit checks (Tables and repeating groups). You need form.design or study.write, and the form must be a Draft in a version in Build.
What you can do
- Select the field and open Validation.
- Switch on Required, and set the limits that fit its type.
- At the bottom, under When a check fails, choose what each check does: Query, Block or Warn. Only the checks the field actually has are listed.
- Preview the form to see the messages (Preview and testing).
Every option
Required
The Required switch (with an optional message, This field is required by default) has no severity. It always does the same things:
- the form cannot be marked complete while the field is empty. In the data entry screen the one button, Submit form, saves and marks the form complete, so with a required field empty the screen lists the errors and saves nothing, and the server would refuse as well (This form cannot be marked complete — …, naming the fields);
- a save that does not ask for completion (from a program using the API) is accepted, leaves the record in progress, and an unanswered required field then has an automatic query titled Required value missing, which closes itself once the field is answered;
- a field hidden by its visibility condition is not checked.
A required Checkbox must be ticked (an unticked box is empty); a required Toggle must be answered (No satisfies it); a required Range needs a value in the boxes. A required table cell is checked the same way, per cell. A field hidden by its visibility condition is not checked.
The three severities
| Severity | What a failing check does | What the person sees |
|---|---|---|
| Query (the default) | The value is saved, and an automatic query is opened for the person who reviews data. The query closes itself if the value is corrected and nobody has answered it yet; once the site has answered, only a person closes it. A query a person raised never closes itself (Work with queries) | An amber warning on the field |
| Block | The save of the whole record is refused with the field and the check's message listed; nothing is written. It judges the record as it would be saved, so a value entered before the check was made to block stops the next save until it is corrected | A red error; the form cannot be submitted, and the server refuses a save that carries it |
| Warn | The message is shown after the save. Nothing is written for it: no query, no event | An amber warning on the field |
Choose Block for a value that cannot be true (a weight of 10,000 kg). Choose Query for a value that is possible but should be confirmed (a laboratory result outside its normal range). Choose Warn for advice. Changing a check's severity in an amendment is a Controlled change and is shown in the amendment's summary.
The 19 checks
A check is on the list for a field only when the field has it: its value is set (a minimum, a pattern) or its type implies it (an email's format). The Where column is where it is enforced: both means the browser and the server.
| Check (as the builder names it) | Key | Applies to | Fails when | Where |
|---|---|---|---|---|
| Minimum | min | Number, Range, Scale | The value is below the minimum (for a Range, the From value) | both |
| Maximum | max | Number, Range, Scale | The value is above the maximum (for a Range, the To value) | both |
| Normal range | normal_range | Number, Scale | The value is outside the subject's normal range (Units and normal ranges). Its query has normal priority; every other check's is high | both |
| Decimal places | decimal_precision | Number, Scale | More decimal places than allowed | both |
| Minimum length, Maximum length | min_length, max_length | Text, Text Area, Email, Phone | Fewer or more characters than allowed | both |
| Pattern | pattern | Text, Text Area, Email, Phone | The value does not match the regular expression; an expression that does not compile is ignored by the server | both |
| Email format | format_email | Not one address of the form name@domain.tld | server | |
| Phone format | format_phone | Phone | Not digits with the usual punctuation (+ ( ) . - and spaces), 6 to 20 characters | server |
| Time format | format_time | Time | Not 24-hour HH:MM, optionally with seconds | server |
| Answer is one of the options | not_an_option | Radio, Dropdown, Multi-Select | A value that is not one of the options | server |
| One answer only | single_choice | Radio, Dropdown | More than one value | server |
| Minimum selections, Maximum selections | min_selections, max_selections | Multi-Select | Fewer or more options chosen than allowed | server |
| File type | file_type | File Upload | The file's extension is not on the allowed list | server |
| No future dates | not_future | Date, Date & Time | The date is after today | both |
| No past dates | not_past | Date, Date & Time | The date is before today | both |
| Earliest date, Latest date | min_date, max_date | Date, Date & Time | The date is outside the limits | both |
Also checked, with no severity of their own: a number field given something that is not a number; a date that is not a date; and an Other, specify choice with its free-text box left empty (the person must say what the other is, whether or not the field is required).
For a table column the set is narrower: Minimum, Maximum, Decimal places and Normal range for number and range columns, length and pattern for text columns, and the date checks for date columns. A column's normal range is a check only while the column's Auto-query when out of normal range switch is on.
The automatic query's name and wording
An automatic query opened by a check is titled by what failed: Required value missing, Below the allowed minimum, Above the allowed maximum, Outside the normal range, Too many decimal places, Too short, Too long, Not in the expected format, Not one of the choices, Too few selections, Too many selections, File type not allowed, Date in the future, Date in the past, Date before the allowed minimum, Date after the allowed maximum. The checks format_email, format_phone, format_time and the Other, specify check have no such title in this release, so their queries are titled by the key (Edit check: format_email). Its text is the check's message. See Work with queries.
Pattern presets
Under Pattern preset: Alphanumeric, Uppercase letters only, Lowercase letters only, Numeric digits only, Phone (international), Zip code (US 5-digit), Postal code (UK), Date DD/MM/YYYY, CDASH Subject ID, No special characters, Hex colour code, or Custom. A valid expression shows a green tick, an invalid one a red mark and Invalid regular expression — check syntax; the Test pattern box tells you at once whether a sample value matches.
What the system records
- The check's settings and severities are part of the form's design revision and its snapshot; the snapshot's content hash covers them.
- A query opened by a check is
query.raisedwith origin auto, the rule key and the priority; its closing isquery.closed. A blocked save writes nothing about the value, because nothing was saved. A Warn leaves no trace. - Every value that is saved is an audit entry with its earlier value and reason; the check does not change that.
What you cannot do, and why
- Give Required a severity. A required field that could be saved and completed empty would not be required.
- Set a severity on a check the field does not have. Nothing would use it.
- Make a Warn leave a record. Warn is deliberately silent so it never creates work; use Query for that.
- Rely on the browser alone. A person using the API directly is checked by the server's checks, which are the authority.
- Set the checks of a form after its version leaves Build. The design is frozen from the submission to UAT.
Compliance Q&A
Yes. The server runs the field checks on every save, whatever the route, and its judgement is the one that counts; the browser repeats the numeric, length, pattern and date checks so a person sees the message before saving. One pass decides what blocks the save, what is only shown and what opens a query, so the three never contradict each other.
Limits: the format, option and file-type checks run on the server only, so the person sees their message after the save rather than as they type.
Evidence: server/src/modules/study/data-capture/domain/validation-engine.ts (one judgement for what blocks, warns or opens a query)client core/engine/validation-engine.tssave-responses.ts
By default, yes: every check opens a query. A designer can set a check to Warn, and then a failing value is saved with a message and no query.
Limits: this is a design decision of each form, controlled like any other change (a Controlled change in an amendment). Review the severities in UAT.
Evidence: server data-capture validation-engine.ts and save-responses.ts (severity: query opens, block refuses, warn is shown and written nowhere)
Related
Field properties · Units and normal ranges · Rules reference · Work with queries · Enter visit data · Preview and testing