Routing, or enabling/disabling different questions based on participants responses can be done in three ways. The first and easiest way is to use the conditions designer. More advanced routing can be set up by using the expression manager and relevance equations. Finally, array questions can use a specific kind of routing, by using filters.
The simplest way to implement routing is the conditions manager. With a simple user interface you can select what questions and answers determine whether any given question should show – or not show, depending on the situation.
First off, LimeSurvey uses a hide/show logic for every question and question group to implement routing. This means that you cannot directly set a question to ‘jump to’ another section or question based on a previous answer. You can of course simulate such behaviour by setting questions that you want to skip not to show based on a condition.
Secondly, the conditions manager is based on a user interface that is somewhat limited; it supports only the listed operators, and does not allow for calculations or other advanced operations in a condition. Similarly, when you use multiple conditions, there is no way to change how they interact; LimeSurvey will automatically use “AND” or “OR” operators based on some simple rules. While you can use scenarios to circumvent this, it might be easier to use relevance equations.
To use the conditions manager, first open the question you want to enable routing on. (I.e. the question that you want to show/hide). Once you have the question open, you can use the conditions manager button in the questions menu to bring up the user interface.
At the top of the manager, directly below the menu, you can see the current conditions for this question. By default, this shows “This question is always shown”. Below that, you can set the options for a new condition. The question field shows a list of all previous questions, and if relevant, sub questions. A second tab for token fields is also available, allowing you to set conditions based on (custom) tokens. In between you can find the comparison operator, giving you a choice of mathematical operators to use when comparing question and answer. The answer is set in the bottom field, and can be a pre-defined answer (an answer option for that question), the answer to another question, a token, or a constant.
By setting these fields, you can create a condition formula, for example “if sex equals ‘female’”. If this formula equates to true, LimeSurvey will show the question. Other examples might be “if age is greater than or equal to 18”, and countless more.
When you select a question in the top section, the answer field in the bottom is populated with predefined options based on that question (the defined answer options, e.g. male/female, 1-10 on a 10 point scale, etc.). The constant tab in the answer section allows you to compare the question to a constant value, e.g. to check if a respondent is 18 or older. The question tab allows you to compare the answers to two questions, and finally the token fields tab allows you to compare a question to the participants token (note that tokens are only available when you enable them, see the access control section for more information)
In cases where you have multiple conditions, things can get a bit tricky. LimeSurvey will assign “AND” or “OR” operators without giving you the option to change them. Conditions that check against the same question will always be assigned the “OR” operator, while conditions that check against different questions will always be assigned the “AND” operator. This can cause problems when you want question X to trigger when either question Y or question Z are answered in a certain way. By default, LimeSurvey would assign the “AND” operator to these multiple conditions, meaning the question would not always trigger.
The workaround is to use scenarios. Scenarios should be seen as manual groupings of conditions, which LimeSurvey interprets with the “OR” operator. To create a new scenario, click the edit button to the right of an existing condition, or create a new condition, and in the top click the ‘+’ icon next to scenarios. You can now fill in a scenario number (note; this HAS to be an integer value, a whole number, or LimeSurvey will give you an error). The default scenario has the number 1, fill in any other number to assign the condition to a new scenario. Your end result should look like the image below.
This question would show when the respondent is either a woman, or is familiar with the brand Fiat. (Which makes no sense in any scenario, but this is a demonstration after all.)
•Once you are done with your conditions, always test them. Questions should appear/disappear when you change your answers. If a question doesn’t work as expected, you can use the survey logic overview to get a better idea of what is going on.
•If your conditions are very complicated, you might consider using relevance equations instead. While a bit more technical, it allows for a lot more flexibility.
Relevance equations are the most powerful and flexible way of setting up routing. They use mathematical equations and some conditional programming. Anyway with a basic knowledge of any programming language should be able to pick up relevance equations quickly, and even to those who have no computer or programming skills, they are simple enough to understand with a few minutes of research. Additionally, LimeSurvey translates conditions set with the condition manager to relevance equations automatically, which means that you can set a basic condition with the condition manager, and then fine-tune it in the relevance equation. The possibilities are quite literally, endless.
Relevance equations are set when you edit a question or question group, in the relevance equation field at the bottom of the screen. In their simplest form, relevance equations have three building blocks, and look like this;
Where X and Y are variables you want to compare to each other, and the equals sign is the operator. When this equation is true, the question will show. (Note; this is why we fill in ‘1’ (the binary or computer form of ‘true’) when we want a question to always show. If the relevance field is empty, LimeSurvey also treats it as true.)
The variables can be anything, a previous answer, a token value, a constant, random number, and mostly anything else that you can come up with. You can also compare multiple variables, compute new variables on the fly, and create complex equations. In the rest of this manual we will refer to the question that is being hid or shown depending on the relevance equation as the routed question, and any question we use to determine if the routed question should be shown as source questions.
To create a simple relevance equation, you need to know the question code of the source question, the label of the answer(s) to the source question, an operator, and a value to compare against. Let’s say we have a gender question with the code ‘sex’, we might then use the following relevance equation in the routed question to only show if the respondent is male.
lower than or equal to
greater than or equal to
not equal to
In this simple example, sex is the code for the gender question, ‘==’ is the equals operator and ‘M’ is the label for male. Of course, there are many more comparisons possible, as shown in the table below. IMPORTANT: the operator for equal to is ‘==’ and NOT ‘=’. In computer languages, ‘=’ is an assignment operator. The equation sex = ‘M’ would assign the value ‘M’ to the variable sex, which is not what we are trying to do, and would probably result in an error.
In the previous section we explained how to create a simple relevance equation. We will now expand this by adding more conditions. Let’s say we want a question to only show when the respondent is male and under 18. We have two questions for these variables coded ‘sex’ and ‘age’. The relevance equation would then look like this;
We have linked two basic equations with the ‘&&’ operator, which stands for ‘AND’. We could also just use the word ‘AND’ to achieve the same effect. If we used ‘OR’ or ‘||’, the question would show up if the respondent was either male or younger than 18. We can add any number of extra conditions, and create very complex relevance equations by combining them. To help with this, we can use ‘(‘ and ‘)’ to group conditions and execute them together, similar to how mathematical equations work. For example;
Would show the question if the respondent is either male and younger than 18, or female and older than 65. (Note; actually, leaving out the brackets would produce the exact same result in this case, as ‘AND’ is processed before ‘OR’. However, assist readability of equations, and to always err on the safe side, you should probably add the brackets anyway.)
We can also do more advanced conditions; for example, if we had a question weight and height, we could compute BMI, and show an additional question to those with a high BMI. A simple way to do this would be;
This assumes that we have the variable height in meters, as well as the variable weight in kilograms. It would then calculate BMI (height2/weight) and display the question if the result was higher than 35. However, this would probably go wrong a lot! First of all, we have not checked whether the respondent has actually answered the height and weight questions, and if they have, if they have actually filled in their height in metres, not centimetres, or inches. We can circumvent some of these problems by setting the height and weight questions to be mandatory and only accept numerical input, and have a separate question to ask for the units of measurement the respondent uses. We should probably also make sure the value of height is somewhere in an expected range. The resulting equation could look like this;
This function first checks what units are selected in the ‘units’ question, if it is metric it will then check whether the height is smaller than 3 metres (a higher value would suggest the respondent entered height in centimetres), and computes BMI. If this is not the case, it will compute BMI after dividing height by 100. Finally, if the units were not metric, it will calculate BMI for imperial units (assuming the only options in the units question were metric or imperial. The ‘if’ statements are actually functions, which work very similar to if statements in excel. The syntax is if(equation, action if true, [action if not true]). In layman’s terms, the if function first checks if a particular statement is true, in this case if the units are metric and if height is smaller then 3, and then executes either the first or the second section of code within it, which are separated by a comma. In theory you can have an infinite amount of nested if statements. More information on if statements can be found in the tailoring section.
There are a large number of other functions that you can use for advanced relevance equations; you can find a list of them here.
When you save a relevance equation, you go back to the question overview screen. Besides showing the name and description, this also shows a marked-up version of your relevance code. Any errors will be highlighted with a red box. Hover your mouse over this box to see a description of what went wrong.
•First of all, you can find more detailed and in-depth information on the Expression Manager on the LimeSurvey manual.
•If you are confused, you can always define a condition in the condition manager first. Saving it will automatically convert the condition to a relevance equation which you can then use as the basis of a more complicated relevance equation
oWhen you do this, make sure to copy the text of the equation to a text file somewhere, and then delete the conditions you created. If there is a condition set in the condition manager this always overrides the relevance equation and resets it even if you edit it manually.
oThe conditions manager will save variable names in a different format. It will use a SGQA code, which will look something like 123X12X2X1. This stands for the number of the survey, question group, question and answer (if applicable) in the LimeSurvey database. You can safely replace these codes with the question code.
•If you need the value of a particular sub question, you can access it with QUESTIONCODE_SUBQUESTIONLABEL. For example, if we had an array of scales with the code ‘array’, with 5 sub questions labelled 1 to 5, and we wanted the answer to the 3rd sub question, we would use ‘array_3’ to get this value.
•Constants should always have parenthesis surrounding them. ‘M’ is a constant, while M without the parenthesis would be seen as the name of a variable. Since this variable (probably) does not exist, it would give an error. Since numbers cannot be the names of variables, you technically do not have to add parenthesis around numbers, but it doesn’t hurt either, so it’s probably a good idea to add them anyway for the sake of consistency.
Many question types can be filtered based on earlier question types. You could do this manually using the expression manager, but there is a far simpler way to do this by using advanced options.
The brands selected in the top question appear as options in the second question.
This can be chained (cascaded) with more follow-up questions, for example with a scale question for each of the brands that a consumer is familiar with, as in the below image.
There are two types of filters, a basic filter, and an exclusion filter. The basic filter shows only those options that are selected in the first question, while the exclusion filter shows all options BUT those that were selected earlier. Enter the code of the question you want to use as a filter in the filter field of the question you want to apply the filter to. You can find this field in the logic section of the advanced options.
Both questions have to have the same sub-questions/answers. If an answer is present in the first question but not in the second, it will not show, even if it is selected in the first question. An exception to this rule is that if an option is present in the second question and not in the first, it will always show. For example, if we added Landrover to the scale array above but not to the familiarity question, it would always show up in the scale array.
There are many different ways filtering can be used, and it can be cascaded indefinitely should you so desire. However, there are some things filters cannot do. For example, say you wanted to ask further sub questions about those brands where a score of 8 or higher was given. To do this, a filter would not suffice. Instead, you would have to set up a question for each brand, and use relevance equations to show only those where an answer was given (eliminating those brands that are not in the list), and the score was 8 or higher (eliminating the brands that were rated lower).