0 votes
ago in SoSci Survey (dt.) by s333375 (120 points)

Guten Tag!

Meine Frage bezieht sich auf die Kombination eines Timers mit einem Schieberegler als Pflichtfrage.

In unserem Experiment gibt es Blöcke, die jeweils aus 2 Seiten bestehen und randomisiert werden. Beide Seiten eines Blocks enthalten jeweils eine Schiebereglerfrage. Diese Fragen sind als Pflichtfragen definiert und müssen aktiv beantwortet werden, bevor zur nächsten Seite gewechselt werden kann.

Zusätzlich läuft ein Timer, der auf der ersten Seite beginnt und auf der zweiten Seite weiterläuft. Nach Ablauf der Zeit soll automatisch zum Beginn des nächsten Blocks weitergeleitet werden, egal, ob der Regler betätigt wurde oder nicht.

Das Problem: Der 2. Schieberegler (auf der 2. Seite des Blocks) muss nicht betätigt werden, obwohl er als Pflichtfrage markiert ist. Man kann einfach auf weiter klicken und kommt dann schon zum nächsten Block, obwohl die Zeit noch nicht abgelaufen ist. Das wollen wir nicht.

Hier der Code

Seite 1 des Blocks (Schieberegler funktioniert)

<script type="text/javascript">

var countdown = %countdown%;
var countdownDisplay;
var countdownTimer;
var buttonID = "submit0";

// Nur auf Blockstartseite: Startzeit setzen
sessionStorage.setItem('blockStart', Date.now());

function countdownStart() {
  countdownDisplay = document.getElementById("countdownDisplay");
  countdownDisplay.style.fontWeight = "bold";
  countdownDisplay.style.fontSize = "90%";
  countdownDisplay.style.textAlign = "left";
  countdownDisplay.style.margin = "0 auto 3em auto";
  countdownDisplay.style.paddingBottom = "0.5em";

  countdownRefresh();
  countdownTimer = window.setInterval(countDown, 1000);
}

function countDown() {
  const start = parseInt(sessionStorage.getItem('blockStart'), 10);
  if (isNaN(start)) return;  // Schutz: wenn blockStart nicht gesetzt

  const now = Date.now();
  const elapsed = Math.floor((now - start) / 1000);
  const remaining = countdown - elapsed;

  if (remaining <= 0) {
    countdownDisplay.textContent = "Nächste Fallvignette wird geladen...";
    clearInterval(countdownTimer);
    document.getElementById(buttonID).click();  // {EM_WHITE_HEAVY_CHECK_MARK} KEIN removeItem() hier!
  } else {
    countdownDisplay.textContent = "Sie erhalten die nächste Fallvignette in " + remaining + " Sekunden";
  }
}

function countdownRefresh() {
  countDown();  // Initialanzeige
}

SoSciTools.attachEvent(window, "load", countdownStart);
</script>

Seite 2 des Blocks

$pageID  = info('pageID');           // z.B. V0102
$seconds = $durPages[$pageID];       // Dein JS-Countdown-Wert

/* 2) Den aktuellen Ablaufwert in eine lokale Variable sichern */
$expiry = $timeout;


/* 3) ALTE Deadline löschen, damit nächste Vignette neu startet */
$timeout = NULL;
registerVariable($timeout);


/* 4) Wenn Zeit abgelaufen → EIN Server-Sprung */
if (time() >= $expiry) {
    goToPage('next');    // oder 'V0201' etc.
    return;
}

/* 5) Sonst: Restzeit an JS übergeben */
replace('%countdown%',$seconds);


<script type="text/javascript">
var countdownDisplay;
var countdownTimer;
var buttonID = "submit0";
var countdown = %countdown%;


function countdownStart() {
  countdownDisplay = document.getElementById("countdownDisplay");
  countdownDisplay.style.fontWeight = "bold";
  countdownDisplay.style.fontSize = "90%";
  countdownDisplay.style.textAlign = "left";
  countdownDisplay.style.margin = "0 auto 3em auto";
  countdownDisplay.style.paddingBottom = "0.5em";

  countdownRefresh();
  countdownTimer = window.setInterval(countDown, 1000);
}

