Translations of this page:
 

Immediately Show Questions when a Certain Option is Selected

Filter questions allow you to display content or questions depending on earlier answers – but sometimes an additional question shall appear directly on the same questionnaire page. In this case, we speak of dynamic content, because the display changes without the browser having transmitted a new HTML page. Dynamic changes of the page require JavaScript, a programming language that runs in the respondent's browser. The server does not learn anything about the changes at first; it only receives the answers after „Next“ has been clicked.

In principle, JavaScript and the Document Object Model (DOM) allow very extensive modifications within a questionnaire page, but this sometimes requires advanced programming skills. This manual is limited to showing or hiding a question depending on an answer.

Tip: If the JavaScript code does not work right away, please use the Developer Tools in the Browser for troubleshooting.

Basics

  1. In JavaScript, there are so-called event handlers. These are functions that are triggered by actions of the user on the page. The action creates an event, and this triggers the connected JavaScript function, the event handler. Possible events are …
    • 'click' – clicking on an element,
    • 'mouseover' – moving the mouse over an element,
    • 'change' – selecting an option in a dropdown or changing a text input field,
    • 'keypressed' – a key press
    • and many others.
  2. Each element of an (HTML) web page has a whole range of properties. SoSci Survey creates each questionnaire page as an HTML page – and all questions and input fields are themselves HTML elements whose properties can be influenced by JavaScript. One such property is the display style (style), and part of it is the display mode (display). The display mode defines how an element is displayed (block or inline) or that it is not displayed at all (none).
  3. The elements of an HTML page are most easily addressed by their HTML ID. SoSci Survey automatically assigns HTML IDs to all input fields, which are based on the question or item ID.
    • The easiest way to determine the ID of an element is with the Developer Tools in the Browser. These tools can show you the HTML code of an element (e.g., a checkbox) – incl. the HTML ID (id="AB01_01"). If you select the „Inspector“ in the developer tools, you can simply click an element of the page to find the corresponding information. Alternatively, you can display the source code of the HTML page in the browser and search for the corresponding element there.
    • For questions, SoSci Survey assigns an HTML ID consisting of the question ID, an underscore (_), and qst (e.g., AB01_qst for question „AB01“).
  4. In SoSci Survey, you can include any content in a questionnaire page, including JavaScript code. The easiest way is to save the code as a text element under Text Elements and Labels (for the display, select „HTML code“) and to drag this text element onto the page under Compose Questionnaire – below the respective question(s).

Note: You should design the JavaScript code in such a way that it hides the content that is not needed – rather than showing the content that is needed. This has the advantage that respondents with JavaScript disabled can still answer the question, because it is not hidden in the first place.

Note: Screen readers, which allow people with visual impairments to take part in your survey, cannot always cope with dynamic content. Using this function may reduce the accessibility of your questionnaire.

Note: By default, some question types use a different display depending on the screen (responsive layout). In rare cases, the display is not chosen correctly if you show such a question by means of JavaScript. In this case, please set an option other than „dynamic“ for Layout in the question.

Note: If you use a simple selection or scale (i.e., not a multiple choice question) as a filter question and have enabled the option to deselect checked options in a simple selection or scale in the questionnaire, the property checked still returns true instead of false after an option has been deselected. In this case, use the event change instead of click.

Tip: If the respondent sees that one of the options involves additional work, this could influence their answering behavior. A classic filter that asks the second question on the following page may make more sense here.

Visible Selection

Depending on a yes/maybe/no question („JN01“, visible selection), an open text question („TX01“) shall be displayed.

The following JavaScript code must be placed on the questionnaire page on which the questions „JN01“ and „TX01“ are located. Either (a) as a text element (display: „HTML code“) that is dragged onto the page, or (b) as an „HTML code“ element on the page.

<script type="text/javascript">
window.addEventListener("load", function() {
  // Show question TX01 if either 1 or 2 has been selected in JN01
  new SoSciTools.ToggleSelection("JN01", [1,2], ["TX01_qst"]);
});
</script>

Alternatively, the functionality can also be implemented without SoSciTools as follows:

