What XLSForm+ODK cannot do

2021-02-05

I’ve been making ODK forms with XLSForm for SEOSAW , as we prepare for a collaborator to set up some new plots in Zimbabwe. I made two forms, one which takes plot information and another which takes stem information. I have some experience setting up woodland survey plots using pen and paper, so naturally I have opinions and vision for what a digital data collection form should look like. This post goes over some of the things I wanted to achieve in ODK, but currently can’t figure out how to. I don’t know with absolute certainty whether the issues listed below are impossible to solve, but I researched each of them on the internet thoroughly before giving up.

I wrote back in 2019 about taking notes in the field, and I even had a stab at making an ODK form then. At the time however, I didn’t have the motivation to finish the app or overcome the issues I encountered, many of which persist and I encountered again this time. XLSForm isn’t a complete programming language, and isn’t as flexible as writing an app from scratch. Unfortunately however I don’t have a background as an app developer, so I think designing an app from scratch would be out of my league.

Issues

Including a table as a hint. One of our questions asks the user to estimate the level of stem decay on a dead tree, using a 1-5 scale. In the SEOSAW guide there is a table which describes how the wood, bark, and branches should appear at each level of the scale, to try to enforce some consistency between data collectors. XLSForm has a guidance_hint field that can provide additional information about a question which is hidden by default but expandable by clicking. I wanted to use HTML or Markdown to create a table in guidance_hint but it seems that XLSForm doesn’t support static tables. As a work-around I created an image of the table and used that in the media::image field.

Incrementing a default answer across repeats. Tags are normally attached to each stem that is measured to allow them to be re-measured later. Normally tags are labelled with integer values, starting at 1 and increasing in sequence to the number of stems in the plot. To avoid having the user type in the tag number each time, I wanted to show a default value that was the previous tag ID +1. This is similar to another issue: autofill an answer with the answer in the previous repeat. The DBH of most trees is measured at 1.3 m height, though occasionally some stem abnormality will necessitate measuring at a different height. This means the user has to type in the POM (Point Of Measurement) of 1.3 m every time. I wanted to take the value given in the previous repeat to the same question and use it as the default in the current repeat.

Dynamically build autocomplete list from previous answers in a repeat. I want the user to input the name of the species of a tree. If an individual of a given species is present in a plot it’s likely there will be more. In order to avoid repeated typing, I wanted to create a dynamic list in a select_one question that would take the answers to the same question submitted in previous repeats, but this seems impossible. This brings be onto another issue with species names. In select_one with “appearance” = autocomplete, it seems logical that if there isn’t an autocompleted match, the user should be able to freely type their submission in the text box. This fails however, and instead marks the submission as blank. I found this forum thread from 2011 which covers the same issue, but it doesn’t seem like anything was done about it. My workaround is to have an “Other” option in the autocomplete list. If the user types “Other” a question below becomes relevant, allowing the user to manually input a different species name. It’s very clunky but I’ve seen this as the recommended answer on the ODK forums. I found this issue in the forums which accomplishes something similar, but in their version the select_one can only be populated with repeat answers if it is outside the repeat. NOTE: I have since been advised on a way to accomplish this, see this post .