Thanks, @Kal_Lam. Your answer brought me onto a good track.
After a day of experimentation, I now have a solution that works robustly and handles all the problems related to moving back and forth in the form. It also shows pretty nice error messages. I’d like to share the file here as an example for anyone who encounters similar problems in the future: Kobo Experiments.xlsx (9.0 KB)
A few explanations:
The form uses a required note
field to display error messages when duplicates are detected. The note is displayed conditionally using its relevant
field. This is different from the solution in the answer above, that use a constraint
to prevent duplicates. It works better, because all global values are updated when the relevance
is evaluated.
There are also other note
fields that are not marked as required
; these can serve as warnings. Warnings help the enumerator find places where they can correct something. Here’s how it looks in Enketo:
Later in the form, there is a section on nets (bednets protecting people from mosquitoes). This uses the new “select one from repeat” feature. Each net covers a certain number of people, and validation rules prevent the same person from being covered twice. For example:
As a bonus, the error message tells the enumerator the number of the net where the person has been used before. There’s some clever awful string manipulation to extract that position.
After each net, a summary shows which people have already been covered and which ones are outstanding. Unfortunately, this only works in Collect, not in Enketo:
The core ideas that make this possible:
- Use a global variable
all_selected
thatjoin
s together all the selected elements. - Check if a value appears twice in this variable, by checking whether
substring-before(all_selected, value)
containsvalue
, - For the summary, generate lists of not yet selected elements using something like
join(', ', /data/person/person_name[not(contains(${all_selected}, .))])
Hope this is helpful!