Collect question type: rank items

What is the general goal of the feature?
As a survey designer, I want to ask subjects to rank certain choices.

Currently users can get something like this functionality using choice filters (Rank options) but it's clunky. The idea would be to add a new widget that lets users drag and drop items into the desired order.

There has been discussion on the specification at https://github.com/opendatakit/xforms-spec/issues/104. The current proposal is to introduce a new odk:rank control element that works the same way as select but for which the order of the responses is meaningful. @TSC, any comments on that proposal?

@Grzesiek2010 has worked on a first pass at a possible interface:


@danbjoseph asked here whether this dragging could be difficult on certain devices.

What are some example use cases for this feature?
Ordering elements by most liked, most important, most likely, etc.

  • Medecine: rank the following symptoms
  • Household wellbeing survey: rank the importance of these household items

There has been significant demand for this over time:

What can you contribute to making this feature a reality?
Project management, code, testing.

Thanks for pushing forward on this @LN! One thing that I don't see is a clear argument for why we shouldn't just add an appearance on a multi-select?

I'm not so worried about dragging, but discoverability of the current UI might be a challenge. Can add something that looks grippable (or a four-way arrow) on the right?

@danbjoseph's suggestion of tapping the number and entering the order that way is also a very natural interaction that we can add.

1 Like

The reason not to add an appearance on a multi-select is that the response has a different meaning entirely. appearance should be for user interfaces that are interchangeable and give the same results. In this case, it would be bad for a client to ignore the appearance fall back to multi-select behavior because it would give the impression of a valid result but wouldn't be right at all. More in the spec discussion at https://github.com/opendatakit/xforms-spec/issues/104

The gripping UI recommended by material design guidelines is a hamburger on the right: see 'reorder' at https://material.io/guidelines/components/lists-controls.html#lists-controls-types-of-list-controls

I definitely prefer the one from the screenshot about but it would be non-standard.

1 Like

Another consideration on how the feature can/should be built in Collect: In many surveys you don't need to rank ALL items but only a subset. E.g. in the 'dangerous animals' example in the above screencast, the instruction could be "Please rank the three most dangerous animals in your view", meaning that the others do not receive a rank at all (or all receive the same).

In KoBoToolbox we implemented a ranking widget in the formbuilder, which allows users to list any number of items and then specify how many need to be ranked (e.g. list 10 animals and require that users select their top 5). This is then translated into n select_one questions (e.g. 5 in the above example, each with 10 choices). Each question has a constraint that prevents ranking the same item more than once.

How would the data be stored/sent to the server? rank1:lion; rank2:leopard; etc. would be my preference as a user, because we are most interested in what was ranked first by how many respondents. But for some it can be useful to see how many time lion was ranked first, second, third, etc. In other words, this is also worthy of a discussion.

1 Like

The reason not to add an appearance on a multi-select is that the response has a different meaning entirely. appearance should be for user interfaces that are interchangeable and give the same results. In this case, it would be bad for a client to ignore the appearance fall back to multi-select behavior because it would give the impression of a valid result but wouldn't be right at all. More in the spec discussion at https://github.com/opendatakit/xforms-spec/issues/104

I agree with @LN but multi select and rank can use the same data type that's why I only implemented a new control type for rank and refactored SelectMultiData class https://github.com/opendatakit/javarosa/pull/295

The pr with changes in the Javarosa is ready and the one for Collect still waits on my local branch but I can show you how it looks:

Can add something that looks grippable (or a four-way arrow) on the right?

I can do that no problem but I thought a single element should be a MediaLayout and work like in single/multi select. I mean we should be able to add audio/video/image am I wrong? Then we don't have enough space for such indicators. Am I wrong?

I changed my first solution I made a year ago ( the gif attached by @LN) and user RecyclerView now so...

Another consideration on how the feature can/should be built in Collect: In many surveys you don't need to rank ALL items but only a subset. E.g. in the 'dangerous animals' example in the above screencast, the instruction could be "Please rank the three most dangerous animals in your view", meaning that the others do not receive a rank at all (or all receive the same).

it should be easy to implement and we can, for example, allow users to remove elements from the list.

How would the data be stored/sent to the server?

as I mentioned above we will use the same data type for multi select and rank so all elements will be separated by commas but in rank the order is important.

3 Likes

Apologies for radio silence here, sometimes I'm not sure where time goes.

I'm pretty lukewarm on a grip indicator. The material design recommendation is two horizontal lines. See https://material.io/design/components/lists.html#behavior for an example. I don't think the meaning of that icon is clear. I think training or hint text would be sufficient. As @Grzesiek2010 mentioned, secondary actions also take up a fair amount of screen real estate. @danbjoseph, @tomsmyth you brought up this valid concern so perhaps you have thoughts on it.

This is a good point, @Tino_Kreutzer. I think ranking all options is the common case and will provide quite a bit of value. Once there's feedback on that question type, we can see about the best way to support subset ranking if there's demand. Two good options are using an attribute or, as @Grzesiek2010 suggested, adding some way to remove some options from the UI.

I've been giving this some thought and I still prefer a space-separated ordered list. I think this is consistent with other question types and provides analysis tools the most flexibility. Ultimately I imagine most users would want a column for each option with the number of the rank in that column. For example:

+-----------+------+------+
| Crocodile | Bull | Seal |
+-----------+------+------+
|         1 |    2 |    3 |
|         2 |    1 |    3 |
|         1 |    2 |    3 |
+-----------+------+------+

This format is best generated by downstream tools (servers, Briefcase, etc).

@martijnr You know I'm always interested in your perspective on spec decisions. Any thoughts on the format of values and whether to immediately come up with an approach for subset ranking?

Should the interaction with the ranking widget match the Navigation option set in Collect's User interface options? That is, if the forward/backward buttons are turned on in navigation options should there be some sort of up/down buttons on each row in the ranking widget?

I agree @LN's sentiment that an icon just for a visual cue takes up valuable screen real estate.

Yes, space-separated ordered list (like a multi-select value).

Updated: :thinking: this makes no sense whatsoever.
For subset ranking, the fixed parts may not be relevant to include in the submission? So we could perhaps exclude those values. However, I always figured that the ranking widget would normally be used in conjunction with the new randomize() function. That may pose a problem if a part of the options are fixed. I don't really see a nice XForms syntax solution for the use of randomize() in such a case.

I hadn't thought about that. I don't think it should be governed by the same setting but I do think we'll want to introduce alternate appearances.

I'm afraid I'm not quite sure what you mean by "fixed parts"! I'm imagining them as frozen in the UI given your follow up about randomize but I do think that's what users want out of a subset rank. I think it would be more like there are, say, 12 items to rank which can be in an itemset and in randomized order but only 3 positions can be assigned. In other words, we only care about the ranking of the top 3 and the other 9 items are ignored.

Spec-wise I don't think we need to make any changes for that as I think you've implied. The value of the question can have exactly the same ordered, space-separated format but with only 3 values included, not 12. We'll just have to consider a variation on the UI.

i would think a line break or spacer of some kind after the number of rows being requested.

and/or perhaps numbers next to the rows for the number of ranks being requested. i.e. you're presented with 8 options and asked for top 3, so the first 3 rows are visibly numbered.

2 Likes

Ah, I totally misunderstood the subset ranking! So ignore my answer please.

Yes, it would be good to figure out the syntax for that. So, just to be clear (this time), would simply a single number indicating the desired length of the ranked list suffice (XForm and XLSForm syntax-wise)?

Right, that’s all the info that’s needed as far as I can tell. I think an attribute would make sense.

Yes, an attribute on <odk:rank> (or bind, hmm...) perhaps.

Just to bring up another possible way to approach this, which is easiest explained by including the UI. (It may already have been brought up in the UI options above.).

We could let the collection of options always be visually separate from the ranked (and therefore selected) options. In that case a count-selected() constraint could take care of getting the required number of ranked items.

Though this may be a less clean-looking widget if all options need to be included (in which case you could drag-and-drop within the same list - as screenshot in OP), it does provide consistency between All and Subset variants of this widget.

Ok, @Tino_Kreutzer, you're right -- let's figure out the subset variant.

Good idea! Regarding the UI, I admit I don't love having to drag items into a list. I think that requires quite a bit of dexterity on some devices and it makes the common case tougher.

But I think the idea works well with something like a dropdown appearance:

In the first example, all items are ranked. In the second, only the top two are ranked.

This would mean a slightly different behavior between appearances. The default appearance would always have a ranking for all items. The dropdown appearance would allow for some blank rankings. Is that acceptable? Or could we introduce an attribute for that (e.g. allow-blanks)?

If we were to introduce an attribute to specify the number of items to rank, I do like @danbjoseph's suggestion of some kind of separator to indicate the number of "ranking spots" here.

1 Like

A common approach in practice is likely to be to use 2 questions. This structure is, as far as I can remember the main one I have seen.

  1. Select the 3 principle problems that affected you

  2. Rank these problems in order

So from my perspective not combining selection and ranking would be fine. Presumably you would just use choice filter to only show the questions to be ranked as per now.

2 Likes

I really like @Neil_Penman's suggestion as a way to support subset ranking. It keeps the widget clean, beautiful and simple (and more fun to build imo). The widget has to be able to deal with dynamically updated options (cascading selections) anyway, so we may as well make that The Subset Ranking Method. There is 0 complexity/code added with this solution, and no syntax additions.

A dropdown appearance to avoid having to drag-and-drop sounds fine to me if there is a need for this.

1 Like

Sounds great, thanks for bringing this up! Agreed with @martijnr that this is nice and clean.

Would like to see dropdown as well but it can be a later addition as it's not needed for subsets.

1 Like

+1 on @Neil_Penman's idea for splitting it into two questions (select priorities, then rank them). This is already possible but complex/awkward to build in XLSForm.

WRT dropdowns: The previously chosen ranks should become unavailable in my view to avoid unnecessary user error OR when a user chooses a rank that was already used it is removed from the first item.

@LN I agree with the UI suggestion of dropdowns rather than dragging. Or use both: That's what SurveyMonkey does; either you assign dropdown values or you start dragging items (at which point each item receives a rank based on the current order).

3 Likes

I was thinking that a rank would always have a value and that resetting it would reset the order to the original one but @martijnr has pointed out on Github that it would be more consistent to provide users with a way to represent "no value".

He is planning this kind of interface for Enketo:

In Collect the equivalent would probably be to have a button that says "start ranking" shown before the list becomes modifiable. Clearing the widget would go back to showing the button.

When we introduce the dropdown variant an empty state can be represented as no rankings set. We'll then need to decide what to do when some ranks are selected but not others.

How does that sound?

This sounds good to me. It's inline (pun?) with what we do with representing null on dates.