In the next release of pyxform
, all choice lists will be generated as ODK XForms secondary instances. Prior to this change, forms that did not use any choice filters would have static selects generated instead. You can track this change in the pyxform
repository.
I'm tagging this as breaking-change because it does mean some form definitions will change structure when re-converted. This could have implications for analysis or other tools used after data collection. It does not affect any core ODK tools.
We are making this change because there are bugs in when inline vs secondary instance choice lists are generated (pyxform#387) currently resulting in bigger form definitions than needed. It's also very common to use the same choices many times in a form and currently those may be included over and over again.
Additionally, choice lists in secondary instances can be filtered and queried whereas inline choice lists cannot. This has led to hacks like putting true()
in choice_filter
to force a secondary instance.
ODK Collect and Enketo will continue to support inline choice lists, this change is just for pyxform
and what it generates.
To make this concrete, given the following XLSForm survey
sheet with a corresponding choices
sheet with choices for Apple and Banana:
type | name | label |
---|---|---|
select_one fruits | fruit | Select a fruit |
Before:
body:
<select1 ref="/data/fruit">
<label>Select a fruit</label>
<item>
<label>Apple</label>
<value>apple</value>
</item>
<item>
<label>Banana</label>
<value>banana</value>
</item>
</select1>
After:
model:
<instance id="fruits">
<root>
<item>
<label>Apple</label>
<name>apple</name>
</item>
<item>
<label>Banana</label>
<name>banana</name>
</item>
</root>
</instance>
body:
<select1 ref="/data/fruit">
<label>Select a fruit</label>
<itemset nodeset="instance('fruits')/root/item">
<value ref="name"/>
<label ref="label"/>
</itemset>
</select1>