Inhaltsverzeichnis

Fragen bei Auswahl einer bestimmten Option sofort einblenden

Filterfragen ermöglichen es zwar, Inhalte bzw. Fragen in Abhängigkeit früherer Antworten anzuzeigen – aber manchmal soll eine zusätzliche Frage direkt auf derselben Fragebogen-Seite erscheinen. In diesem Fall spricht man von dynamischen Inhalten, weil sich die Anzeige verändert, ohne dass eine neue HTML-Seite vom Browser übermittelt wurde. Dynamische Veränderungen der Seite erfordern JavaScript, eine Programmiersprache, die im Browser des Teilnehmers läuft. Der Server erfährt zunächst nichts von den Änderungen, er erhält die Antworten erst nach dem Klick auf „Weiter“.

Prinzipiell sind mit JavaScript und dem Document Object Model (DOM) sehr umfassende Modifikationen innerhalb einer Fragebogenseite möglich, allerdings erfordert dies mitunter fortgeschrittene Programmier-Kenntnisse. Diese Anleitung beschränkt sich darauf, wie man damit eine Frage in Abhängigkeit einer Antwort ein- bzw. ausblendet.

Tipp: Falls der JavaScript-Code nicht auf Anhieb funktioniert, nutzen Sie bitte zur Fehlersuche die Entwickler-Tools im Browser.

Grundwissen

  1. In JavaScript gibt es so genannte Event Handler. Das sind Funktionen, die durch Aktionen des Nutzers auf der Seite ausgelöst werden. Die Aktionen erzeugt ein Event, und dieses löst die verbundene JavaScript-Funktion, den EventHandler aus. Mögliche Events sind …
    • 'click' – der Klick auf ein Element,
    • 'mouseover' – das Bewegen der Maus über ein Element,
    • 'change' – die Auswahl einer Option in einem Dropdown oder die Änderung eines Texteingabefelds,
    • 'keypressed' – ein Tastendruck
    • und viele andere.
  2. Jedes Element einer (HTML-)Internetseite hat eine ganze Reihe von Eigenschaften. SoSci Survey erstellt die einzelne Fragebogen-Seite als HTML-Seite – und alle Fragen und Eingabefelder sind ihrerseits HTML-Elemente, deren Eigenschaften durch JavaScript beeinflusst werden können. Eine solche Eigenschaft ist der Darstellungsstil (style) und ein Teil davon ist der Anzeigemodus (display). Der Anzeigemodus definiert, wie ein Element angezeigt wird (block oder inline) oder dass es eben nicht angezeigt wird (none).
  3. Die Elemente einer HTML-Seite lassen sich am einfachsten anhand ihrer HTML-ID ansprechen. SoSci Survey vergibt für alle Eingabefelder automatisch HTML IDs, die sich an der Frage- bzw. Itemkennung orientieren.
    • Am einfachsten ermitteln Sie die ID eines Elements mit den Entwickler-Tools im Browser. Diese Werkzeuge können Ihnen den HTML-Code eines Elements (z.B. eines Auswahlfeldes) zeigen – inkl. der HTML-ID (id="AB01_01"). Wenn Sie in den Entwickler-Werkezugen den „Inspektor“ auswählen, können Sie ein Element der Seite einfach anklicken, um die passenden Informationen zu finden. Alternativ können Sie sich den Quelltext der HTML-Seite im Browser anzeigen lassen und dort das entsprechende Element suchen.
    • Für Fragen vergibt SoSci Survey jeweils eine HTML-ID bestehend aus der Frage-Kennung, einem Unterstrich (_) und qst (z.B. AB01_qst für Frage „AB01“).
  4. In SoSci Survey kann man beliebige Inhalte in eine Fragebogenseite aufnehmen. Also auch JavaScript Code. Dies geschieht am einfachsten, indem man den Code unter Textbausteine u. Beschriftung als Textbaustein speichert (für die Darstellung muss man „HTML-Code“ auswählen) und diesen Textbaustein beim Fragebogen zusammenstellen in die Seite zieht. Und zwar unter die jeweilige Frage(n).

