This page will walk through an example of setting up a form that will display a random yes/no question from a lookup table. This is useful for asking randomized questions for doing knowledge assessment, or to send random behavior change communication out (for example, using CommCare Messaging).
First setup, the following table using the Manage Lookup Tables page. Setup the table so that they are available for all mobile workers in the project.
|field: question_id||field: question_text||field: question_category|
|p01||Do you know the optimal spacing for planting maize?||planting|
|p02||Do you know the depth of hole to dig for each crop?||planting|
|p03||Do you know the width of hole for each crop?||planting|
|f01||Do you know how often you should apply fertilizer?||fertilizer|
|f02||Do you know the quantity of fertilizer to apply?||fertilizer|
|f03||Can you identify what a plant looks like that has been over-fertilized?||fertilizer|
This table has two categories of questions - this corresponds to two different random questions that we will include in our form.
Including Lookup Table Information in the Form
Once we've defined a lookup table, we need to reference it in our form. This is done by adding an "instance" line that references the name of the table. You can place this above any existing instance tags in your form.
You can choose any word for the id="__" portion. This is how you'll reference your lookup table in the rest of the form. For the src="jr://fixture/item-list:____" section, you must specify the Table ID that you created the table with.
Selecting a Random Question
First, lets add two select question to the form for each of our random questions.
Next ,we need to add 3 hidden values per random question we want to ask. These are used for selecting a random question, storing the ID of the selected random question and storing the actual question text of the random question. Add the following hidden values as shown below.
Now we'll add calculate conditions to each of the hidden values, starting with those for the planting random question.
In the planting_question_num hidden value, add the following calculate condition:
|if(count(instance('random_questions')/random_question_list/random_question[question_category = 'planting']) > 0, 1 + int(random() * (count(instance('random_questions')/random_question_list/random_question[question_category = 'planting']) - 1)), "")|
This calculation looks a bit complicated, but it basically checks the number of questions in the fertilizer category, and randomly picks a number between 1 and the number of questions.
Note: You may get a notice saying that the expression was too complex to validate. You can just hit "Ok" as this is expected when using lookup tables.
In the planting_question_id hidden value, add the following calculate condition:
|if(/data/planting_question_num != "", instance('random_questions')/random_question_list/random_question[question_category = 'planting'][int(/data/planting_question_num )]/question_id, "")|
This calculation makes sure that a planting_question_num has been calculated, then stores the question_id for the randomly chosen question.
In the planting_question_text hidden value, add the following calculate condition:
|if(/data/planting_question_num != "", instance('random_questions')/random_question_list/random_question[question_category = 'planting'][int(/data/planting_question_num )]/question_text, "")|
This calculation is similar to the previous one, but instead of storing the code, it stores the actual question text to be displayed.
Next, we will change the label for the the "Planting Random Question" select question to just display the text of the selected question, using an <output value="..." /> statement. Change the label as is shown below.
You can now setup similar calculations and labels for fertilizer calculations and question. You will just need to change the question_category to "fertilizer" instead of planting in any calculations.
Testing an application with Lookup Tables
In order to test the conditional select options and other logic works in the application, you must sign on as a mobile user and submit 'real' data to the server.
- Generic User: Create a generic user called "dimagi" or "demo" and update the fixture specifically for this user - populating all the conditional select options with the same 'dimagi' or 'demo'. As long as the partner is aware of the use case, they will be able to filter out this user in reports. During training, mobile users will sign onto CommCare and submit live 'practice' data. Work with the partner to specify a date where all data submitted to CommCare HQ is considered actual data for program purposes. This should be made clear to the FLWs and to the data analyst/M&E officer.
- Training Application: Copy the final application - remove the conditional select options from the application. This app can be used during training as a training application and the users can enter data in demo mode.
- No SIM: If the partner has not secured SIM cards for the phones prior to training, install CommCare on all the phones. Use one SIM card to restore the user or practice user ('dimagi' or 'demo') to all phones. The phone will update according to the latest fixture item list on HQ. Remove the SIM. The conditional select options will work on the phones and the data will not be submitted to the CommCare HQ.