Counting the number of all options in a select_one / select_multiple variable

Bump. No updates AFAIK. But perhaps we should resurrect a discussion as to perhaps how best go about offering such a feature. As @martijnr indicates, if these options are already in an explicit itemset then a solution already exists. However if not - as in my above example of a basic XForm - the XPath count() approach wont work. But then in that case these are arguably statically declared options in any case, so the form writer already knows what the count is [sic].

Perhaps an option might be to introduce something similar to randomize() - which as a side effect turns an option list into an itemset - but in this case not randomize them. And by doing so expose the options to be counted via count(). Call it say itemset()?

Thoughts? @ln?

The first question I have is whether there is actually any benefit to pyxform generating static choice lists rather than always using secondary instances. See https://github.com/XLSForm/pyxform/issues/203 for some discussion about that. It's not uncommon for me to add bogus choice filters in order to force instance creation. That's what I would do in this case rather than randomizing the order of the values. I think it would be ideal to always generate instances for selects since those provide a lot of power, including for this situation.

I'm guessing that in this case people are using search() or "fast itemsets". I would not be inclined to add functionality to those since they are on a deprecation path.

1 Like

First, although we could certainly adjust pyxform to generate secondary instances for choice lists, I'd [selfishly] prefer if this could be configurable behavior. Also it doesn't really address the fact that choice lists are after all standard XForm, so a general purpose (XPath?) solution - to counting the number of choices in a select/select1- that now requires that the ultimate (XML) XForm to have been generated via XLSForm doesn't quite seem right...

Counting choices in a static select doesn't make much sense, does it? If the choices are static, then the person designing the form knows exactly how many there are (as you pointed out previously, @Xiphware) . The counting is only useful if that count can actually change.

Taking a step back, here, I think before going too far down brainstorming around a feature, we should be really clear on what the user story is because there are so many great ideas that also need attention!

In this case it would be helpful to get examples of when counting all the options is helpful and to be really explicit about what data sources users want to leverage. My guess is that this all gets resolved once users use spec-compliant secondary external instances.

Agreed. Perhaps @yabasha and @gerlonggs can provide some more specific usecases to help guide when and in what circumstances counting choices is needed/desirable.

1 Like

Perhaps, but no more or less than the existing jr:choice-name(), which is of a similar ilk...

@Xiphware Agreed. Perhaps @yabasha and @gerlonggs can provide some more specific usecases to help guide when and in what circumstances counting choices is needed/desirable.

Here's a usecase I am currently working on; I have two forms, a Registration form and a Consultation form. The Registration form registers patients in a facility and creates an appointment with a doctor. The Consultation form is to pull data from the Registration form using the search() function into a select_one when a doctor’s name is selected. I would like to count the number of patients in the select_one since there’s a maximum number of patients that can be seen by a doctor per day.

Hello,

I'm interested to know how I can use this trick as I am willing to randomize my select choices. Kindly assist

check this document https://docs.opendatakit.org/form-question-types/#randomizing-choice-order

Hi Arif,
The documentation doesn't seem to show how I would count the number of options once I have randomized the choices.

What trick do you mean? There is no trick the topic is in features category that means it's just a proposal.

Actually, there is a 'trick'... :wink:. If you randomize the choices the XForm will turn them into a nodeset, which you can then use the XPath count() function to count how many there are.

Have a play with this form in https://opendatakit.org/xlsform/

count-choices.xls (19.5 KB)

[Update] You can also trigger turning the choices to a nodeset with a simple choice_filter, which avoids randomizing your choices... A simple no-op filter like true() will suffice

count-choices2.xls (20 KB)

[this trick courtesy @LN :wink: ]

3 Likes

Here's one solution that has worked for me. I have a calculate field with this sort of expression in the calculate field:

count(instance('list_product')/root/item[string-length(name)>0])

Where "list_product" is the name of the list itself, and the "string-length(name)>0" just ensures every list item that has a length larger than 0 gets counted so basically everything.

2 Likes

@Xiphware,

Great trick! works absolutely fine if list is part of external_choice or choice list.
I am loading the values from external CSV.
Therefore entry in my choice list is only one, so I always get count 1 whereas list is more 10-15.
It it possible to calculate/count the options from list?
Thanks in advance!

1 Like

A post was split to a new topic: Count selected options

did anyone find a solution to @Prashant_K's query?

@Dipankar_Das, the solution posted above by @Hussein_Lightwalla will do what you need.

If the CSV is list_product.csv this will count the total number of options.

You could also filter this CSV, eg if you had columns type and location in the file and you previously asked questions to get ${product_type} and ${product_warehouse} you could use the following to count the number of options that match the type and location fields:

count(instance('list_product')/root/item[${product_type}=type and ${product_warehouse}=location])

2 Likes

Thank you @ahblake.
This works wonders for me :))

Also, in addition to this, is there any solution if you want the same calculation when you're working with search() and has multiple columns in it?