Hinweis: Sie sollten den JavaScript Code so gestalten, dass er die nicht-benötigten Inhalte ausblendet – nicht die benötigten einblendet. Das hat den Vorteil, dass Teilnehmer mit deaktiviertem JavaScript die Frage trotzdem beantworten können, weil sie hier gar nicht erst ausgeblendet wird.

Hinweis: Screenreader, die es Menschen mit Sehbehinderung erlauben, an Ihrer Befragung teilzunehmen, kommen mit dynamischen Inhalten nicht immer zurecht. Durch Verwendung dieser Funktion kann sich die Barrierefreiheit Ihres Fragebogens reduzieren.

Hinweis: Einige Fragetypen verwenden in der Standard-Einstellung je nach Bildschirm eine andere Darstellung (responsive Layout). In seltenen Fällen wird die Darstellung nicht korrekt gewählt, wenn Sie solch eine Frage per JavaScript einblenden. In diesem Fall stellen Sie für Darstellung in der Frage bitte eine andere Option als „dynamisch“ ein.

Hinweis: Wenn Sie eine einfache Auswahl oder Skala (also keine Mehrfachauswahl) als Filterfrage verwenden und im Fragebogen die Option „Kreuzchen in einfacher Auswahl oder Skala abwählbar“ aktiviert haben, so liefert die Eigenschaft checked nach dem Abwählen einer Option weiterhin true statt false. Verwenden Sie in diesem Fall das Event change statt click.

Tipp: Wenn der Teilnehmer sieht, dass eine der Auswahloptionen mit zusätzlicher Arbeit verbunden ist, dann könnte dies sein Antwortverhalten beeinflussen. Ein klassischer Filter mit Abfrage der zweiten Frage auf der Folgeseite kann hier sinnvoller sein.

Sichtbare Auswahl

Abhängig von einer Ja/Vielleicht/Nein-Frage („JN01“, sichtbare Auswahl) soll eine offene Textfrage („TX01“) angezeigt werden.

Der folgende JavaScript-Code wird als Textbaustein gespeichert (Darstellung:HTML-Code“) und unter den Fragen „JN01“ und „TX01“ in die Fragebogen-Seite gezogen.

<script type="text/javascript">
<!--
var optionA = document.getElementById("JN01_01a");  // JN01_01a ist die HTML-ID der Auswahloption "Ja"
var optionB = document.getElementById("JN01_02a");  // Option "Vielleicht"
var optionC = document.getElementById("JN01_03a");  // Option "Nein"
var frage = document.getElementById("TX01_qst");  // HTML-ID der Texteingabe
 
function toggle() {
  // Die zwei Pipes (||) sind ein logisches "Oder"
  // Die Bedingung prüft also: Ist Option A ausgewählt oder ist B ausgewählt?
  if (optionA.checked || optionB.checked) {
    // Wurde "Ja" oder "Vielleicht" ausgewählt, dann wird die Frage angezeigt
    // Keine Angabe ("") verwendet die Standard-Einstellung (normal anzeigen)
    frage.style.display = "";
  } else {
    // Mit der Anzeigeoption "none" wird die Frage ausgeblendet
    frage.style.display = "none";
  }
}
 
// Die Funktion soll jedesmal ausgeführt werden, wenn eine der drei Optionen angeklickt wird
SoSciTools.attachEvent(optionA, "click", toggle);
SoSciTools.attachEvent(optionB, "click", toggle);
SoSciTools.attachEvent(optionC, "click", toggle);
 
// Und jetzt gleich soll sie auch ausgeführt werden, damit die Anzeige zu Beginn korrekt ist
// (z.B. ausblenden der Texteingabe zu Beginn)
toggle();
// -->
</script>

Pflichtfragen

Damit Fragen dynamisch eingeblendet werden können, müssen sie schon (unsichtbar) auf der Seite vorhanden sein. Blenden Sie keine Pflichtfragen ein/aus: Auch wenn der Teilnehmer unsichtbare Fragen nicht beantworten kann, besteht SoSci Survey bei Pflichtfragen auf eine Antwort.

Wenn Sie die Antwort auf eine (womöglich) ausgeblendete Frage prüfen möchten, verwenden Sie eine Individuelle Antwortprüfung. Dort prüfen Sie, ob die Frage ausgeblendet oder beantwortet wurde. Falls nicht, zeigen Sie die Seite erneut an.

