Last-saved value does not work as dynamic default with CSV search() - How to replace CSV search() by select_one_from_file

1. What is the problem? Be very detailed.

For a Service Provision Assessment study, I would like to use the last-saved value as a dynamic default so that the data collector does not have to reenter the district and facility when they are conducting research in the same place.

As the study is multi-country and I want to keep the XLSForms as standard as possible between countries, I am using CSV files to store all variables that do not have an equivalence from one country to another or whose attributes are likely to change during the study. In particular, I have a CSV file for storing the list of facilities + other attributes related to these facilities (e,g. the intervention status of a given facility will change during the study). This list of facilities is different in each country.
facilities.csv (192 Bytes)

I cascade the selection in 2 steps: first selection of the district, then selection of the facility within the selected district, using the search() function from an external CSV.

I was able to use the last-saved value as a dynamic default for the selection of the district without any problem (EDIT: I have actually tried to use it alone, and ODK Collect now keeps on crashing when I start a new form, so probably not working either), but I have not been able to use the dynamic default for the selection of the facility. I am wondering whether I should use last-saved in a different way, or whether this is something that is simply not possible in this context. Many thanks in advance for your insights!

I am aware of the fact that the ODK core team is generally not very much in favour of the use of the search() function and advising for limiting its use, but the proposed alternatives do not meet my requirements (although it is totally possible that I have missed something, in which case I will be happy to be proven wrong!).

image
image
image

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

ODK Central v1.1.0
ODKCollect 1.29.3

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

Use ${last-saved#a1_2} as default, where a1_2 returns the name of the CSV choice (i.e. the key value in the CSV file)
02-TIMCI-SPA-CGEI-ref-form_demo.xlsx (18.6 KB)
image

Use ${last-saved#fname} as default, where fname returns the label of the CSV choice (i.e. the label value in the CSV file)
02-TIMCI-SPA-CGEI-ref-form_demo.xlsx (18.6 KB)
image

I have quickly double-checked that last-saved worked as intended with a "standard" select_one question, which was actually the case, so my current guess is that it is its use with the search() function that is indeed the issue.

4. What steps can we take to reproduce the problem?
See XLSForms and CSV attached above

5. Anything else we should know or have? If you have a test form or screenshots or logs, attach below.
See XLSForms and CSV attached above

The challenge with search()/pulldata is that because it exists outside of the ODK form specification and the form evaluation engine, general implementations for new features like dynamic defaults typically won't work with it.

Is the primary problem that you need to solve that you need to use external data files? If so, perhaps you could use the standards-compliant external secondary instances with select_one_from_file. There are some loose ends to the implementation including support for multilingual labels, performance improvements and documentation. If you are using modern devices and your lists have thousands of elements or fewer, it will likely work well for you. Defaults, choice filters and lookups work the same way as with choice lists built into the form.

The least familiar part will probably be querying which uses XPath syntax. For example, to get the label from the facilities dataset: instance('facilities')/root/item[name=${a1_2}]/label.

select_from_file.zip (23.2 KB)

2 Likes

Many thanks for your rapid answer @LN. The main reason why I was not using select_one_from_file was that I was indeed missing the query syntax. Your example is therefore super useful and I will probably have a new look at the documentation as I had totally missed this information.
Now that I understand how it works, I agree that it seems a much better option to replace the search() / pulldata to the ODK form standard-compliant function :slight_smile:

NB: I have slightly modified the title of the post to make it easier to find if others encounter the same issue.

1 Like

I've added some documentation on external secondary instances at https://docs.getodk.org/form-datasets/. As always, we'd love feedback on what's helpful and what more should be added.

2 Likes

Hi @LN - many thanks for the updated documentation. It reads well. If this is possible, I think a minimalist XLSForm example in the "Referencing values in datasets" section that concretely illustrates the example you give in the last two sentences of the section may be helpful to readers, as I found the example you shared with me in this conversation very helpful to better reflect on the elements described in the documentation.

1 Like

could you tell me how this syntax would look inside a group of questions, or where and how I would put this syntax of using the last one as default in ODKBuild(online).. Thank you very much