How to get the option on a select multiple that was displayed highest in the list

1. What is the problem? Be very detailed.

We used to rely on previous behavior in ODK Collect that the order of saved multi-select answers was the same as shown on screen. So we could list a bunch of family planning methods in order of effectiveness:

  • Method A
  • Method B
  • Method C

and get the most effective one that was selected with selected-at(${family_planning_method}, 0). Now that doesn't work. According to my review of pull request #3964 it looks like the data for a multi-select is saved in order that the items are selected, and de-selecting just removes from that list.

What is the best way to do this now? Is there a way to "sort" select multiple in some way?

2. What app or server are you using and on what device and operating system? Include version numbers.

Collect v1.30.1

3. What you have you tried to fix the problem?

We need form design wizards. We could do a super nested "if" statement, along the lines of

if method_A is selected, then method_A, else if method_B is selected, then method_B, else if .....

but that isn't ideal since we have a long list of methods.

4. What steps can we take to reproduce the problem?

Any old select multiple question. Look at hierarchy view to see the order that the answers are saved. See https://github.com/getodk/collect/issues/4050 for example.

Hello @jpringle,

You might want to try the rank ${listname} widget / type where listname is the list in your choices. rank can work as standalone or a subset of pre-selected list using choice-filter and at least one select_multiple.

The rank displays available items, and with a long press, enumerators can shuffle the list based on order of importance (both asc or desc)

An example that uses rank as subset can be:

name type label choice_filter

  • q1 select_multiple method Which of the following methods are used
  • q2 rank method by order of use frequency, how would you rank these methods? selected(${q1}, name)

Now to Calculate the top item in the list, you can use the same method you are used to of indexing select_multiple items like:

type name label calculation
calculate topmost First ranked item selected-at(${q2},0)

See more about rank in the ODK DOCS: https://docs.getodk.org/form-question-types/?highlight=rank#rank-widget

Best regards,
Jules R

Thanks for the response @jules_rugwiro . That isn't exactly what we are going for, because the second question lets the respondent rank what is previously selected. We do not need that because we already know the order of effectiveness. An IUD is more effective than the rhythm method, for example.

Here is a form that I think does what you're looking for. I've introduced a new column that gives a score to each option (utility in my form). I compute the max utility out of all the choices selected. Then I look up the choice with that utility. This requires that every choice have a unique score but that seems like a reasonable and expected requirement. You don't have to separate out highest_utility from highest_choice if you don't want to -- I just did it for readability of the example. You also don't necessarily need a separate column and could use the "utility" of each item as its name. That would simplify the expressions somewhat.

In general, if you find that you're using a feature that's not documented, please do ask here on the forum whether it's intended as a feature. If it is, it should be documented. In this case, the select multiple order should be considered an implementation detail. What PR #3964 did was make sure all select multiple appearances share code to help maintainability. I believe your approach specifically relied on behavior only the minimal select appearance had.

2 Likes