<script type="text/javascript">
<!--
var optionA = document.getElementById("JN01_01a");  // JN01_01a is the HTML ID of the option "yes"
var optionB = document.getElementById("JN01_02a");  // Option "maybe"
var optionC = document.getElementById("JN01_03a");  // Option "no"
var question = document.getElementById("TX01_qst");  // HTML ID of the text input
 
function toggle() {
  // The two pipes (||) are a logical "or"
  // So the condition checks: Is option A selected or is B selected?
  if (optionA.checked || optionB.checked) {
    // If "yes" or "maybe" has been selected, the question is displayed
    // No value ("") uses the default setting (display normally)
    question.style.display = "";
  } else {
    // The display option "none" hides the question
    question.style.display = "none";
  }
}
 
// The function shall be run every time one of the three options is clicked
SoSciTools.attachEvent(optionA, "click", toggle);
SoSciTools.attachEvent(optionB, "click", toggle);
SoSciTools.attachEvent(optionC, "click", toggle);
 
// And it shall also be run right away, so that the display is correct at the beginning
// (e.g., hiding the text input at the beginning)
toggle();
// -->
</script>

Mandatory Questions

For questions to be displayed dynamically, they must already be present (invisibly) on the page. Do not show/hide mandatory questions: Even though the respondent cannot answer invisible questions, SoSci Survey insists on an answer for mandatory questions.

If you want to check the answer to a (possibly) hidden question, use a Individual Response Check. There, you check whether the question was hidden or answered. If not, you display the page again.

Below is an example code matching the example above with the visible selection. Please remember that the PHP code must either be entered at the bottom of the page under „PHP for Processing Responses“ or at the top of the next page of the questionnaire.

if (
    // Is question TX01 displayed?
    ((value('JN01') == 1) || (value('JN01') == 2)) &&
    // Is the answer to the text input question TX01 missing?
    (trim(value('TX01_01')) == '')
) {
    // Display the page again
    repeatPage();
}

Multiple Similar Questions

Sometimes the same function is used several times on a questionnaire page. Taking the previous example: Let's assume that the page does not only contain one selection with an additional question, but four selection questions with four additional questions.

The obvious solution would be to copy the JavaScript code. However, this does not work without further ado, because the variables (optionA, optionB) and also the name of the function (toggle()) would then get in each other's way. If you decide to copy, you would have to use different names for the variables and functions in each copy. But there is a more elegant way.

Below, the JavaScript code from above is encapsulated in a function or class DynamicFilter(). The 4 tuples of selection and additional question differ in the IDs of the selection question and the additional question. Accordingly, the function has two parameters selectionID and questionID. These parameters are used for the IDs in the first lines: „JN01_01a“ becomes selectionID + „_01“.

This manual omits the <script> tag; if you use the code, you of course have to add <script type=„text/javascript“> at the very beginning and </script> at the end.

function DynamicFilter(selectionID, questionID) {
    var optionA = document.getElementById(selectionID  + "_01a");  // JN01_01a is the HTML ID of the option "yes"
    var optionB = document.getElementById(selectionID  + "_02a");  // Option "maybe"
    var optionC = document.getElementById(selectionID  + "_03a");  // Option "no"
    var question = document.getElementById(questionID + "_qst");  // HTML ID of the text input
 
    function toggle() {
      // The two pipes (||) are a logical "or"
      // So the condition checks: Is option A selected or is B selected?
      if (optionA.checked || optionB.checked) {
        // If "yes" or "maybe" has been selected, the question is displayed
        // No value ("") uses the default setting (display normally)
        question.style.display = "";
      } else {
        // The display option "none" hides the question
        question.style.display = "none";
      }
    }
 
    // The function shall be run every time one of the three options is clicked
    SoSciTools.attachEvent(optionA, "click", toggle);
    SoSciTools.attachEvent(optionB, "click", toggle);
    SoSciTools.attachEvent(optionC, "click", toggle);
 
    // And it shall also be run right away, so that the display is correct at the beginning
    // (e.g., hiding the text input at the beginning)
    toggle();
}

Everything else remains the same. Now this class function still has to be called to initialize a new instance of the class. This requires the keyword new.

new DynamicFilter("JN01", "TX01");

Together with this call, the code works as in the previous example. But of course, this one line can be repeated several times with further IDs:

new DynamicFilter("JN02", "TX02");
new DynamicFilter("JN03", "TX03");
new DynamicFilter("JN04", "TX04");

This way, the same filter can be used several times on a page very clearly. Of course, it only works this easily if all filter questions and follow-up questions have the same structure. By encapsulating it in a function, however, you can generally avoid the problem that the variables have to be named differently.

An additional question („DD02“) shall be displayed depending on whether a certain option (e.g., the one with the answer code „7“) has been selected in a dropdown selection („DD01“).

<script type="text/javascript">
window.addEventListener("load", function() {
  // Show question DD02 if option 7 has been selected in the dropdown DD01
  new SoSciTools.ToggleDropdown("DD01", [7], ["DD02_qst"]);
});
</script>

Alternatively, the function can also be implemented without SoSciTools as follows.

<script type="text/javascript">
<!--
var dropdown = document.getElementById("DD01");  // The input field of question DD01
var question = document.getElementById("DD02_qst");  // The question DD02 to be shown/hidden
 
function toggle() {
  if (dropdown.value == "7") {  // Enter the value (answer code) here for which the second dropdown shall be shown
    question.style.display = "";
  } else {
    question.style.display = "none";
  }
}
 
SoSciTools.attachEvent(dropdown, "change", toggle);  // Adjust the display when the selection changes
SoSciTools.attachEvent(dropdown, "click", toggle);  // Also check on click - otherwise the change may only take effect when leaving the dropdown
toggle();  // And also ensure the correct display at the beginning
// -->
</script>

Ranking

For a ranking question (e.g., „RK01“), the change can be monitored efficiently via the JavaScript instance provided by SoSci Survey. The following example code displays the question „AB01“ if card 2 is placed on rank 1, 2, or 3.

<script>
function toggle() {
  var question = document.getElementById('AB01_qst');
  var input = s2.RK01.item(2).input;
 
  if ((input.value >= 1) && (input.value <= 3)) {
    question.style.display = "";
  } else {
    question.style.display = "none";
  }
}
 
window.addEventListener("load", function() {
    s2.RK01.addEventListener("click", toggle);
});
</script>

Slider

The JavaScript class SoSciTools.ToggleSelection can also be used for sliders. As the first parameter, enter the variable ID of the slider item, and as the second, all values for which the question(s) shall be displayed.

<script type="text/javascript">
window.addEventListener("load", function() {
  // Show question TX01 if a value between 91 and 101 has been set in the slider SL01_01
  new SoSciTools.ToggleSelection("SL01_01", [91,92,93,94,95,96,97,98,99,100,101], ["TX01_qst"]);
});
</script>

Offering Alternative Questions

You have a dropdown selection „AB05“ and would like to offer another selection depending on the choice. For this, in the present example, a further selection (sight) has to be created for each city in addition to the first selection (favorite city) and included on the page.

Result in the questionnaire

Tip: If you are also considering a visible selection, the extended selection already allows a hierarchical selection of options in a dynamic variant.

Tip: Dynamically showing questions also works in combination with placing questions side by side.

Questionnaire Page

Maybe you cannot work with the default HTML IDs – for example, because you include a question several times on the page and display different items each time. In this case, the questions to be shown are enclosed in DIV elements. This makes the questionnaire page quite long. For the first question, the value 4 pixels is set as spacing to the next question (Settings for displaying the question).

Questionnaire page with all necessary elements

JavaScript Code

The following HTML/JavaScript code is saved in a text element (e.g., with the ID „js_dynamic“, display: „HTML code“):

<script type="text/javascript">
<!--
var dropdown = document.getElementById("AB05");
 
function blender() {
  // The value corresponds to the answer code in the variables listing
  var selection = dropdown.value;
  // However, the value is initially not a number but a text
  selection = parseInt(selection);
 
  // This check is repeated for each question to be shown
  var question1 = document.getElementById("blockAB06");
  if (selection == 1) {
    // Show
    question1.style.display = "";
  } else {
    // Hide
    question1.style.display = "none";
  }
 
  var question2 = document.getElementById("blockAB07");
  if (selection == 2) {
    question2.style.display = "";
  } else {
    question2.style.display = "none";
  }
 
  var question3 = document.getElementById("blockAB08");
  if (selection == 3) {
    question3.style.display = "";
  } else {
    question3.style.display = "none";
  }
}
 
