Universal Field Validator

@UVCHOICES

@UVCHOICES is a REDCap action tag that shows or hides individual choices of a radio, dropdown or checkbox field based on the live values of other fields — cascading country to region to site in a single field.

REDCap's @HIDECHOICE hides options statically. @UVCHOICES shows or hides individual options of a radio, dropdown or checkbox field based on the live values of other fields — a country → region → site cascade in one field, instead of one near-duplicate field per country.

Syntax

JSON form only. Exactly one of show (a whitelist — every other code of the field hides) or hide (a blacklist) per tag, plus optional when, message and blockSave.

@UVCHOICES={"when":"[country]='1'","show":["101","102","103"]}
@UVCHOICES={"when":"[country]='2'","show":["201","202"]}

@UVCHOICES={"when":"[legacy_entry]<>'1'","hide":["9"]}

@UVCHOICES={"when":"[pilot(1)]='1'","show":["s01","s02"],
            "message":"Only pilot sites during the pilot phase.",
            "blockSave":"hard"}

Codes must exist in the field's own choice list. An unknown code is a configuration error that names the real codes.

Branching

Repeat the tag with different when conditions, plus at most one without as the fallback. Exactly one true condition filters; none — and no fallback — shows everything; more than one true is a visible conflict, in which case the filter is not applied and the save is never blocked on a configuration problem.

Conditions may reference fields on other instruments. Those are resolved server-side against saved values, so nothing off-page leaks into the browser.

A hidden selection is never cleared

If the stored or selected choice becomes hidden — the user changes the country after picking a site — the module keeps it visible (dropdowns keep the option in place but disabled), flags the field invalid with your message, and applies blockSave. Silently erasing an entered value is the one thing this mode refuses to do. Fix it by picking one of the shown choices.

Out-of-list values are out of scope. A value that is not in the field's choice list at all — a missing-data code such as -99 — is never flagged.

Field types

Radio, dropdown and checkbox. Not yes/no, true/false, sql, or matrix fields — matrix rows render different markup, so the tag is refused there rather than half-working.

Dropdown filtering physically removes and re-inserts <option> elements, because Safari ignores CSS hiding on options. Configure via field annotation only in this version.

Audit

A save that lands a hidden choice — via the API, an import, or a race — is logged by the post-save audit as type: choices, reason: hidden-choice, and the Validation scan reports it retrospectively.