If the participant's answer to a question is to have an effect on the further course of the interview, it is a filter question. You can define filters either directly in the question (question filter, simple variant) or in the questionnaire (PHP filter).
PHP filters allow much more sophisticated filters than question filters, but require handling of a little PHP program code. Most users of SoSci Survey have never worked with a programming language before. To create filter questions, you will learn some basic knowledge of programming with PHP in this chapter. Don't worry: The first step is always the hardest. all beginnings are difficult, but the programming of filters is absolutely feasible and the reward of the effort is a steep learning curve. Any frustrations are usually compensated for by a joyful aha experience.
Important: To understand this chapter, the chapter Introduction to PHPis strongly recommended.
Important: If a filter does not work as desired, , please take a look into Problem solution for filters.
Tip: If the participants are divided into control and experimental groups (Random generator, Randomization) and see different questionnaire pages, then it usually makes sense to work with setPageOrder()
instead of goToPage()
: The earlier SoSci Survey knows in the questionnaire process that pages are being skipped, the more accurately the progress bar can be adjusted.
Tip: PHP filters are also used in the video tutorial Advanced Filter Questions
Before filters and their function are explained in detail, here is the solution for those who have little time. A yes-no filter is probably the most common use for filters.
Example 1: If a participant answers “yes”, an additional question will be displayed.
Example 2: If a participant answers “no”, several pages are skipped.
You need the following information for the installation of the filter:
You can find the variable identifier in the variable overview . It says something like this
[PT01] Dropdown selection TV usage PT01 TV usage 1 = yes 2 = no -9 = no answer
So the variable is called PT01, the answer code for “yes” is 1 and the code for “no” is 2. Ideally, you have determined for the filter question that the participant must answer it (check the answer tab). Then the code -9 can no longer occur
Attention: Should there be more variables, e.g. PT01_01
and PT01_02
, check the question type. It is important you chose the question type “Selection” or “Dropdown Selection” if you only allow the choice of one option, not “Multiple Choice”.
The filter should be entered as a PHP code when Creating A Questionnaire, at the exact point where the filter should be active (e.g. where the second question is shown or skipped). Simply drag-and-drop a PHP code from the right sight into your questionnaire page (Introduction to PHP).
Important: A PHP filter can never be on the same page as the filter question (the question the answer refers to, in this case PT01
). SoSci Survey loads the questionnaire page by page in order to show the questionee the whole page. The moment the page with the filter question loads, the questionee cannot possibly have answered the questions - and thus the filter cannot react to the answer (value()
).
If you can handle the PHP function value()
, you can implement a number of filters with it.
The following PHP code uses value()
to check whether response code 1
has been stored for variable PT01
. If this is the case, the question AB01
is displayed using question()
.
Note the double equal sign (==
) after the value()
command.
if (value('PT01') == 1) { question('AB01'); }
Tip: This filter can also be used as a Filter questions (question filter) without PHP code.
Tip: If you want to save yourself some typing work, simply drag the question you want to display from the right into the PHP code. Then you can adjust the display options of the question. After confirming with the green check mark, the PHP code for the question will be appended at the bottom of the PHP code element. Then all you have to do is move the code to the right place (between the curly brackets).
Tip: You can also write several question()
commands between the braces {
and }
.
Depending on a previous answer (or a group assignment, e.g. by Randomization), should question A or question B be shown?
In the following example, depending on the answer to a selection question (AF01), either question FF01 or FF02 is displayed.
if (value('AF01') == 2) { question('FF01'); } else { question('FF02'); }
Important: Questions FF01 and FF02 must not be pulled to the side. Otherwise they will be displayed twice: once by the question()
command and once by being dragged to the side.
If the question FF01 is to be displayed for multiple answers in AF01, the Linking Multiple Conditions or
is used.
if ((value('AF01') == 2) or (value('AF01') == 4)) { question('FF01'); } else { question('FF02'); }
It can also be selected from more than 2 questions.
if (value('AF01') == 1) { question('FF01'); } elseif ((value('AF01') == 2) or (value('AF01') == 4)) { question('FF02'); } else { question('FF03'); }
Instead of questions, contents, e.g. stimuli, can also be varied. More about this in the chapter Randomization. In the following example - depending on the code in variable AF01 - either the text module with the identifier “stimulus1” or “stimulus2” is displayed.
if ((value('AF01') == 2) or (value('AF01') == 4)) { text('stimulus1'); } else { text('stimulus2'); }
When Assembling the Questionnaire, you now select the page on which you want to continue with a “no”. Enter an identifier for this page, e.g. “no TV” (Page IDs).
Then go to the page where you have placed the PHP code element for the filter (see above). Write the following:
if (value('PT01') == 2) { goToPage('keinTV'); }
This code uses value()
to check whether the value 2 was stored in the variable PT01. If this is the case, processing with goToPage()
jumps directly to the page with the identifier “noTV”. Subsequent contents of the current page are ignored.
Tip: Read the rest of this chapter. It's worth it!
Filters are programmed in your questionnaire using IF-THEN-ELSE relationships in a PHP code element. In the PHP programming language, the corresponding keywords are if (IF-THEN) and else (ELSE).
After if there is a so-called condition in brackets. If the condition is met, then the command (which is in turn behind the condition) is executed:
if (condition) demand
Additionally you may add the command else that will be executed in case the condition above is not fulfilled:
if (condition) command_1 else command_2
In order to present everything clearly (and to allow multiple commands), the commands are written in curly brackets ({
and }
). The indent simplifies the readability.
if (condition) { command_1 } else { command_2 }
A filter always uses two things: A cause and a consequence on the questionnaire's process.
The following example bases on a question on page 2 of the questionnaire, asking the questionee how much he earns per month. He had to choose between several categories: 1=no income, 2=up to 500$, and so on. This will be the filter question.
Now it is important to know that SoSci Survey - while page 2 is being created - has no idea what the respondent will answer. The page is first created in full, then displayed to the respondent. The respondent selects an option and clicks “Next”. Only when “Next” is clicked is the answer to page 2 sent to the survey server and saved. Immediately afterwards, the server creates page 3 and sends it to the participant to fill out.
The key point here is that an answer from page 2 is only known to the server on page 3. Therefore, the filter for the question can only be created on page 3 at the earliest.
But what if the questions on page 3 should only be displayed if the first option has been selected? Then you have to think outside the box: the filter redirects all respondents who have not selected the first option directly to page 4.
Most filters in SoSci Survey work according to this principle: you skip individual questions or entire pages. In some cases, several filters have to be added one after the other:
For example, if you show a multiple choice with 5 car brands on page 10 and want to ask 4 questions about each of the well-known brands (across 2 pages), you need 5 filters. The first filter checks on page 11 whether the first item of the multiple choice has been clicked. If not, it jumps directly to page 13 (pages 11 and 12 contain the questions about the first brand). The next filter is on page 13. If the second brand (i.e. the second item) has not been clicked, it goes directly to page 15.
If the third mark is checked, the filter on page 15 does not respond. The questions on the page are displayed as normal and SoSci Survey waits for the respondent to click on “Next”. Then page 16 is displayed with the two questions. The next filter is not until page 17: it either directs the participant directly to page 19 or not…
A condition is always put into round brackets (). It may be complied with (the condition will return “true”) or not (“false”).
A condition can look differently. The most common use is the comparision of two values (e.g. two numbers):
==
(two equal signs) checks if two values are the same,!=
(exclamation mark and equal sign) checks if two values are not the same,>
(greater than sign) checks if value one is greater than value two (only works with numerical values),<
(less than sign) checks if value one is less than value two (only works with numerical values).
Attention: To check if two variables are the same, always use two equal signs (==
)! Using only one equal sign (=
) will try to allocate a value to a variable!
Tip: To check if a variable has the value 1 or 2, read Linking Multiple Conditions
Let's go back to the simple example: On page 1 of the questionnaire, question AB01 is asked (a choice about income). The aim is that questions EK01 and EK02 are only asked if the respondent selects the first option in question AB01.
Conversely, this means: If the respondent chooses an answer option greater than 2 (income up to 500 EUR), then page 3 is skipped.
The following example describes a questionnaire with 3 pages. On page 2, it is checked whether the person has declared an income of more than 500 EUR. If not, the rest of the page is skipped and the questionnaire continues directly on page 3.
Tip: How to implement php in the questionnaire is fully described in the chapter Introduction to PHP. Essentially, to use filters you need to drag-and-drop the element PHP-Code (above the list of questions in the “compose questionnaire”-area) into the questionnaire.
Tip: You don't need to enter the questions themselves as PHP-code - you can still drag-and-drop them from the selection list into the page (Comfortable Programming)
For page 3 in the questionnaire you will need a page ID. Let's use “tvconsum”. We need this to be able to jump to this page using goToPage()
The ID can simply be assigned when composing the questionnaire. Click on the page and enter the ID on the upper left.
Normally, you will only use PHP code in the questionnaire where you need it - as above. However, because the contents of the questionnaire page can be presented so succinctly in PHP code, you will often find the following form in the instructions. In terms of content, the function is identical to the above implementation with little PHP code.
Page 1
question('AB01'); // Monthly income
Page 2
if (value('AB01') > 2) { goToPage('tvconsumption'); // Directly goes to page 3 } question('EK01'); // Study funding question('EK02'); // Other income
Page 3 with ID “tvconsumption”
// Page 3 must have the ID "tvconsumption" question('TK01'); // Daily TV consumption question('TK02'); // Favorite TV station
Important: Questions can be dragged-and-dropped into the questionnaire page as well as being implemented via question()
into PHP. While you are technically able to do both, doing so will result in the question being displayed twice and receiving respective error messages.
value()
prints the answer the questionee gave. This will only work after the questionee has hit the “next”-button after he answered the question.In the example, the IF condition is followed by a curly bracket ( {). Curly brackets are used in PHP to group together several functions/commands (e.g. several questions). It is generally a good idea to put the statement(s) after an IF construction in curly brackets - if you do not use brackets and insert further commands, you will often spend a long time looking for the error.
Tip : Use curly brackets for each statement block and indent the PHP code with spaces as in the example (unfortunately the input fields still have problems with tabs). This way you don't lose track of things even with more complex filters and avoid mistakes.
Example for page 2
if (value('AB01') <= 2) { question('AB02'); // Study funding question('AB03'); // Other income } else { question('AB04'); // Working hours per week question('AB05'); // Employment question('AB06'); // Employment limitation } question('AB07'); // This question will be visible to everyone
This paragraph explains the programming of a small filter step by step.
Back to using IF-THEN-conditions as filter questions: Every question can become a filter question, when its answer is used as a condition. First, create any question.
Look at the variables listing. You will find the following
The ID of the question is TF01. The question type is selection, so the answers are saved right under the ID TF01 – if the question would be a scale for example, the answers would be saved below the items instead of the ID. The variables listing tells you the values TF01 can contain: 1 for the answer “yes” and 2 for “no”. -9 is also possible (the question was not answered), though it should not occur as we configured the question to demand a complete answer. You find more details in the chapter Codes and output values.
Create a new questionnaire at compose questionnaire, Name “filter1”, Title “My first filter question”. Tip : The option This question demands a complete answer should in general be used very sparse. But as filters need to decide things upon this answer, it is recommended to use the option for filter questions.
To use TF01 as filter question, you need the command value()
. This function looks up, which answer the questionee gave to this question. In our example, the command value('TF01')
would print 1 or 2 (not -9 because it must be answered). As usual, the requirement is that the question was asked on a questionnaire page before the current one.
If the question TF01 was asked on page 1 of the questionnaire, a PHP-Code on page 2 would look like this:
if (value('TF01') == 1) { question('IN01'); // Type of internet connection question('IN02'); // Commercial use of the internet connection? question('IN03'); // Service provider } question('AB01'); // Job description
The condition checks, whether the answer was equal to 1. In our words, whether the questionee has chosen “yes”. If this condition is true, page 2 will ask three questions about the internet usage (IN01 to IN03).
All respondents – regardless of whether they have an internet connection at home or not – also receive question AB01. People without an internet connection only see this one question on page 2 – people with an internet connection see a total of 4 questions.
By using , elseyou could also ask why you don't have a connection at home:
if (value('TF01') == 1) { question('IN01'); // Type of internet connection question('IN02'); // Commercial use of the internet connection question('IN03'); // Service provider } else { question('IN04'); // Why no internet connection at home? } question('AB01'); // Job description ===== Skip Pages ===== If not using any ''else''-commands and having no other questions on the page, it can happen that the software loads an empty page. Although SoSciSurvey will not show empty pages to questionees since version 2.2.02, this happening is considered bad programming. Empty pages would happen in the following example, if the questionee had answered "no": <code php> if (value('TF_01') == 1) { question('IN_01'); // Type of internet connection question('IN_02'); // Commercial use of the internet connection question('IN_03'); // Service provider }
In this and some other cases, you better use the command goToPage()
. This will directly jump to the stated page in the questionnaire. In the example above, page 2 is only relevant for people with internet connection. All others should jump to page 3.
To use the goToPage()
-command, you need to configure an ID for the page the questionnaire should jump to. In the following example the target page has the ID "usage"
. If you only need to jump to the page following the current one, you can also use the ID "next"
.
The following examples will output the same page (if the questionnee has answered “no”), because following the goToPage()
command, nothing will be executed. The goToPage()
-command leaves the current page and will never return.
Option 1: skip to page “usage” if there's nothing to ask
if (value('TF_01') == 1) { question('IN_01'); // Type of internet connection question('IN_02'); // Commercial use of the internet connection question('IN_03'); // Service provider } else { goToPage('nutzung'); // Jump to page 3 with the ID "usage" }
Option 2: Skip the irrelevant questions
if (value('TF01') != 1) { // You could also check if: value() == 2 goToPage('usage'); // Jump to page 3 with the ID "usage" } question('IN_01'); // Type of internet connection question('IN_02'); // Commercial use of the internet connection question('IN_03'); // Service provider
Example 2 can be used to skip more than one page as well.
Tip: Asking some benchmark data reveals the questionee is not of interest to you? Screenout: Filter unsuitable participants
Tip: Ever since SoSci Survey Version 2.2.02 empty pages will be skipped by default. Thereby you often times don't have to worry about empty pages.
In the example, you have used a selection. A simple selection stores only a single value (namely the selected option), which value()is queried using the question identifier (eg TF01).
However, if you use scales, text entries or multiple choice, you must use the identifier of the corresponding item (e.g. TF02_02) and not the identifier of the question.
The multiple choice selection TF03 contains 4 items. The item with the ID 3 (TF03_03) asks if the questionee uses a mobile phone to access the internet. You will always find the right ID in the variables listing.
The following display is shown in debug mode when you click Next on page 1 (where question TF02 is displayed) . In the example, the first and third items were checked.
In a multiple choice, each item can have the value 1 (not selected) or 2 (selected). If you now want to filter on page 2 whether the respondent has a DSL connection, the PHP code looks like this:
Filter for multiple choice selections
if (value('TF02_03') == 2) { // Has item 2 been selected? question('IN10'); // Download speed question('IN11'); // Usage of video conferences } else { question('IN09'); // Internet connection at home? }
A major disadvantage of multiple choice is that you cannot check whether the respondent has answered it. After all, no tick can be a correct answer.
The problem can be avoided by using a 2-stage scale instead of a multiple choice. If you label the minimum with “no” and the maximum with “yes” (in the figure, the direction of the scale is descending, the orientation of the label is in the middle), you get the same value for each item as in the multiple choice (1=no, 2=yes).
The chapter At least one item shows some tricks on how to use scales in filters.
In case your survey has a certain target group, you might want to filter unsuitable participants and dismiss them after some screening questions. To do so, ask the screening questions early in the questionnaire and use a common filter afterwards.
goToPage('end')
will lead your questionnee to the end of the questionnaire. The interview will be marked as completed and the questionnee will be shown the sendoff.text()
and buttonHide()
can be used to show an individual sendoff. The interview will not be marked as “completed”. Save the sendoff text in Text elements and labels.// Screenout with individual text if (value('AB01') > 3) { text('screenout'); // Show send-off buttonHide(); // Hide the next-button pageStop(); // In case other content shows with the filter }
Tip: By repeating a filter you are able to check different variables. Using boolean operators you can check several variables in one filter (Linking Multiple Conditions).
Tip: You can also create a simple screenout without any PHP code if the screenout is triggered by a selection question. To do this, create a text in the question catalog that should be shown during the screenout. Then edit the screenout (selection) question and enter a screenout in the “Filter question” tab. There you would then have to select the text you created previously.
Filters are an extremely flexible tool. They can even be nested if necessary or check complex conditions. More on this in further chapters (see below).
Unfortunately, filters don't always work as you would like them to. If a filter doesn't work, there are a few simple ways to track down the error:
debug('TF02_03');
debug(value('TF02_02') == 2);
.goToPage()
is recommended only, if questions should be skipped. In case you want to ask alternate questions, the way to do so is by implementing them into the IF-block.goToPage()
will immediately build the stated page (not after hitting next). It will attach this page to the current page (if there were questions asked before the filter).goToPage()
and hitting next, the questionnaire will continue normally.Most filters can be sufficiently programmed using the above programming basics. But not all. The following chapters will show you solutions for more complex filters: