SurveyCTO Select from Roster Age Order

Revision as of 11:30, 5 April 2018 by Admin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Use Case

In this example we list name and age for up to 10 children in a repeat group. In the second repeat group we list the children in age order and ask the respondent to select a child that has his or her mother present. If the first child's mother is not present then the second youngest child is listed and the respondent is again asked to select the child that has his or her mother present. If two children has the same age, then both children are listed at the same time and the respondent is asked to select one of them.

If a child is selected no more children is listed and the name and index in the first repeat group is stored in separate calculate fields so that they can be referenced later. If no child has a mother present then these two calculate fields are empty.

Code Explanation

The example code can be found here. The first loop and how the child names are dynamically loaded into the choice list used in the second loop is explained here.

The second loop is repeated up to the same number of times as there are unique ages in the child roster, but the repeats are stopped as soon as a child is selected. That is achieved by first joining all ages in child_ages and remove duplicates. Duplicates are removed as children with the same ages are listed at the same time. Then the number of elements are counted in child_ages in field unique_ages_num. This is used as the maximum number of repeats, but the repeat count is created in mother_select_repeat_count that is set to 0 as soon as a child is selected.

The most complicated part of the code is the filter expression in select_mother_present. The expression has two parts rank-value(indexed-repeat(${child_age},${child_roster},filter),${child_ages}) = ${unique_ages_num} + 1 - ${mother_index} and filter = 0. The second part is the easiest and is used to always show the option Not Present.

The first part of the filter expression uses indexed-repeat() to get the age of all children and evaluates how they rank in the list in child_ages using the rank-value() function. The filter column in the choices tab makes sure that each child is associated with its correct age in indexed-repeat(). So, the children that will be listed are the children which age has a rank in the child_ages list that equals the value on the right hand side of the equality sign.

We cannot compare the age rank described above directly with mother_index as mother_index is ascending and the function rank-value() return the descending rank. Remember that we want to list the youngest child first but rank-value() returns the oldest child as rank 1. Therefore ${unique_ages_num} + 1 - ${mother_index} converts the mother_index so that the part to the right of the equality sign descends from the numbers of unique ages (unique_age_num) to 1, and thereby lists the youngest child first.

When no child is selected in a repeat, child_index_mother_present is set to zero but when a child is selected it is set to the index in the first loop of that child. When child_index_mother_present takes a non-zero value child_index_selected is no longer zero and the repeat group count is set to zero and the repeat group is exited. child_index_selected is then used to return the name of the child selected.

Back to Parent

This article is part of the topic SurveyCTO Coding Practices