Question Objects
Question objects expose model metadata and live answer state to safe survey logic. Metadata is read-only. Mutation methods are available only in <run-code> and other runtime flows that explicitly allow mutation.
Question objects are available in two forms:
- Named references such as
Q1,AGE, orSEGMENTfor other questions or auto-punched answers. $curr, the question currently being evaluated in question-local logic.
Core metadata
Q1.name
Q1.type
Q1.description
Q1.comment
Q1.required
Q1.hidden
Q1.pageIndex
Q1.displayStyle
Q1.min
Q1.max
Q1.step
Q1.order
Answer readers
Q1.value
Q1.answer
Q1.values
Q1.count
Q1.sum
Q1.isAnswered
Q1.isBlank
Q1.val()
Q1.first()
Q1.last()
Q1.rank(1)
Q1.has(1)
Q1.includes(1)
Q1.equals(1)
Q1.isin([1, 2, 3])
Q1.all([1, 2])
Q1.toArray()
Q1.toJSON()
value and answer return the normalized current value. values returns an array-like comparable list for choice/ranking answers.
Options and attributes
Q1.o1
Q1.om2
Q1.options.o1.label
Q1.options.o98.isOpenEnded
Q1.option(1).selected
Q1.attr1.value
Q1.attrs.attr1.options.o2.selected
Q1.attr(1).has(2)
Positive option aliases use o{code}. Negative option aliases use om{abs(code)}. Attribute aliases use attr{code} or attrm{abs(code)}.
$curr
$curr is the current question object in question-local logic. It is useful when an option, attribute, group, validation, or run-code block should remain reusable inside the current question.
<question type="multi" name="BRAND">
<run-code>
if ($curr.o1 && $curr.o2) {
setAnswer("BRAND_SEGMENT", "dual");
}
</run-code>
<options>
<option value="1">Brand A</option>
<option value="2">Brand B</option>
<option value="3" if="$curr.o1">Shown after Brand A</option>
</options>
</question>
Do not use $curr in top-level redirect, quota, screen-out, jump, or share-list logic. Use a named question reference there instead.
Run-code mutation methods
Q1.setAnswer(1);
Q1.clearAnswer();
Q_MULTI.options.o2.toggle();
Q_ATTR.attrs.attr1.options.o2.select();
Mutation methods are type-aware and intentionally unavailable in compact if, <condition>, and <validation>. In those read-only locations, use question readers such as Q1.val() or Q1.has(1).
$quota helper
$quota is a frozen quota snapshot namespace. Each property name is a quota sheet/source id. Missing sheets are undefined; missing cells return null.
$quota.gender_quota.cells
$quota.gender_quota.get("male_18_34")
$quota.gender_quota.getPriorityCells()
$quota.gender_quota.getPriorityCells(2, "ratio")
$quota.gender_quota.getAssignmentCells()
| Member/method | Return value | Notes |
|---|---|---|
$quota.{sheet}.cells | Array<{ id, label }> | Authored cell ids and labels from the trusted quota definition. |
$quota.{sheet}.get(cellId) | { label, limit, complete, quotafull } or null | Counts are from the current persisted snapshot. complete is the complete-sample count; quotafull is quota-full count. |
$quota.{sheet}.getPriorityCells(count = 1, type = "count") | Array<string> | Returns underfilled eligible cell ids using the same count/ratio priority algorithm as quota assignment. The return is always an array, even when count is 1. Ties can be randomized. |
$quota.{sheet}.getAssignmentCells() | Array<string> | Current respondent’s assigned/counted cell ids for that quota sheet at the moment the code runs. Before the relevant <quota> checkpoint, this is usually empty. |
The helper is intentionally DB-free. Authored JavaScript reads the runtime snapshot supplied by Survey Link, server persistence, or Run generate; it cannot fetch quota rows directly or bypass server-side quota authority.
<quota source="concept_quota" />
<question type="single" name="HQ_CONCEPT" hidden>
<run-code>
const ids = $quota.concept_quota.getAssignmentCells();
const first = ids.at(0);
if (first) {
setAnswer("HQ_CONCEPT", String(first).replace("r", ""));
}
</run-code>
<options>
<option value="1">Concept A</option>
<option value="2">Concept B</option>
</options>
</question>
Time and params helpers
$now is a Luxon DateTime at evaluation time. $params is the Survey Link URL params object when the runtime supplies it.
$now.toISODate()
$params.source
$params.campaign
Use Luxon.DateTime.fromISO(QDATE.value) when parsing authored date answers.