There are many ways to hide questions using XLSForm. How you do it depends on a few things. In this blog post we will review some common scenarios, common problems and best practices. Familiarity with Survey123 Connect and XLSForm is assumed.
Calculate a question and hide it permanently using the hidden appearance
The most common scenario for permanently hiding a question is where you want to automatically calculate a value and keep it hidden from users. Below is an example where I calculate the horizontal accuracy of a geopoint question and the email of the currently signed-in user. In both cases I use an expression in the calculation column and set the appearance of the question to hidden.
Calculate and hidden question types versus hidden appearance
In the example above, one could argue that the same could have been achieved using a calculate or hidden question types. For example:
The calculate and hidden question types are both part of the XLSForm specification and as such supported in Survey123. Having said this, I think it is better to use the hidden appearance.
The problem with the calculate and hidden question types is that they allow you to hide a question at the expense of giving up the question type. Look at row 3 above, for example: If I set the question type to hidden, my question type is no longer decimal. It becomes a hidden question type, which automatically maps to a string (text) data type. Calculate and hidden question types always default to text. That is a problem, because my accuracy calculation is going to output a decimal value and I do not want it as text. To correct this, I need to go into the bind::esri:fieldType column and specify that the field type is esriFieldTypeDouble. That is one more thing I need to worry about! I would rather set my question type as I like, and then use the hidden appearance.
The only case where I still like to use calculate question types is when working with grid layouts. In that case, calculate has the advantage that it does not take up any space in the grid layout, as opposed to a question with the hidden appearance, which will still take a space (albeit an empty space).
Permanently hiding a question to keep track of status
Let's explore another scenario where you want to permanently hide a question, and use the hidden appearance. Pretend you are creating a form for people to report incidents. You want to use a field to keep track of the status of the incident. When an incident is reported with Survey123, you want the status to always be 'Open'. Using a second survey, or maybe another ArcGIS app, you want another person to open the record and be able to change the status to 'In progress' or 'Closed' using a drop-down list.
This is one way to do it:
Note that rows 2 and 3 will be visible to the user, but rows 5 and 6 will be hidden. In row 5 we store the status, which has a default value of Open. The respondent of the form will not see the question, but when the record is submitted, the status field will always be Open. The status question uses the select_one question type. This means that when the survey is published, a domain will be created so values can be changed through a drop-down list.
This is an example where the hidden appearance has saved our bacon again! If we were to use a hidden question type in row 5, we could have not had this question create a domain. Row 6 has no secrets: We add it so the survey layer has a field where a reviewer can enter comments. This question is hidden in the form but visible to any ArcGIS app that opens the layer.
Using a hidden question to initialize a form
Another common scenario where you want to hide a question is when you prepopulate a value when the form is initialized using app link or a custom URL. Here is an example:
Note that in this scenario, the hidden question is not being calculated. Instead, it is expected that you populate this question when the form is initialized through a custom URL parameter or app link. You pass the customer ID to the form, and then the customer name, surname and phone questions are automatically populated. Again, you may want to hide the customer ID question to avoid confusion: You expect the name, surname and phone to be known, so you present them to the respondent in case they need to be corrected. As for the customer ID, you do not want anyone to change it and you want to keep the form simple, so you hide it.
You do not always need to hide a question when it receives data from an app link, but if you want to hide it, this is the best way to do it: with the hidden appearance.
Dynamically hiding questions using body::esri:visible and relevant
While permanently hiding a question is useful, you might also want to show and hide a question dynamically. There are two main ways to do this in Survey123. These two approaches have subtle, but important differences.
The body::esri:visible column dictates if a question is visible or not. If the expression in this column evaluates to false, the question is hidden. For example:
In the above design, the comments question in row 4 will only be visible if the damage level is High. There is not much more to it: body::esri:visible controls the visibility of a question through an XLSForm expression. That's it!
We also have the relevant column which does something similar, and more. The relevant column, like body::esri:visible, controls the visibility of a question, but it also clears the value in the question when the expression evaluates to false. Big difference! Visible and relevant are two very different things!
The relevant column affects both the question's visibility AND its value. This can be both very useful and also sometimes problematic. For example, say a question is relevant and the user answers it. Now the user changes something in the form that makes that question not relevant. At that point, whatever value was entered in the question is cleared. That data is lost forever. This is often known as question skipping, which is different to simply controlling the visibility of a question.
A lot of survey authors use the relevant column over body::esri:visible. In part, this is due to history: We added support for relevant many years ago. The body::esri:visible column is much newer. Now that you have the choice, you can decide what behavior you want.
Now, something important to remember is that image and audio questions do not support body::esri:visible.
Use groups to avoid repetitive relevancy and visibility expressions
When working on very large forms, you may find yourself applying the same relevancy or visibility expression to many questions. When this happens, consider using groups so your expression can be applied once to the group, rather than to every question. For example, consider this situation:
See how many times the expression ${building_affected} = 'Yes' needs to be evaluated? 11! Next, have a look at this:
In this case the visibility expression is evaluated only once, which is much more efficient. You do no have to use this technique every time you see two or three consecutive questions using the same visibility or relevancy expression, but keep it in mind, particularly when your form grows in size.