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

xlsform
form-design

(Ya Basha) #1

Hello,

I have a select_one variable on my ODK form.

1.I want to count the number of all options

any ideas


(Dickson) #2

Hi @yabasha,

Can you provide more description of your problem? With example.

You can use count-selected() to count the number of selected items.

Checkout more info here https://docs.opendatakit.org/form-operators-functions/?highlight=count%20selected#count-selected


(Dr. Gareth S. Bestor) #3

are you willing to randomize them...?


(Grzegorz Orczykowski) #4

I don't think so... it's not the first question about calculating all possible options in select one and select multiple. I have seen at least two similar questions.
As I know it's not possible so if I'm correct and as I said it's not the first question maybe we should add such an option. @yanokwa what do you think?


(Dr. Gareth S. Bestor) #5

I asked ‘cause you can use a ‘trick’ - if you randomize them it’ll convert the control’s options list to a nodeset, which you can then count()...

But yes, especially when pulling in option lists from external datasets, I agree that being able to determine the numbers of options would be quite useful (less critical for hard coded options since the form writer knows how many they added).


(Grzegorz Orczykowski) #6

I created an issue on the Javarosa repository https://github.com/opendatakit/javarosa/issues/400


(Yaw Anokwa) #7

I'll move this conversation into Features so we can discuss it there.

@Xiphware Since you are becoming the person who adds things to JavaRosa, any ideas on how we should do this?


(Dr. Gareth S. Bestor) #8

Probably in terms of usability, the most obvious approach would be adding a new custom XPath function for this purpose, eg count-options(${my_select_question}), since that's how form writers are familiar with dealing with select_ones and select_multis (eg selected(), count-selected()...).

Although in terms of actual underlying implementation it may be quite a different beast, since we're not merely processing the contents of a node in the instance XML; in many (simple) cases the options list may not even exist in as an XML instance in the XForm definition, and only be defined as part of the control's <item> list. Probably it'll require identifying the associated control/question, and then looking up all the options wherever they've persisted after parsing (in my case, the options table in my internal DB). But hey, that's all merely 'implementation details', eh... :wink:

So does count-options(${my_select_question}) make sense?


(Ya Basha) #9

Thank you @Xiphware for your comments and yes that's what I want to use count-options(${Q1}) and I hope soon this function will be added


(Dr. Gareth S. Bestor) #10

easier said than done... :wink: . But I think we've probably got a reasonable consensus that such a thing is worthwhile, eh. :slight_smile:


(Dr. Gareth S. Bestor) #11

I'll wait for a bit more feedback - @martijnr? @ggalmazor? @yanokwa? - about a count-options() XPath function, and if OK I'll open a javaRosa github issue to track. I might be able to work on something, but I cant promise exactly when a PR will be ready.


(Martijn van de Rijdt) #12

count-options(${Q1}) as an XPath function does not seem right to me, because the nodes do not exist in the primary instance, as @xiphware mentioned.

Since we are talking about itemsets (only, right?), the solution in XForms already exists (count()), so I think we should (only) look into a way to make it easier to use this in XLSForm.

Perhaps count-options(${Q1}) could be translated to count(instance('a')/path/to/nodes) by pyxform by extracting the itemset content of Q1 and copying it as a parameter of count().


(Dr. Gareth S. Bestor) #13

The problem, as I see it, is there is no requirement (at least in XForms, and possibly in ODK/javaRosa?) for the options of a select to be converted into an itemset (with which to then count). For example, in the following very simple XML form containing a single select1, created in and exported from Kobo:

<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <h:head>
    <h:title>countoptions</h:title>
    <model>
      <instance>
        <data id="snapshot_xml">
          <select_1/>
          <meta>
            <instanceID/>
          </meta>
        </data>
      </instance>
      <bind nodeset="/data/select_1" required="false()" type="select1"/>
      <bind calculate="concat('uuid:', uuid())" nodeset="/data/meta/instanceID" readonly="true()" type="string"/>
    </model>
  </h:head>
  <h:body>
    <select1 ref="/data/select_1">
      <label>please select 1</label>
      <item>
        <label>Option 1</label>
        <value>option_1</value>
      </item>
      <item>
        <label>Option 2</label>
        <value>option_2</value>
      </item>
      <item>
        <label>Option 3</label>
        <value>option_3</value>
      </item>
      <item>
        <label>Option 4</label>
        <value>option_4</value>
      </item>
      <item>
        <label>Option 5</label>
        <value>option_5</value>
      </item>
    </select1>
  </h:body>
</h:html>

...there is no instance('a')/path/to/nodes itemset to count(), right?!

It would seem that unless we want to introduce a new requirement that all select options must now be represented as an itemset (which the above Kobo form apparently does not), I don't think we can rely on the existing count() function. Or am I missing something?


(Dr. Gareth S. Bestor) #14

Yup, specifying the desired select_one or select_multi control in the XPath function using ${Q1} [or in reality, /instance/data/Q1...), of whose options you want to count, would be tricky to implement. But from this nodeset ref we should be able to uniquely determine the binding and control of the actual select question's control itself, from which we can (hopefully) locate its corresponding itemset or item list. I just cant think of better way by which a (potentially XForm illiterate) XLSForm writer can uniquely identify a select question, except via the control's node ref: ${Q1}, aka instance/data/Q1

[hence my earlier comment, "easier said than done"... :wink: ]