function countDown() {
  const startRaw = sessionStorage.getItem('blockStart');
  if (!startRaw) return;  // Schutz: falls Wert fehlt

  const start = parseInt(startRaw, 10);
  if (isNaN(start)) return;  // Schutz: wenn Wert ungültig

  const now = Date.now();
  const elapsed = Math.floor((now - start) / 1000);
  const remaining = countdown - elapsed;

  if (remaining <= 0) {
    countdownDisplay.textContent = "Nächste Fallvignette wird geladen...";
    clearInterval(countdownTimer);
    sessionStorage.removeItem('blockStart');  // nur hier löschen
    document.getElementById(buttonID).click();
  } else {
    countdownDisplay.textContent = "Sie erhalten die nächste Fallvignette in " + remaining + " Sekunden";
  }
}

function countdownRefresh() {
  countDown();
}

SoSciTools.attachEvent(window, "load", countdownStart);
</script>

Über eine Rückmeldung freue ich mich sehr, vielen Dank!

ago by SoSci Survey (350k points)
Ich vermute stark, dass das Verhalten damit zusammenhängt wie Sie die Rotation der Seiten implementiert haben. Möchten Sie den entsprechenden PHP-Code bitte posten?
ago by s333375 (120 points)
Vielen Dank für die schnelle Rückmeldung. Hier der Code für die Rotation:

/***** 1 | Rotation mischen *****/
$rotation = [
  'A' => 'V0101-V0102',
  'B' => 'V0201-V0202',
  'C' => 'V0301-V0302',
  'D' => 'V0401-V0402',
  'E' => 'V0501-V0502',
  'F' => 'V0601-V0602',
  'G' => 'V0701-V0702',
  'H' => 'V0801-V0802',
  'I' => 'V0901-V0902',
  'J' => 'V1001-V1002',
  'K' => 'V1101-V1102',
  'L' => 'V1201-V1202',];


/***** 1b | Blocks wirklich mischen *****/
$keys = array_keys($rotation);   // A–L
shuffle($keys);                  // zufällige Reihenfolge
$rotationShuffled = [];
foreach ($keys as $k) {
    $rotationShuffled[$k] = $rotation[$k];
}

$rotation = $rotationShuffled;   // ab hier gilt nur noch die gemischte Reihenfolg


/***** 2 | Dauer-Array *****/
$dur = array_merge(array_fill(0,6,51), array_fill(0,6,146));

if (mt_rand(0,1)) {                 // 50 % drehen
    $dur = array_reverse($dur);     // 40,40,20,20
}


/***** 3 | Dauer den einzelnen Seiten zuordnen *****/
$i = 0;
if (!isset($durPages)) { $durPages = []; registerVariable('durPages'); }

foreach ($rotation as $pages) {
    $t = $dur[$i++];                     // EIN Wert pro Block
    foreach (explode('-', $pages) as $pageID) {
        $durPages[$pageID] = $t;         // beide Seiten erhalten dieselbe Zeit
    }
}

/***** 4 | Reihenfolge mit Zwischenseite bauen *****/
$startID  = 'START';
$middleID = 'MID';
$order = [];

$order[] = $startID;  // 1) START ganz am Anfang

$i       = 0;
foreach ($rotation as $pages) {
    $order[] = $pages;    // jeden Vignetten-Block anhängen
    $i++;
    if ($i === 6) {
        // 2) nach genau 6 Blöcken einmalige MID-Seite
        $order[] = $middleID;
    }
}

// Keine array_pop nötig, da wir MID nur einmal kontrolliert einfügen
setPageOrder($order, 'Post');


/* Alles merken, damit spätere Seiten darauf zugreifen können */
registerVariable($rotation);
registerVariable($durPages);

$firstDur  = $dur[0];  // Zeit für die ersten 6 Vignetten
$secondDur = $dur[6];  // Zeit für die nächsten 6 Vignetten


// 3) Variablen registrieren, damit START/MID darauf zugreifen können

registerVariable($firstDur);
registerVariable($secondDur);

$idx = 1;
foreach ($rotation as $blockID => $pages) {
    // Blockbuchstaben sichern
    put(sprintf('RA04_%02d', $idx), $blockID);            // z. B. "C"

    // passende Dauer sichern
    put(sprintf('RA05_%02d', $idx), $dur[$idx - 1]);      // 9 oder 12
    $idx++;
}
ago by SoSci Survey (350k points)
Hmmm ... dieser Code wird auf einer Seite vor der ersten rotierten Seite ausgeführt, korrekt? Ich sehe hier keine direkte Auswirkung auf die Antwortpflicht.

Was zeigt die Debug-Information denn an, wenn Sie den zweiten Schieberegler nicht betätigen und auf Weiter geklickt haben?

Please log in or register to answer this question.

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...