Beispiel:2025-Quiz.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css">  
<title>Multiple-Choice-Quiz - 2025</title>
<style>
#quiz label {
	display: block;
	background-color: lightBlue;
	border: medium solid steelBlue;
      cursor: pointer;
      transition: background-color 0.2s, border-color 0.2s;
    }

    /* Hover-Effekt */
    #quiz label:hover {
      background-color: lightyellow;
    }

    /* mache Fokus sichtbar */
    #quiz input[type="radio"]:focus + label {
      outline: 2px solid black;
      outline-offset: 2px;
    }

    /* Auswahl */
    #quiz input[type="radio"]:checked + label {
      background-color: gold;
      border-color: #866a00;
    }

#quiz input {  /*visually-hidden */
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}
#quiz label {
	border-radius: 0.2em;
	margin: 0.1em 0;
	padding: 1em 2em;
	max-width: 33em;
}

#quiz legend {
  border: thin solid;
  border-radius: 0 0.5em 0.5em;
  padding: 0.5em;
}

#quiz button{
padding: 0.5em;
  font-size: 1.1em;
}
/* listing with solutions */

.question {
	font-weight: bold;
}

.correct {
	color: #0c0;
}

.incorrect {
	color: #c00;
}

.correct:before {
	content: '✓';
	color: #0d0;
}

.incorrect:before {
	content: '✗';
	color: #f00;
}

.correct:before,
.incorrect:before {
	font: 2em bold;
	padding: 0 0.2em;
}

#scores,
#scores td,
#scores th {
	border: 1px solid black;
	border-collapse: collapse;
	text-align: center;
}

</style>
</head>

<body><h1>Multiple-Choice-Quiz zum Jubiläum</h1>
    
<form id="quiz">
	<p id="intro"><img src="https://wiki.selfhtml.org/images/a/a9/Mannheim_Quadratstadt.svg" alt="vereinfachte Darstellung der Quadratestadt Mannheim Mit alten und neuen SELF-Logos" width=300" style="float:right;margin-left:1em"> Zum 10-Jährigen Jubiläum gab es 2005 ein Quiz, 2016 ein Self-Weihnachtsquiz. <br>Es hat lange gedauert, aber zum 30-Jährigen Jubiläum liefern wir eine Neuauflage!</p>
  <button type="submit">Starte Quiz!</button>
</form>

<template id="quizRadiogroup">
  <fieldset role="radiogroup">
    <legend>Frage …</legend>
  </fieldset>
</template>

<script>
document.addEventListener("DOMContentLoaded", function () {
  const JSONUrl = "/extensions/Selfhtml/example.php/Beispiel:2025.json";
  const form = document.getElementById("quiz");
  const intro = document.getElementById("intro");
  const button = form.querySelector("button");
  const template = document.getElementById("quizRadiogroup");

  let questions = [];
  let currentQuestionIndex = 0;
  let results = [];
button.addEventListener("click", async function (e) {
  e.preventDefault();

  if (document.getElementById("intro")) {
    document.getElementById("intro").remove();
    await loadQuestions();
    renderQuestion(currentQuestionIndex);
    button.textContent = "Auswahl bestätigen";
  } else {
    handleSubmit();
  }
});

  async function loadQuestions() {
    try {
      const response = await fetch(JSONUrl);
      const data = await response.json();
      questions = data.data;
    } catch (error) {
      console.error("Fehler beim Laden der Fragen:", error);
    }
  }

  function renderQuestion(index) {
    const questionData = questions[index];
    const oldFieldset = form.querySelector("fieldset");
    if (oldFieldset) oldFieldset.remove();

    const quizContent = template.content.cloneNode(true);
    const fieldset = quizContent.querySelector("fieldset");
    const legend = fieldset.querySelector("legend");

    legend.innerHTML = `${questionData.category}: ${questionData.question}`; //to allow code and pre

    // Clear all children except the legend element
    while (fieldset.children.length > 1) {
      fieldset.removeChild(fieldset.lastChild);
    }

    questionData.answers.forEach((answer, i) => {
      const inputId = `q${index}_a${i}`;

      const input = document.createElement("input");
      input.type = "radio";
      input.name = `q${index}`;
      input.id = inputId;
      input.value = answer.answer;

      const label = document.createElement("label");
      label.htmlFor = inputId;
      label.textContent = answer.answer;

      fieldset.appendChild(input);
      fieldset.appendChild(label);
    });

    form.insertBefore(fieldset, button);
  }

  function handleSubmit() { 
    const selected = form.querySelector(`input[name="q${currentQuestionIndex}"]:checked`);
    if (!selected) {
      alertBox("Bitte wählen Sie eine Antwort aus!", "error");
      return;
    }

    const question = questions[currentQuestionIndex];
    const selectedValue = selected.value;
    const selectedAnswerObj = question.answers.find(a => a.answer === selectedValue);
    const correctAnswer = question.answers.find(a => a.correct);

    const isCorrect = selectedAnswerObj?.correct;

    // Store result
    results.push({
      question: question.question,
      userAnswer: selectedValue,
      isCorrect,
      correctAnswer: correctAnswer.answer,
      explanation: question.explanation || "",
    });

    currentQuestionIndex++;

    if (currentQuestionIndex < questions.length) {
      setTimeout(() => {
        renderQuestion(currentQuestionIndex);
      }, 500);
    } else {
      form.remove(); // remove quiz form
      renderResults();
    }
  }

  function renderResults() {
    const resultList = document.createElement("ol");
    resultList.id = "result";

    results.forEach(result => {
      const li = document.createElement("li");

      const questionP = document.createElement("p");
      questionP.className = "question";
      questionP.innerHTML = result.question;

      const answerP = document.createElement("p");
      answerP.innerHTML = `Ihre Antwort: <em class="${result.isCorrect ? "correct" : "incorrect"}">${result.userAnswer}</em>`;

      const explanationP = document.createElement("p");
      explanationP.innerHTML = `Erläuterung: <em>${result.explanation}</em>`;

      li.appendChild(questionP);
      li.appendChild(answerP);
      li.appendChild(explanationP);

      resultList.appendChild(li);
    });

    const score = results.filter(r => r.isCorrect).length;
    const total = results.length;
    const scoreSummary = document.createElement("p");
    const percentage = Math.round((score / total) * 100);
    scoreSummary.innerHTML = `<strong>Ergebnis:</strong> ${score} von ${total} Fragen richtig beantwortet (${percentage}%).`;

    document.body.appendChild(scoreSummary);
    document.body.appendChild(resultList);
  }

  function alertBox(text, type) {
    const alert = document.createElement("p");
    alert.textContent = text;
    alert.className = type;
    form.appendChild(alert);
    setTimeout(() => alert.remove(), 3000);
  }
});
</script>

</body>
</html>