This page covers advanced patterns for working with repeat groups in rtSurvey. For the basics of setting up a repeat group, see Grouping and Repeats.


Dynamic repeat count

By default, the enumerator decides how many times to repeat. You can fix the number of repetitions using repeat_count:

typenamelabelrepeat_count
begin_repeathousehold_membersHousehold member${num_members}
textmember_nameMember name
integermember_ageAge
end_repeat

The repeat runs exactly ${num_members} times, where num_members was collected earlier in the form. The enumerator cannot add or remove instances.


Indexed access: indexed-repeat()

Access a specific repeat instance’s field value from outside the repeat group using indexed-repeat(repeatedField, repeatGroup, index):

typenamelabelcalculation
calculatefirst_nameindexed-repeat(${member_name}, ${household_members}, 1)
calculatesecond_nameindexed-repeat(${member_name}, ${household_members}, 2)

This is useful for building summary fields or referencing the “primary” member’s data after the repeat.


Current instance position: index()

Inside a repeat group, index() returns the 1-based position of the current instance. Use it to label each repetition or create unique identifiers:

typenamelabel
begin_repeatplotsPlot
noteplot_labelPlot number ${index()}
textplot_idPlot ID
end_repeat

Referencing fields in the same instance

Within a repeat, use ${fieldname} to reference another field in the same repeat instance. There is no need for indexed-repeat() within the same loop:

typenamelabelrelevant
begin_repeatmembersMember
textmember_nameName
integermember_ageAge
textschool_nameSchool name${member_age} < 18
end_repeat

Referencing parent fields from inside a repeat

Fields outside (above) the repeat group can be referenced normally with ${fieldname}:

typenamelabel
textvillageVillage name
begin_repeatplotsAgricultural plot
noteplot_contextPlots in ${village}
end_repeat

Summarising repeat data

Use repeat aggregate functions outside the repeat group to summarise:

FunctionExampleDescription
count(group)count(${household_members})Number of instances
sum(field)sum(${loan_amount})Sum of a numeric field
min(field)min(${member_age})Minimum value
max(field)max(${member_age})Maximum value
join(sep, field)join(', ', ${member_name})Comma-separated list
count-if(group, expr)count-if(${members}, ${member_age} < 18)Conditional count
sum-if(field, expr)sum-if(${loan_amount}, ${loan_amount} > 500)Conditional sum
join-if(sep, field, expr)join-if(', ', ${name}, ${age} >= 18)Conditional join

Пример: Household summary

typenamelabelcalculation
integernum_membersHow many members?
begin_repeatmembersMember${num_members}
textmember_nameName
integermember_ageAge
end_repeat
calculatetotal_memberscount(${members})
calculatechildren_countcount-if(${members}, ${member_age} < 18)
calculateadult_namesjoin-if(', ', ${member_name}, ${member_age} >= 18)
notesummary${total_members} members; ${children_count} under 18. Adults: ${adult_names}

Nested repeats

A repeat group can contain another repeat group. Use this carefully — nested repeats add complexity and can be confusing for enumerators.

typenamelabel
begin_repeathouseholdsHousehold
texthh_idHousehold ID
begin_repeathh_membersMember
textmember_nameMember name
end_repeat
end_repeat

To reference a field in an outer repeat from the inner repeat, use ${fieldname} — it resolves to the nearest matching ancestor:

Inside the hh_members repeat, ${hh_id} returns the ID of the current household, not all households.


Rank inside repeat groups: rank-index()

When a rank field exists inside a repeat, use rank-index(instanceNumber, repeatedField) from outside to get the ordinal rank of a specific instance:

typenamelabelcalculation
calculatetop_scorerrank-index(1, ${score})

rank-index(1, ${score}) returns the instance index of the highest score.


Best Practices

  1. Always use repeat_count when the number of repetitions is known in advance — it prevents enumerators from accidentally adding or removing instances.
  2. Keep repeat groups focused — a repeat with 20+ questions per instance is difficult to navigate.
  3. Name repeat groups clearly (e.g., household_members, not repeat1) — the name appears in function calls and exported data.
  4. Test with the maximum expected number of instances to verify performance.
  5. Use field-list appearance on the repeat group to show all fields on one screen per instance (mobile).

Limitations

  • indexed-repeat() requires a valid index (1 to count of instances) — out-of-range indices return empty.
  • Nested repeats beyond 2 levels are not recommended and may cause display issues on some clients.
  • Aggregate functions (sum, count, etc.) operate on the entire repeat group — you cannot aggregate a subset of instances without *-if variants.
Беше ли полезна тази страница?