Inhaltsverzeichnis

Navigation in the Questionnaire

Participants usually start on the first page and then fill out the questionnaire sequentially. The sequence can be changed with setPageOrder() or goToPage(), but the participants still follow the sequence given by the project manager.

This tutorial describes how to add a menu or navigation to the questionnaire so that participants can jump between pages and/or sections. This is especially useful when using a form in SoSci Survey to get specific information of your participants (see also Forms with Different Input Formats).

Example for a navigation menu in the questionnaire

Basics

Step one is to fill the IDs on every page which your participants can jump to, under “Compile Questionnaire”. Enter the title of your page as Note.

Enter page ID and note

The navigation buttons are created by the function buttonToPage(). This function generates HTML-Code, which can be implemented in the questionnaire page using html(). With the following PHP-code you are able to create buttons on a questionnaire page with different purposes.

html(
  '<div>'
  buttonToPage('start').
  buttonToPage('contact').
  buttonToPage('study').
  buttonToPage('services').
  buttonToPage('documents').
  buttonToPage('notes').
  buttonToPage('submit').
  '</div>'.
);

Buttons for navigation between different pages

The PHP-Code is required on every page (e.g. at the top) of your questionnare to be enabled. This is very inconvenient and makes subsequent changes more difficult. Therefore, you define a new function that manages the navigation and any further adjustments. It is located under Compile Questionnare in the tab *PHP Functions*.

function navigation() {
    // Navigation
    html(
      '<div>'
      buttonToPage('start').
      buttonToPage('contact').
      buttonToPage('study').
      buttonToPage('services').
      buttonToPage('documents').
      buttonToPage('notes').
      buttonToPage('submit').
      '</div>'.
    );
    // Label of the Next button
    option('nextbutton', 'next form');
}

To enable the function, the following PHP-Code is needed on each page of your questionnare:

navigation();

Layout Customization

The layout of the page and its buttons can be changed with CSS. First some HTML-Code additions are required:

html(
  '<div style="border: 2px solid #CCCCCCCC; border-left: 0 none; border-right: 0 none; padding: 20px 0 12px 0; margin-bottom: 3em;">'.
  '<div class="s2flex NavButtons" style="flex-wrap: wrap; margin-right: -8px">'.NL.
  buttonToPage('start').
  buttonToPage('contact').
  buttonToPage('study').
  buttonToPage('services').
  buttonToPage('documents').
  buttonToPage('notes').
  '<div style="width: 2em;"></div>'.
  buttonToPage('submit').
  '</div>'.
  '</div>'.
);

In the HTML-Template you need to add CSS-statements within the <style> section matching your Survey Layout:

div.NavButtons button {
  border: 2px solid %color.4%;
  border radius: 5px;
  padding: 7px 6px;
  margin-bottom: 8px;
  flex-grow: 1;
  margin-right: 8px;
}
div.NavButtons button.currentPage {
  background color: %color.4%;
  color: white;
}

The second block (button.currentPage) ensures that the navigation button of the current page is highlighted. The function buttonToPage() assigns the CSS-class currentPage to the button which refers to the current page.

Progress Indication

If there is no given order of answering the questions, you might want to show your participants their progress on your survey. For example by showing your participants which pages are complete and which are incomplete.

Navigation with display of the completion status

Therefore you add further CSS-declarations in your questionnare-layout, which show a green hook next to complete pages, and a red cross next to the name of incomplete pages. Both icons are defined in the UTF-8-character set and can be used by their character-codes (2713 and 274C). The current page should not show an icon.

div.NavButtons button.complete:after { content: " \2713"; }
div.NavButtons button.incomplete:after { content: " \274C"; }
div.NavButtons button.currentPage:after { content: none; }

Whether or not the page is completely filled in, the PHP code must check the completeness by using value() or getItems() respectively. The CSS-classes complete and incomplete can then be specified as the fourth parameter in the function buttonToPage(). The second and third parameters remain empty with NULL.

The affiliated PHP-code is saved in *PHP-Functions* of your questionnare and could look like this:

function navigation() {
    // Completion check
    $cContact = (count(array_merge(
        checkItem('KD02', 'KD01_01'),
        checkQst('KD01', [2,3,4,5,6,8]),
        checkItem('KD03', 'KD01_07')
    )) === 0);
 
    $cStart = (
      (count(array_intersect(getItems('KD01', 'valid'), [2,3,4,5,6,8])) == 6) and
      (value('KD02', 'code:ifany') > 0) and
      ((value('KD03', 'code:ifany') > 0) or (value('KD03', 'code:ifany') == -2)
    );
 
    // Here you can run additional checks on ...
    // "study" -> $cStudy
    // "services" -> $cServices
    // "documents" -> $cDocuments
    // ... and so on.
 
 
    // Navigation
    html('<div style="border: 2px solid #CCCCCC; border-left: 0 none; border-right: 0 none; padding: 20px 0 12px 0; margin-bottom: 3em;">'.
      '<div class="s2flex NavButtons" style="flex-wrap: wrap; margin-right: -8px">'.NL.
      buttonToPage('start').
      buttonToPage('contact', NULL, NULL, ($cContact ? 'complete' : 'incomplete')).
      buttonToPage('study', NULL, NULL, ($cStudy ? 'complete' : 'incomplete')).
      buttonToPage('study', NULL, NULL, ($cServices ? 'complete' : 'incomplete')).
      buttonToPage('documents', NULL, NULL, ($cDocuments ? 'complete' : 'incomplete')).
      buttonToPage('notes').
      '<div style="width: 2em;"></div>'.
      buttonToPage('submit').
      '</div>'.
      '</div>'.
    );
    option('nextbutton', 'next form');
}
 
 
function checkQst($qID, $items) {
  $fail = [];
  foreach ($items as $item) {
    $answer = value(id($qID, $item), 'code:ifany');
    if (($answer < -3) or ($answer === '')) {
      $text = preg_replace('/:.*/', '', getItemtext($qID, $item))
      $fail[] = $text;
    }
  }
  return $fail;
}
 
function checkItem($varIDs, $textID) {
  $fail = [];
  if (!is_array($varIDs)) {
    $varIDs = [$varIDs];
  }
  foreach ($varIDs as $varID) {
    $answer = value($varID, 'code:ifany');
    if (($answer < -3) or ($answer === '')) {
      $text = preg_replace('/:.*/', '', getItemtext($textID));
      $fail[] = $text;
      // Only one of them
      break;
    }
  }
  return $fail;
}

Note: The 'code:ifany' in the value() function will hide warnings that would usually appear, if the question has not been asked in the questionnaire, so far.

The following code snippet is responsible for assigning the CSS-class complete or incomplete, which is entered in varied form as the fourth parameter in the function buttonToPage():

    ($cContact ? 'complete' : 'incomplete')

In this particular example the buttons “start”, “notes” and “send” don't have a progress indication.

The PHP-code for the progress indication depends on the individual case of your survey. The functions checkQst() and checkItem() can be helpful in any case. In addition to that, they are created to show your participants a list of missing statements. Those missing statements are shown in a list on the page “submit”.

Individual checks may also become more complicated and must be outsourced to separate functions.

    $cStudy = (count(checkStudy()) === 0);
    $cServices = (count(checkECTS()) === 0);
    $cDocuments = (count(checkDocs()) === 0);