Nachfolgend ein Beispiel-Code passend zum obigen Beispiel mit der sichtbaren Auswahl. Bitte denken Sie daran, dass der PHP-Code entweder unten auf der Seite bei „Verarbeitung der Antworten mittels PHP“ eingetragen werden muss oder oben auf der nächsten Seite des Fragebogens.

if (
    // Wird die Frage TX01 angezeigt?
    ((value('JN01') == 1) || (value('JN01') == 2)) &&
    // Fehlt die Antwort bei der Texteingabe-Frage TX01?
    (trim(value('TX01_01')) == '')
) {
    // Seite erneut anzeigen
    repeatPage();
}

Mehrere gleichartige Fragen

Mitunter kommt es vor, dass dieselbe Funktion auf einer Fragebogen-Seite mehrfach zum Einsatz kommt. Wenn wir das vorige Beispiel nehmen: Nehmen wir einmal an, dass auf der Seite nicht nur eine Auswahl mit Zusatzfrage ist, sondern vier Auswahlfragen mit vier Zusatzfragen.

Die naheliegende Lösung wäre es, den JavaScript-Code zu kopieren. Das funktioniert aber nicht ohne weiteres, weil die Variablen (optionA, optionB) und auch der Name der Funktion (toggle()) sich dann gegenseitig in die Quere kommen. Wenn Sie sich für das Kopieren entscheiden, müssten Sie also bei jeder Kopie andere Namen für die Variablen und Funktionen verwenden. Aber es geht auch eleganter.

Nachfolgend wird der JavaScript-Code von oben in eine Funktion bzw. Klasse DynamicFilter() gekapselt. Die 4 Auswahl-Zusatzfrage-Tupel unterscheiden sich in den Kennungen von Auswahlfrage und Zusatzfrage. Entsprechend hat die Funktion zwei Parameter auswahlID und frageID. Diese Parameter werden für die Kennungen in den ersten Zeilen verwendet: Aus „JN01_01a“ wird dann auswahlID + „_01“.

Diese Anleitung lässt das <script>-Tag zu Beginn weg, wenn Sie den Code verwenden, müssen Sie natürlich ganz zu Beginn das <script type=„text/javascript“> und am Ende das </script> ergänzen.

function DynamicFilter(auswahlID, frageID) {
    var optionA = document.getElementById(auswahlID  + "_01a");  // JN01_01a ist die HTML-ID der Auswahloption "Ja"
    var optionB = document.getElementById(auswahlID  + "_02a");  // Option "Vielleicht"
    var optionC = document.getElementById(auswahlID  + "_03a");  // Option "Nein"
    var frage = document.getElementById(frageID + "_qst");  // HTML-ID der Texteingabe
 
    function toggle() {
      // Die zwei Pipes (||) sind ein logisches "Oder"
      // Die Bedingung prüft also: Ist Option A ausgewählt oder ist B ausgewählt?
      if (optionA.checked || optionB.checked) {
        // Wurde "Ja" oder "Vielleicht" ausgewählt, dann wird die Frage angezeigt
        // Keine Angabe ("") verwendet die Standard-Einstellung (normal anzeigen)
        frage.style.display = "";
      } else {
        // Mit der Anzeigeoption "none" wird die Frage ausgeblendet
        frage.style.display = "none";
      }
    }
 
    // Die Funktion soll jedesmal ausgeführt werden, wenn eine der drei Optionen angeklickt wird
    SoSciTools.attachEvent(optionA, "click", toggle);
    SoSciTools.attachEvent(optionB, "click", toggle);
    SoSciTools.attachEvent(optionC, "click", toggle);
 
    // Und jetzt gleich soll sie auch ausgeführt werden, damit die Anzeige zu Beginn korrekt ist
    // (z.B. ausblenden der Texteingabe zu Beginn)
    toggle();
}
 
 
// -->
</script>

Alles andere bleibt gleich. Nun muss diese Klassen-Funktion noch aufgerufen werden, um eine neue Instanz der Klasse zu initialisieren. Dafür benötigt man das Schlüsselwort new.

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

Mit diesem Aufruf zusammen funktioniert der Code wie im vorigen Beispiel. Aber natürlich kann man diese eine Zeil mit weiteren Kennungen mehrfach wiederholen:

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

So lässt sich derselbe Filter sehr übersichtlich mehrfach auf einer Seite verwenden. So einfach funktioniert das natürlich nur dann, wenn alle Filterfragen und Folgefragen dieselbe Struktur haben. Durch das Kapseln in einer Funktion kann man aber generell das Problem umgehen, dass die Variablen unterschiedliche benannt sein müssen.

Eine zusätzliche Frage („DD02“) soll abhängig davon angezeigt werden, ob in einer Dropdown-Auswahl („DD01“) eine bestimmte Option (z.B. jene mit Antwortcode „7“) ausgewählt wurde.

<script type="text/javascript">
<!--
var dropdown = document.getElementById("DD01");  // Das Eingabefeld der Frage DD01
var frage = document.getElementById("DD02_qst");  // Die Frage DD02, die ein-/auszublenden ist
 
function toggle() {
  if (dropdown.value == "7") {  // Hier den Wert (Antwortcode) eintragen, bei dem das zweite Dropdown eingeblendet werden soll
    frage.style.display = "";
  } else {
    frage.style.display = "none";
  }
}
 
SoSciTools.attachEvent(dropdown, "change", toggle);  // Bei einer Änderung der Auswahl die Anzeige anpassen
SoSciTools.attachEvent(dropdown, "click", toggle);  // Auch beim Klick prüfen - sonst wird die Änderung evtl. erst beim Verlassen des Dropdowns wirksam
toggle();  // Und zu Beginn auch die korrekte Anzeige sicherstellen
// -->
</script>

Rangordnung

Bei einer Rangordnungsfrage (z.B. „RK01“) lässt sich die Änderung effizient über die von SoSci Survey bereitgestellte JavaScript-Instanz überwachen. Der folgende Beispiel-Code zeigt die Frage „AB01“ an, wenn das Kärtchen 2 auf den Rangplatz 1, 2 oder 3 gelegt wird.

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

Alternative Fragen anbieten

Sie haben eine Dropdown-Auswahl „AB05“ und möchten abhängig von der Auswahl eine weitere Auswahl anbieten. Dafür muss im vorliegenden Beispiel neben der ersten Auswahl (Lieblingsstadt) für jede Stadt eine weitere Auswahl (Sehenswürdigkeit) erstellt und auf der Seite eingebunden werden.

Ergebnis im Fragebogen

Tipp: Falls Sie auch eine sichtbare Auswahl in Erwägung ziehen, ermöglicht die Erweiterten Auswahl eine hierarchische Auswahl von Optionen bereits in einer dynamischen Variante.

Tipp: Das dynamische Einblenden von Fragen funktioniert auch in Kombination mit der Platzierung von Fragen nebeneinander.

Fragebogen-Seite

Vielleicht können Sie einmal nicht mit den standardmäßig vorhandenen HTML-IDs arbeiten – etwa deshalb, weil Sie eine Frage mehrfach auf der Seite einbinden und jeweils unterschiedliche Items anzeigen. In diesem Fall werden die einzublendenden Fragen mit DIV-Elementen umschlossen. Dadurch wird die Fragebogen-Seite recht lang. Für die erste Frage ist als Abstand zur nächsten Frage der Wert 4 Pixel eingestellt (Einstellungen zur Anzeige der Frage).

Fragebogen-Seite mit allen notwendigen Elementen

JavaScript-Code

Der folgende HTML-/JavaScript-Code wird in einem Textbaustein (z.B. mit der Kennung „js_dynamic“, Darstellung:HTML-Code“) gespeichert:

<script type="text/javascript">
<!--
var dropdown = document.getElementById("AB05");
 
function blender() {
  // Der Wert in value entspricht dem Antwortcode in der Variablen-Übersicht
  var auswahl = dropdown.value;
  // Allerdings ist der Wert zunächst keine Zahl, sondern ein Text
  auswahl = parseInt(auswahl);
 
  // Diese Prüfung wird für jede einzublendende Frage wiederholt
  var frage1 = document.getElementById("blockAB06");
  if (auswahl == 1) {
    // Anzeigen
    frage1.style.display = "";
  } else {
    // Ausblenden
    frage1.style.display = "none";
  }
 
  var frage2 = document.getElementById("blockAB07");
  if (auswahl == 2) {
    frage2 .style.display = "";
  } else {
    frage2 .style.display = "none";
  }
 
  var frage3 = document.getElementById("blockAB08");
  if (auswahl == 3) {
    frage3 .style.display = "";
  } else {
    frage3 .style.display = "none";
  }
}
 
