This article covers these topics:
- Introduction to variables
- Local variables
- Global variables
- Variable format
- Variables in reports
- Using variables in the passback url
- Examples
Introduction to variables
Variables can be used to store survey data temporarily or permanently. QMob provides two types or variables: local variables and global variables.
- Local variables store data temporarily and can only be used within a single survey entry. A local variable is erased at the end of a survey entry, as soon as the answers are sent.
- Global variables store data permanently and can be used across survey entries and different surveys. A global variable is erased only when the clearglobal() function is invoked.
Note:The variable name can only contain: a-z, A-Z, _, ., 1-9, and it must start with a character a-z. Note that variable names are case sensitive.
Local variables
Local variables can be set with the action setvar(name,value). The variable can then be accessed with var(name) in conditions, or with $var(name) in question texts. A local variable lies in the scope of the survey entry and cannot be shared between surveys.
Local variable functions
| Function | Description |
|---|---|
| setvar(varname,value) | Sets the value of a local variable. |
| var(varname) | Gets the value of a local variable. |
| isset(varname) | Checks if specified local variable has been set or not |
Global variables
Global variables are used to pass data between multiple surveys, or across multiple entries of the same survey. They are especially useful in diaries. For instance, global variables are used when responses from earlier entries of the diary need to trigger questions in future entries of the same diary. Furthermore, global variables are necessary when passing data from one survey to a later stage survey in a multi-stage diary, without asking the respondent to re-enter data. Global Variables are stored in the device and related to a specific survey. A survey can access (read and write) global variables in other surveys, but that requires configuration in the survey code.
Global variable functions
| Function | Description |
|---|---|
| setglobal(varname,value) | Sets the value of a global variable. |
| global(varname, default_value) | Gets the value of a global variable and if not found set it to the default value (default value is an optional parameter) |
| isglobalset(varname) | Checks if specified global variable has been set or not |
| clearglobal(varname) | Clears a global variable. |
Global variable access
The attribute <globalvariables> (defined under the <survey> element) can be used to control the access to global variables from all external surveys:
| Value | Description | Default value |
|---|---|---|
| allow_external_read | Controls if other surveys are allowed to read global variables from this survey. | true |
| allow_external_write | Controls if other surveys are allowed to write global variables in this survey | false |
The attribute <external> can be used to control the access to global variables from/to a particular external survey:
| Value | Description | Default value |
|---|---|---|
| survey | The ID of the survey these attributes apply for | - |
| prefix | The prefix to use in scripting when reading or writing the variable. | empty string (writing to a variable in another survey will require a non-empty prefix to be present) |
| allow_read | Allows reading of global variables in the enclosing survey for specified survey. | As defined by allow_external_read in <globalvariables> |
| allow_write | Allows writing of global variables in the enclosing survey for specified survey. | As defined by allow_external_write in <globalvariables> |
Using global variables within the same project
Global variables can be defined by using the function setglobal(varname,default_value). The example below creates a global variable called age, and assigns to it a value of 35.
<precondition then="setglobal(age,35)"/>
In order to read global variables you can use the global(varname) function. The example below pipes the previously defined global variable into some text. Please note that the value of age will be stored in the device so it can also be recalled in different survey/diary entries.
<question type="info" text="Hi Nick, you said you are $global(age) years old." {parameters} />
Using global variables across projects
Global variables can also be used to pass values across projects. In this case a project needs to define which other projects have access to its global variables, as explained in the example below.
For example, we have two projects, one with ID=1, and the other with ID=2 (which we'll call for simplicity project 1 and project 2). Project 1 defines a global variable age, whereas project 2 reads the global variable from project 1 and modifies it. First of all, we need to set the header of project 1 declaring that project 2 has access to its variables by using the tag <external survey>, as described in the example below.
<survey name="Project 1" id="1" {parameters}>
<globalvariables>
<external survey="2" allow_read="true" allow_write="true"/>
</globalvariables>
</survey>
The allow_read and allow_write attributes define whether project 2 has access to read and/or to write global variables in project 1. Alternatively, it's also possible to define that every project will have access to project 1 variables, using the allow_external_read and allow_external_writeattributes.
<survey name="Project 1" id="1" {parameters}>
<globalvariables allow_external_read="true" allow_external_write="true"/>
</survey>
Note that allow_write and allow_read have priority over allow_external_read and allow_external_write
We now need to define a way for project 2 to refer to global variables of project 1 by setting a prefix as in the example below.
<survey name="Project 2" id="2" {parameters}>
<globalvariables>
<external survey="1" prefix="prj1"/>
</globalvariables>
</survey>
prj1 is now the prefix with which project 2 will be able to access global variables of project 1. Say for example that project 1 defines a variable age:
<precondition then="setglobal(age,35)"/>
In project 2, we will need to add prj1. in front of the variable name in order to refer to the age variable defined in project 1:
<question type="info" text="Hi Nick, you said you are $global(prj1.age) years old." {parameters} />
Given project 2 has permissions to write that variable, it could also set it to a different value:
<postcondition then="setglobal(prj1.age,40)"/>
Known issues
Global variables are stored on the device, so they will not work as expected if a diary is taken by a respondent on multiple devices (e.g. if the survey is started on a phone and finished on a tablet).
Variable format
Integer variables
You can set an integer with the action setvar(name,Integer-value). The integer can then be accessed with var(name) in conditions or in question texts. This integer variable lies in the scope of the survey and cannot be shared between surveys.
String variables
Text strings can be specified inside single quotation marks. This allows the use of space, comma and other special characters inside a text string. Characters can be escaped with the backslash character e.g. a single quote can be written as \' and a backslash as two backslash characters (\\). Also \n is supported for line breaks.
String comparisons are case-insensitive. At the moment there is no function to perform case-sensitive compares.
Example:
setvar(myvar,'This is a text string,\n\nisn\'t it?')
Floating point variables
It is also possible to use floating-point values in variables. The $round and $trunc variables are special functions to round and format a floating-point value. You can use them in question text to show a formatted variable value without modifying the variable itself. They can be also combined with the setvar function in a pre/post-condition. For example to round the variable "a" to two decimals, you might write the following script:
setvar(a,round(var(a),2))
Below we present a list of useful functions that can be applied to floating point variables:
$round(value,factor)
Rounds a floating-point number. The factor parameter says how many decimals the result should have. It can also be negative in which case it specifies how many points to the left of the decimal point to round to. The round function can also be used as a formatting function to add decimal places to a number.
Some examples:
round(1.2345,0) = 1
round(1.2345,3) = 1.235
round(1234.5,-2) = 1200
round(1.55,0) = 2
round(1.23,3) = 1.230
round(1.999,2) = 2.00
$trunc(value)
The trunc or truncate function drops the digits in a floating-point number without rounding. Thus, trunc(1.5) = 1 and trunc(-1.5) = -1.
$random(min,max)
Generates a random number in the range [min,max], min and max included.
Variables in reports
You can include variables in your QMob reports. To include a global variable in a report, you first need to need to save its value in a local variable. This can be done by using the global function (to read the value of the global variable) and the setvar function (to set the value of the local variable). In the example below we save global variable gvar into local variable lvar.
setvar(lvar,global(gvar))
For information on report creation, see creating reports.
Using variables in the passback url
A passback URL may contain parameters with variable values. Each value is identified by the dollar ($) character, for example, $idvar.
https://servername.com/CODE990099/id=$idvar/rst=1.
Note: Only the value can be a variable; the rest of the URL must be explicitly specified in the passback. In other words, the server address and names of the parameters cannot be variables. These variables are resolved on the server side once the entry is received. For this to work, a variable with the exact name must be set within the survey with the setvar() function.
Examples
Simple calculations using variables
Question 0 (info screen)
<question type="info" title="Welcome " id="5" text="Welcome to the calculation test!" alias="Q0">
<precondition then="setvar(myvariable,10)"/>
<precondition then="setvar(myvariable2,5)"/>
</question>
Question 1
<question type="info" title="Welcome " id="5" text="Welcome to the calculation test!" alias="Q0">
<precondition then="setvar(myvariable,10)"/>
<precondition then="setvar(myvariable2,5)"/>
</question>
Question 2
<question type="single" max_select="1" order="fixed" style="more-options-below" enable_lookup="false" optional_response="false" id="1" text="My variable is $var(myvariable) my second variable is $var(myvariable2) What do you want to calculate?" alias="Q1">
<choice id="1" label="myvariable + myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="2" label="myvariable - myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="3" label="myvariable * myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="4" label="myvariable / myvariable2" anchored="false" exclusive="false" alias=""/>
<postcondition if="answer(Q1)==1" then="setvar(myvariable,myvariable+myvariable2)"/>
<postcondition if="answer(Q1)==2" then="setvar(myvariable,myvariable-myvariable2)"/>
<postcondition if="answer(Q1)==3" then="setvar(myvariable,myvariable*myvariable2)"/>
<postcondition if="answer(Q1)==4" then="setvar(myvariable,myvariable/myvariable2)"/>
</question>
Question 3
<question type="single" max_select="1" order="fixed" style="more-options-below" enable_lookup="false"
optional_response="false" id="3" text="My variable is $var(myvariable) my second variable is $var(myvariable2) What do you want to calculate next?" alias="Q3">
<choice id="1" label="myvariable + myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="2" label="myvariable - myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="3" label="myvariable * myvariable2" anchored="false" exclusive="false" alias=""/>
<choice id="4" label="myvariable / myvariable2" anchored="false" exclusive="false" alias=""/>
<postcondition if="answer(Q3)==1" then="setvar(myvariable,myvariable+myvariable2)"/>
<postcondition if="answer(Q3)==2" then="setvar(myvariable,myvariable-myvariable2)"/>
<postcondition if="answer(Q3)==3" then="setvar(myvariable,myvariable*myvariable2)"/>
<postcondition if="answer(Q3)==4" then="setvar(myvariable,myvariable/myvariable2)"/>
</question>
Question 4 (info screen)
<question type="info" title="Thank You!" id="4" text="My variable is $var(myvariable) my second variable is $var(myvariable2) Thank you for participating." alias="Q4"/>