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

Hallo,

wir haben ein Experiment erstellt mit zweiseitigen Blöcken, die randomisiert werden (siehe Beispielcode):

// Erstellung des Arrays der Blöcke: 

$rotation = array(
'A' => 'V0101-V0102',   
'B' => 'V0201-V0202',   
'C' => 'V0301-V0302',
'D' => 'V0401-V0402');

// Reihenfolge der Blöcke zufällig mischen
shuffle($rotation);

setPageOrder($rotation, 'ENDE');

Jetzt wollen wir zusätzlich noch einen Timer einbauen. Dieser soll einmal 20s und einmal 40s betragen und dabei sollen die Hälfte der Blöcke 20s und die andere 40s als Timer erhalten (dabei soll auch randomisiert werden ob erst die Blöcke mit 20s und 40s angezeigt werden). Den Code damit der Timer über den ganzen Block (also zwei Seiten) hinweg abläuft haben wir schon. Diesen habe ich auch am Ende des Posts angehängt.

Frage: Da es jetzt schon eine Randomisierung der Blöcke (siehe Code oben) gibt, wäre es unseres Erachtens nach am einfachsten nach eben dieser Randomisierung im gleichen Code die Randomisierung des Timers und die Zuweisung des Timers pro Block zu realisieren.

Leider hat unser Code bisher nicht funktioniert. Ist unsere Idee prinzipiell möglich und wenn ja: Könnten Sie uns einen Tipp geben, wie wir dies am besten angehen? Ich habe hier den Ansatz unseres Codes angehängt, welcher leider nicht funktioniert. Ich hoffe der Post ist einigermaßen verständlich Vielen Dank im Vorraus!

Ansatz Code Randomisierung:

/* 1. Vier Vignetten-Blöcke definieren und mischen */
$rotation = array(
  'V0101-V0102',  // Vignette 1
  'V0201-V0202',  // Vignette 2
  'V0301-V0302',  // Vignette 3
  'V0401-V0402'   // Vignette 4
);

shuffle($rotation);

// 2. Paarungen [20,40] und [40,20] mischen und das erste Paar übernehmen
$pairs = [
    [20, 40],
    [40, 20]
];

shuffle($pairs);

list($firstTime, $secondTime) = $pairs[0];

// 3. Erste 2 Vignetten = $firstTime, letzte 2 = $secondTime
$durations = [];
foreach (array_slice($rotation, 0, 2) as $block) {
    $durations[$block] = $firstTime;
}
foreach (array_slice($rotation, 2, 2) as $block) {
    $durations[$block] = $secondTime;
}

// 4. Reihenfolge in SoSciSurvey setzen
setPageOrder($rotation, 'TiA');

// 5. Zeitwerte in Teilnehmer-Variablen speichern
//    (mit der globalen set()-Funktion)
foreach ($durations as $block => $time) {
    $varName = 'time_' . str_replace('-', '_', $block);
    set($varName, $time);
}



**Timer S1 :** 


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

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

function countdownStart() {
  countdownDisplay = document.createElement("div");
  countdownDisplay.style.fontWeight = "bold";
  countdownDisplay.style.textAlign = "center";
  countdownDisplay.style.margin = "0 auto 3em auto";
  countdownDisplay.style.paddingBottom = "1em";
  document.body.insertBefore(countdownDisplay, document.body.firstChild);

  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 = 30 - 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>


**Timer S2** 

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

function countdownStart() {
  countdownDisplay = document.createElement("div");
  countdownDisplay.style.fontWeight = "bold";
  countdownDisplay.style.textAlign = "center";
  countdownDisplay.style.margin = "0 auto 3em auto";
  countdownDisplay.style.paddingBottom = "1em";
  document.body.insertBefore(countdownDisplay, document.body.firstChild);

  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 = 30 - 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>

1 Answer

0 votes
ago by SoSci Survey (347k points)

Ich würde empfehlen, dass Sie die Rotation über einen Zufallsgenerator erledigen und nicht via shuffle(). Das macht es deutlich besser kontrollierbar. Das gilt auch für die Zuordnung der Zeiten.

Was mir bei Ihrem Timer fehlt, ist ein PHP-Part, welcher dafür sorgt, dass der Timer über mehr als eine Seite läuft. Sie arbeiten mit sessionStorage ... ich würde hier die Lösung empfehlen, wie sie in der Anleitung steht: Timer: Countdown über mehrere Seiten

Wenn Sie eigenen Code verwenden, müssen Sie auch selbst ein wenig ins Debugging einsteigen. Die Fehlerkonsole im Browser ist da ein recht guter Startpunkt. Meine Vermutung wäre, dass Sie pro Block einen anderen Storage verwenden müssen.

ago by s333376 (120 points)
Hallo und vielen Dank für Ihre Antwort.

Könnten Sie mir einen Ansatz geben wie ich die Zuordnung der Zeiten mit dem Zufallsgenerator erledigen lassen kann? Ich finde leider keine sinnvolle Lösung bzw mir fällt keine ein.

Eine Idee die ich hätte wäre es die Rotation so zu lassen wie sie ist und anschließend nur noch die Zeiten zuzuordnen. Aber ich bin natürlich auch offen dafür, beides über den Zufallsgenerator laufen zu lassen.

Die Timer funktionieren ja bisher, diesen muss nur noch die richtige Zeit zugewiesen werden. Aber wir können natürlich auch die Version aus der Anleitung nehmen.

Vielen Dank und viele Grüße
ago by SoSci Survey (347k points)
> dabei sollen die Hälfte der Blöcke 20s und die andere 40s als Timer erhalten (dabei soll auch randomisiert werden ob erst die Blöcke mit 20s und 40s angezeigt werden)

Auch Ihrem Code und der Beschreibung schließe ich, dass die Reihenfolge nur 20,20,40,40 oder 40,40,20,20 sein kann. Also nur zwei Möglichkeiten.

Sie könnten in den Zufallsgenerator diese beiden Zeilen schreiben ...

1 = 20,20,40,40
2 = 40,40,20,20

... und dann mittels value(..., 'csv') die 4 Werte als Array auslesen, und jeweils den passenden nehmen. Oder Sie arbeiten direkt mit dem Code 1/2, denn dieser bestimmt ja eindeutig, welche Zeit auf welcher Seite verwendet werden soll.

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

...