I am authoring a survey with Survey123 XLSForms and I cannot quite get where I want with choice filters and the relevant field.
The form has a question, "date_drit_test" that the user can leave blank (if no test occurred) or fill out (if a test occurred):
If the user selects a date, then another question, 'drit_test_result' should appear to indicate test results (which was hidden if no date was selected):
However, I do not want any null values in the 'drit_test_result' column. If a user does not select a date for the DRIT test, I want the value of 'drit_test_result' to be filled with "Not tested"/"NT".
I've got everything working save the last bit. I also suspect I could make my choice filter without the "helper" column 'date_drit_result' but couldn't figure out how to do it - any thoughts there?
Relevant worksheets & fields:
survey worksheet | |||||
type | name | label | calculation | choice_filter | relevant |
date | date_drit_test | Date of DRIT test | |||
hidden | date_drit_result | Was there a DRIT test date? | if(string-length(${date_drit_test})>0, "test_date_present", "test_date_absent") | ||
select_one test_result | drit_test_result | DRIT test result | test_filter=${date_drit_result} | string-length(${date_drit_test})>0 | |
choices worksheet | |||||
list_name | name | label | test_filter | ||
test_result | INC | Inconclusive | test_date_present | ||
test_result | N | Negative | test_date_present | ||
test_result | P | Positive | test_date_present | ||
test_result | NT | Not Tested | test_date_absent | ||
test_result | RT | Retested | test_date_present | ||
test_result | F | Failed (PCR) | test_date_present |
Can you use a calculated field to store the final result? if(string-length(${drit_test_result})>0,${drit_test_result},"Not Tested")
to go further, you could set use a note to display this in lieu of the test_result question and use the relevant column to only display it when there's no date selected
Simple solution is to rename drit_test_result to something list drit_test_result_slct then add a calculate:
EDIT: Updated calculate. I forgot to include the jr:choice-name() component to save the label rather than the name. Basically, just need to choose whether you want to save the name or label from drit_test_result_slct.
Thanks for your suggestion @abureaux ! I'm not sure I understand your response fully and I'm getting an error when I try to incorporate your suggestion (maybe around the first appearance of ")
There are three ways you could do this.
This is what I was thinking. Basically, it automates the "Not Tested" part.
Here is what you have. This works perfectly fine but just takes an extra click (just make the select_one "required"):
Here is a slightly modified version of yours that removes that extra click. It's convoluted, but it does work:
EDIT: I removed the 'note' from Option 3. It was just there for proof of concept since the select_one is hidden for part of this operation. It wasn't required to make this work.
Your answer looks cleaner - but then am I storing the full text (e.g., "Not Tested" vs "NT")? How can I add a domain to that calculate field?
Each of the three options all have slightly different applications, so just select the one that works best. At first, I was just thinking Feature Reports, which Option 1 would do well.
Options 2 and 3 will handle domain values better since they deal with the actual select_one. Option 3 would automate the process more for your end users since they don't need to make a selection at all.
Thanks so much for staying with me @abureaux !
I tried Option 3, and it is mostly working. Users don't see options for test result when they leave the date field empty. If they leave the date field empty, "NT" / "Not Tested" is selected. If they choose a date they can choose any of the other test result options. However, the drit_test_result field is still displaying codes instead of labels in my table when I view it in Survey123 (my other fields with domains show the labels).
Also, when I attempt to edit a record and delete the entry from date_drit_test, "NT" is not auto-populated (even though "calculateMode" is set to "always").
Erica
Opps. There was an error on my part in Option 3. This should work as expected.
The idea is you would use "drit_test_result" as your reference field as it will have either the user's selection (if there is a date) or "Not Tested" (if there is no date). This should minimize user input while preserving your domain values. "drit_test_result_slct" can be ignored in the table as it is just an intermediary field, but you don't want to make it null if you are allowing editing because you want that user selection (if any) to be preserved.
Survey tab:
Choices tab:
When you submit:
When you Edit a submission:
Note: That "Just a random select" at the end is just a plain select_one I used for side-by-side testing.
I replaced the single quotation marks with "" and it works better... but now I'm getting labels in one field and code in the other: