v1.5.1 — checkbox state was unreadable on REDCap 17 (live-found, pid 149)
Bug fix. Anyone using a checkbox in a when/assert condition, or filtering a
checkbox with @UVCHOICES, should take this release. Found on the first live
run of 1.5.0 on REDCap 17.0.6.
- The defect. For each checkbox option, REDCap 17 renders TWO elements: a
hidden input named__chk__<field>_RC_<code>(its VALUE is the code when
checked,""when not —type=hidden, so its.checkedis always false) and
the visible clickable<input type=checkbox>carrying id
id-__chk__<field>_RC_<code>(shared name__chkn__<field>). The engine read
.checkedoff the element it found by name — the hidden mirror — so a
checked box read as unchecked. Consequence: every[field(code)]checkbox
reference evaluated false regardless of the real state. A cascade gated on a
checkbox (e.g.@UVCHOICES={"when":"[pilot(1)]='1'",…}) never activated; a
checkbox@UVASSERT/@UVREQUIRED/@UVUNIQUEwhennever fired; a
checked-but-hidden@UVCHOICEScode was never detected as stale. - The fix. A single
QRID_readCheckbox(field, code)now resolves the state
across renderings: a__chk__…_RC_codethat IS a checkbox → its.checked
(classic REDCap); one that ishidden→value === code(17.x mirror); else
the visibleid-__chk__…_RC_codecheckbox → its.checked.readRefroutes
every checkbox reference through it,requestFieldalso binds change/click on
the visible__chkn__<field>(the hidden mirror fires no events), and the
@UVCHOICESrenderer computes "is this option checked" the same robust way so
a checked option is never hidden from under the user. - Why the tests missed it. The DOM stub modeled
__chk__…_RC_codeas a real
checkbox with a working.checked— more forgiving than REDCap 17. The stub
now models the 17.x two-element structure (hidden mirror + visible box in one
choicevert row);tests/choices_dom_js.cjsgained a checkbox-ref-gated
cascade and a checked-hidden-stale case (58→67 checks) that FAIL on the old
code and pass on the fix (verified by reverting). Backward compatibility with
the classic single-checkbox rendering is retained and still covered. - Radio, dropdown, the two-level cascade, stale-kept selections, and the
save-block (off/confirm/hard) were all verified working live on the same run.
Known issues (not fixed here)
- Performance on rule-heavy projects. A project injecting ~69 rules made a
checkbox click freeze the page for tens of seconds live (each rule installs its
owndocument.bodyMutationObserver; a click that mutates the DOM fans out to
all of them). Pre-existing and module-wide, not specific to choices mode —
tracked separately. Candidate fix: inject only rules whose fields are on the
rendered instrument, and share one observer. - Checkbox message placement. A
@UVCHOICESmessage on a checkbox field is
anchored inside the first option row; a show/hide list that hides that first
code could hide the message with it. Narrow (typical cascades keep the first
code shown); to be re-anchored above the option rows in a later release.
Universal Field Validator is a REDCap external module. Rule kinds: @UVALIDATE (check-character / regex), @UVASSERT (cross-field constraints), @UVREQUIRED (conditional required), @UVUNIQUE (no duplicates across records), @UVCHOICES (dynamic choice filtering).
Docs: README · User guide · Action-tag examples · Install