// The function should first be called directly,
// since all dropdowns have to be hidden
blender();
 
// Now the function has to be linked to the change event
// of the first dropdown
SoSciTools.attachEvent(dropdown, "change", blender);
SoSciTools.attachEvent(dropdown, "click", blender);
 
// -->
</script>

Example 4: Scale

In this example, a scale item with 5 options (1=„not at all“ to 5=„very often“) is to be linked to text fields. The text field for each item should only appear if the option 3, 4 or 5 has been selected.

Furthermore, the solution shall not only be used for a pair of items, but for a whole battery (10 scale items and 10 text input fields, which are represented as Combined Questions). To make this work without having to repeat the whole code 10 times, the JavaScript functionality is encapsulated as a class (function). This class is then called exactly once for each of the 10 items.

In the following example, the items have the following identifiers:

  • Scales: SK01_01 to SK01_10
  • Text inputs: TE01_01 to TE01_10

The JavaScript code for the 10 item pairs would look like this. A large part of the code is spent on first finding the selection fields of each scale item (at the top). This has the advantage that the code works independent of the scale level and of DK options.

The core of the function, which shows and hides the input field, is again the element.style.display = "none";

<script type="text/javascript">
 
/**
 * Find and list inputs (radio) of the
 * scale with the identifier itemID.
 */
function getScaleInputs(itemID) {
    var inputs = {};
    // The regular inputs
    for (var i=1; i<100; i++) {
        var inputID = itemID + i;
        var input = document.getElementById(inputID);
        if (input) {
            inputs[i] = input;
        } else {
            break;
        }
    }
    // And then there may be DK options
    for (var i=-1; i>=-3; i--) {
        var inputID = itemID + "DK" + (-i);
        if (i == -1) {
            inputID = itemID + "DK";
        }
        var input = document.getElementById(inputID);
        if (input) {
            inputs[i] = input;
        }
    }
 
    return inputs;
}
 
/**
 * The class that connects the scale item (identifier itemID)
 * to a text input (or similar) with the identifier inputID.
 * The array "show" defines for which values the
 * input field or item should be displayed.
 */
function linkScaleToInput(itemID, inputID, show) {
    // First, we need all radio inputs for the item
    var radio = getScaleInputs(itemID);
    var element = document.getElementById(inputID);
 
    // We need a function to read the value
    // that was checked in the scale
    function getValue() {
        for (var value in radio) {
            if (radio[value].checked) {
                return parseInt(value);
            }
        }
        return -9;
    }
 
    // Then we need a function to respond
    // to the selection
    function onSelect() {
        var value = getValue();
 
        // Display, if the value is listed in "show",
        // or hife vial display=none
        if (show.indexOf(value) > -1) {
            element.style.display = "";
        } else {
            element.style.display = "none";
        }
    }
 
    for (var value in radio) {
        radio[value].addEventListener("click", onSelect);
    }
 
    // Use the correct display in the beginning
    onSelect();
}
 
// One instanmce of the class for each scale item
new linkScaleToInput("SK01_01", "TE01_01", [3,4,5]);
new linkScaleToInput("SK01_02", "TE01_02", [3,4,5]);
new linkScaleToInput("SK01_03", "TE01_03", [3,4,5]);
new linkScaleToInput("SK01_04", "TE01_04", [3,4,5]);
new linkScaleToInput("SK01_05", "TE01_05", [3,4,5]);
new linkScaleToInput("SK01_06", "TE01_06", [3,4,5]);
new linkScaleToInput("SK01_07", "TE01_07", [3,4,5]);
new linkScaleToInput("SK01_08", "TE01_08", [3,4,5]);
new linkScaleToInput("SK01_09", "TE01_09", [3,4,5]);
new linkScaleToInput("SK01_10", "TE01_10", [3,4,5]);
 
</script>
en/create/dynamic.txt · Last modified: by 127.0.0.1
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
Driven by DokuWiki