Show the label (instead of value) of a select_one or select_multiple answer in a later question

A lot of users prefer to use numeric internal values for choice list options in multiple choice questions; it makes analysis, doing logic checks in the form, etc. easier. At the same time, you may wish to return and display a prior answer from a multiple choice question in a later question in your form design and this can pose a problem. Directly referring to the multiple choice question would display the internally stored numeric value rather than the label of the answer, which is more user readable.

Note: For anyone not comfortable writing expressions by hand, don't worry. Most of the expressions discussed in this guide can be built for you using the calculation expression wizard in the online form designer or the tools on the Design tab (Your forms and datasets > Tools > Build calculation).

The problem

For example, lets say a form design has a select_one field (q1) where the primary source of the respondent's income is asked and the answer choices use numeric codes. E.g. 1 = farming, 2 = small business, 3 = salaried job. The respondent selects 3, 'salaried job' as the answer.

And in the next question (q2) the user would like to ask "How much do you make each month from ${q1}?" and dynamically have the question text change to display the actual income source.

But simply referring to the multiple choice field directly - as I have done above - will display the actual answer stored in the field ${q1}, and so would appear as "How much do you make each month from 3?" rather than "How much do you make each month from salaried job?"

The solution

In order to display the label of the answer option rather than the answer option itself, one has to first use the jr:choice-name() function in a calculate field and then refer to this calculate field instead. The jr:choice-name() function lets you pull the label associated with a particular answer value and store that label as a string. So, in the above example, after q1, I could create a calculate field and put the following as its calculation expression:

jr:choice-name(${q1}, '${q1}')

That will take the value stored in q1, and then pull the label associated with that value in the list of answer options for q1.

Then, for my question text in q2, I can put the following: "How much do you make each month from ${calcfieldname}?"

Now the question text will display the label, since that is now stored as a string in the calculate field.

Displaying select_multiple answers

You can do something similar if you actually have a select_multiple field and want to later display the label of one of the answers selected. Since more than one answer could be selected, you have to nest the selected-at() function inside the jr:choice-name() function to indicate which of the multiple answers you want to refer to pull the corresponding label. For example, if you want to display the label of the first answer option selected, you should create a calculate field with the following calculation expression:

jr:choice-name(selected-at(${selectmultfield}, 0), '${selectmultfield}')

And then you can refer to this calculate field in the question text of later questions.

Limitations

The jr:choice-name() function does have a limitation in the context of multilingual form designs. It does not readily re-evaluate in response to swapping languages while using the form. Expressions in general re-evaluate at different points (e.g. when fields upon which they depend change their values) but form logic is agnostic of which labels are being displayed at the time. As a result, if you are swapping between languages while testing a form, moving backward and forward, you might see labels from the wrong language returned. This limitation might make jr:choice-name() an unsuitable solution for multilingual data collection scenarios that require going backward in the form (e.g. when using non-linear form navigation). If form users are likely to stick to one language and have no reason to page back and swap languages, this limitation should not be cause for concern.

There are other methods for dynamically displaying pieces of text from different languages in a form design that don't have this limitation but they are a bit more work. The first, suitable if the choice list is not very long, would be to use a nested if() expression in a calculate field per language to return the right label to display. Using the above example, this would look like this for English:

if(${q1} = 1, 'farming', if(${q1} = 2, 'small business', 'salaried job')) 

In the above, if() appears inside if() which is possible to do, to get more than two outcomes. To extend, a.) add in new if() conditions ("if(${field} = 'value', 'result if true', .."), b.) make sure that you add additional closing brackets at the end and c.) be sure that the "if false" condition returned at the end is accounted for in your logic. if() expressions must be specified by hand.

Otherwise, you might pre-load label values from an attached data source per language using the pulldata() function in a calculate field. This would look like this for English:

pulldata('income_source', 'english_label', 'id_key', '${q1})

Functions and operators referenced in this article: jr:choice-name(), selected-at() if() and pulldata(). For a full list of SurveyCTO functions and operators, please read this help topic.

0 Comments

Article is closed for comments.