Choice filter from repeat inside another repeat

Hello, is there a way to filter choices based on previous repeat?

How many members? (rpt)
First repeat: (rpt)
names, age, gender,

Second repeat (rpt)
Head of Household: select from names from first repeat (but i need to filter the name entered in first itteration in first repeat)

His wife:

In my example, the code is working like this:

The first itteration of the second repeat does hide the first name entered in the first itteration of the first repeat.

The issue is with the other itterations in the second repeat:

The second itteration of the second repeat does not hide the second name entered in the second itteration of the first repeat.

@Kal_Lam @Xiphware

Thanks in advance
select-one-from-repeats.xlsx (10.9 KB)

I’m a little confused by your form… The first repeat is to enter details about every member of the family:

That makes sense.

But the following questions appears to be intended to identify - out of all the above members of the family entered - which individual is:

  1. Head of household
  2. Youngest child, if any?
  3. Wife (presumably of head-of-houshold), if any?

Correct? But if so, these are singular questions, whereas you have them inside a repeat, which is being repeated the same number of times as ${Q1}. That is, for a family of a 6, you are effectively asking the same head-of-household question 6 times (ditto youngest child and wife). :thinking:

I dont think Q4, Q5 and Q7 should be repeated. Or am I missing something?

Have a look at this form as see if its doing something closer to what you are trying to accomplish:


884bc9f06c06a18acff833c828bda82d8ae71f92.xlsx (9.8 KB)

Thank you @Xiphware for your reply.
You are right my form doesn’t show the actual case.

Imagine that we have more than one married member in the family, (i’ll ask them in the first repeat about it), and HHH question will disappear after the first itteration of second repeat (position(…) <2 or any similar relevant).

So why I need the filter is like this:

In first repeat we asked about all family members and alot of other questions. We knew the names, ages and genders.

In second repeat once it come to question who is the wife of “person name”, that’s person name should not be in the list and this is my issue.

I’m able to make a constraint to not allow to select the same name of the person, but I want to hide it, why? because if I knew the way to hide, I can do another filteration for gender age married or not etc.

I hope I explained my issue.

OK. I think I understand what you are trying to do.

Have a look at the following form. I’ve simplified it to just focus on the above requirement (hence no age or gender questions); that is, filtering the displayed choices in the second repeat from the values entered in the first.


select-one-from-repeats.xlsx (10.2 KB)

As you can see below, the names listed for spouse in the second repeat excludes the current individual (and I made this question dependent on whether they are married or not).

The trick here is that the choice filter on the select_one ${Q2} is actually evaluated in the context of the first repeat (!), hence you actually need the indexed-repeat() to compare against the calculated cc_mmbr_name from the second repeat [which I readily admit is a bit counter-intuitive, hence it took me a while to figure out. But if you care to look at the raw XML it starts to make a bit more sense…].

Have a play with my form and see if you can adapt this to your need.

1 Like

OMG, you can’t imagine how much time I spent on this and couldn’t figure it out. Thank you so so much, honestly can’t find the words to thank you.

If I can ask you in the same matter, are we able to add options to the question: “Select their spouse” so the options will be the ${Q2}, and extra options, leats say: Spouse doesn’t live in the HH, Spouse died or leaved etc.

I tried to put a list so:

select_one Q2

in choices:
list name label
Q2 ${Q2} ${Q2}
Q2 1 Spouse doesn’t live in the HH

but the form is craching and give error.

An update, the provided method does work on Enketo but doesn’t work on Collect.

For first itteration in second repeat, it does filter the name of the person, but for next repeats it keep filtering the same name of the first person from firt itteration.

Ex: Male 1, Male2, Female1, Female 2,

When we ask for Male1 questions, it hides his name and only Male2, Female1, Female 2,
When we move to Male2, it keeps hiding Male1 and show the same answers Male2, Female1, Female 2,

It worked on Enketo, but didn’t work on Collect app.

@Xiphware

Glad we were able to figure something out for you! :slight_smile:

Short answer no. The select-from-repeat feature basically harvests all the option labels (and for that matter names!) to display in the choice-list from the XML element for the repeat in the root instance of the XML form data. Which is to say, all the options you want to display have to somehow get embedded into your repeat group’s data subtree.

Although there might be some fancy acrobatics to add some some ‘dummy’ hard-coded iterations into your repeat - and then try to hide them to ensure they don’t get displayed, yadda, yadda,. … - this is probably not something I’d suggest pursuing. The fact is you have to be a little careful using select-from-repeats because you are basically using user-entered data as your select options. And there is nothing to prevent the user entering whatever they want [aside: which is why this feature isn’t support for select_multiple, because the user could readily enter “foo bar”, which would screw up the select_multiple response list result because it uses a space delimiter between each selected option!].

So even if you could figure out how to add, say, a “Dont know” option as an extra option, there is nothing to prevent a devious user from entering “Dont know” as somebody’s name! Then you would have two “Dont know” options and no way to distinguish between them once the data is submitted.

Instead, I would probably recommend adding explicit additional questions; eg “Is X married?” and then if so ask “Is their spouse a member of the household?”, and if so only then show your filtered select question “Select their spouse”.

It worked on Enketo, but didn’t work on Collect app.

Bugger. I’ll have to investigate why… :frowning:

[to be fair, yes you could add additional explicit constraints to prevent the user entering “Dont know” as somebody’s name, but hopefully you get my point. I don’t recommend mixing free-form text input with predefined identifiers because you must then go to the extra trouble of ensuring the free-form text can never collide with your constants. Hence I’d suggest explicit - and unambiguous - additional separate questions. And keep any free-form input as clearly ring-fenced as possible]

1 Like

Sorry for the delay. It actually took a little bit of effort to figure this out…

I’m using a slightly different (and lower-level XPath…) nodeset filter here, but one that works as desired for both Enketo and Collect. It basically performs the equivalent of the previous indexed-repeat() [but works for both! :laughing:].

Enketo and Collect use different XPath engines, so (rarely) nuances in their different behavior surface, particularly when dealing with uncommon/esoteric stuff like filtering between repeat groups and select-from-repeats…


select-one-from-repeatsV2.xlsx (10.3 KB)

Tested against Enketo

And KoboCollect

2 Likes