Repeat Recipes and Tips#

See also

Repeating questions describes repeat basics.

Referencing repeated questions from inside the repeat#

Within a repeat, you can reference other questions in that same repeat instance in the usual manner.

XLSForm

survey#

type

name

label

note

child_questions_note

Please provide the following details about each child in your household.

begin_repeat

child_details

Children in household

text

child_first_name

Name

text

child_age

Age of ${child_first_name}

end_repeat

To reference a question from a different repeat instance, or from outside the repeat, use indexed-repeat() and position().

Referencing repeated questions from outside the repeat#

A question in a repeat can be referenced from outside the repeat with indexed-repeat(${question-name}, ${repeat-name}, index).

Counting repeats and answers#

Counting the total number of repeat instances#

Use count(${name-of-repeat}) to get the number of repeat instances.

Counting the number of times a particular answer was given#

To count the number of times a specific response is given, add a calculate field inside the repeat which evaluates to 1 or 0 depending on the answer. Then, outside the repeat, calculate the sum() of the calculate field.

XLSForm

survey#

type

name

label

calculation

begin_repeat

guest_details

Guest details

text

guest_name

Guest name

select_one meal_options

meal_preference

Meal preference

calculate

chkn

if(${meal_preference} = 'chicken', 1, 0 )

calculate

fsh

if(${meal_preference} = 'fish', 1, 0 )

calculate

veg

if(${meal_preference} = 'vegetarian', 1, 0 )

end_repeat

calculate

chkn_count

sum(${chkn})

calculate

fsh_count

sum(${fsh})

calculate

veg_count

sum(${veg})

choices#

list_name

name

label

meal_options

chicken

Chicken

meal_options

fish

Fish

meal_options

vegetarian

Vegetarian

Using additional repeats to follow up on repeated questions#

Sometimes it is convenient to gather an initial set of responses, and then ask more detailed question after you have collected the whole set.

For example:

  • collecting the names of all the people in a household, and then asking questions about each person

  • collecting the names of each type of crop being grown, and then asking questions about each crop

This can be done by using count() and position(..). count() is used to guarantee that the second repeat has the same number of instances as the original repeat. position(..) provides the index of the repeat instance it was called from. This is used to refer to questions from the first repeat in the follow-up repeat.

XLSForm

type

name

label

repeat_count

calculation

note

person_list_note

Please list the names of the people in your household.

begin_repeat

person

Member of household

text

name

Name

end_repeat

begin_repeat

person_details

Details

count(${person})

calculate

current_name

indexed-repeat(${name}, ${person}, position(..))

date

member_bday

Birthday of ${current_name}

end_repeat

Setting a max limit on repetitions#

If you want the user to decide how many times to repeat, but you also want to limit the maximum number of repetitions, you have a few options.

Using a constraint to limit repetitions#

If the user knows how many repetitions they will complete, you can ask them this in a question before the repeat group and set a constraint on that question.

XLSForm

survey#

type

name

label

constraint

repeat_count

integer

number_in_party

How many guests are in your party?

. <= 8

note

party_names_note

Please provide details for each guest.

begin_repeat

guest_details

Guest details

${number_in_party}

text

guest_name

Guest's name

text

guest_dietary

Does this guest have any dietary restrictions?

end_repeat

Note

If the count is decreased by a user, no groups will be deleted. This avoids accidental data loss: a user who accidentally sets the count too low can set it to a higher number and still have the repetitions that were previously created.

A recommended way to handle this case is using relevance to hide any extra values:

survey#

type

name

label

constraint

repeat_count

relevant

integer

number_in_party

How many guests are in your party?

. <= 8

note

party_names_note

Please provide details for each guest.

begin_repeat

guest_details

Guest details

${number_in_party}

begin_group

guest_details_gr

position(..) <= ${number_in_party}

text

guest_name

Guest's name

text

guest_dietary

Does this guest have any dietary restrictions?

end_group

end_repeat

Using relevants to limit repetitions#

If asking the user ahead of time doesn't make sense, another strategy is to manually repeat the question in the form and use the relevant column to skip repetitions if the previous question is left blank. This sets a maximum number of responses: the number of times you included the question in the form.

To check if the previous question has a response, reference the question in the relevant column.

XLSForm

survey#

type

name

label

relevant

note

images_note

Take up to five pictures.

image

image_1

Image 1

image

image_2

Image 2

${image_1}

image

image_3

Image 3

${image_2}

image

image_4

Image 4

${image_3}

image

image_5

Image 5

${image_4}

This pattern can be combined with required responses to enforce a minimum number of responses.

XLSForm

survey#

type

name

label

required

relevant

note

images_note

Take 3-5 pictures.

image

image_1

Image 1

yes

image

image_2

Image 2

yes

image

image_3

Image 3

yes

image

image_4

Image 4

${image_3}

image

image_5

Image 5

${image_4}