// Die Funktion sollte zunächst einmal direkt aufgerufen werden,
// es müssen ja alle Dropdowns ausgeblendet werden
blender();
 
// Nun muss die Funktion noch mit dem change-Ereignis des ersten
// Dropdowns verknüpft werden
SoSciTools.attachEvent(dropdown, "change", blender);
SoSciTools.attachEvent(dropdown, "click", blender);
 
// -->
</script>

Beispiel 4: Skala

In diesem Beispiel soll ein Skalenitem mit 5 Auswahlmöglichkeiten (1=„überhaupt nicht“ bis 5=„sehr häufig“) mit einem Textfeld gekoppelt werden. Das Textfeld soll nur angezeigt werden, wenn mindestens 3 („hin und wieder“) ausgewählt wurde.

Außerdem soll die Lösung nicht nur für ein Item-Pärchen genutzt werden, sondern gleich für eine ganze Batterie (10 Skalen-Items und 10 Texteingabefelder, welche als Kombinierte Fragen dargestellt werden). Damit das funktioniert, ohne dass der komplette Code 10-mal wiederholt werden muss, wird die JavaScript-Funktionnalität als Klasse (function) gekapselt. Diese Klasse wir dann für jedes der 10 Items genau einmal aufgerufen.

Im folhenden Beispiel haben die Items folgende Kennungen:

Der JavaScript-Code für die 10 Item-Pärchen würde wie folgt aussehen. Ein großer Teil des Codes entfällt dabei (ganz oben) darauf, erst einmal die Auswahlfelder eines jeden Skalenitems zu finden. Das hat den Vorteil, dass der Code unabhängig vom eingestellten Skalenniveau und unabhängig von Ausweichoptionen funktioniert.

Der Kern der Funktion, welcher das Eingabefeld ein- und ausblendet ist wieder das element.style.display = "none";

<script type="text/javascript">
 
/**
 * Auswahlfelder (radio) der Skala mit der
 * Kennung itemID finden und auflisten.
 */
function getScaleInputs(itemID) {
    var inputs = {};
    // Einmal die regulären Auswahlfelder
    for (var i=1; i<100; i++) {
        var inputID = itemID + i;
        var input = document.getElementById(inputID);
        if (input) {
            inputs[i] = input;
        } else {
            break;
        }
    }
    // Und dann könnte es noch Ausweichoptionen geben
    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;
}
 
/**
 * Die Klasse, welche das Skalenitem (Kennung itemID) mit
 * einem Eingabefeld (o.ä.) mit der Kennung inputID verbindet.
 * In dem Array show wird definiert, bei welchen Werten das
 * Eingabefeld oder Element angezeigt werden soll.
 */
function linkScaleToInput(itemID, inputID, show) {
    // Wir benötigen zunächst alle Auswahldfelder des Skalenitems
    var radio = getScaleInputs(itemID);
    var element = document.getElementById(inputID);
 
    // Wir brauchen eine Funktion, um den
    // in der Skala ausgewählten Wert zu ermitteln.
    function getValue() {
        for (var value in radio) {
            if (radio[value].checked) {
                return parseInt(value);
            }
        }
        return -9;
    }
 
    // Und dann benötigen wir eine Funktion,
    // welche auf eine Auswahl reagiert
    function onSelect() {
        var value = getValue();
 
        // Anzeigen, wenn der Wert in show gelistet wurde,
        // oder mittels display=none verbergen
        if (show.indexOf(value) > -1) {
            element.style.display = "";
        } else {
            element.style.display = "none";
        }
    }
 
    for (var value in radio) {
        radio[value].addEventListener("click", onSelect);
    }
 
    // Zu Beginn die Anzeige korrekt wählen
    onSelect();
}
 
// Eine Instanz der Klasse für jedes Item der Skala
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>