Feature: Support both Free-Text and Multiple-Choice question types
This commit is contained in:
+64
-14
@@ -103,16 +103,42 @@ function renderQuestion(qData) {
|
||||
document.getElementById("attemptBadge").innerText = `Versuch ${attemptsUsed + 1} von ${maxAttempts}`;
|
||||
document.getElementById("frageText").innerText = qData.question;
|
||||
|
||||
const textGroup = document.getElementById("textAnswerGroup");
|
||||
const choiceGroup = document.getElementById("choiceAnswerGroup");
|
||||
const choiceContainer = document.getElementById("choiceOptionsContainer");
|
||||
const input = document.getElementById("answerInput");
|
||||
input.value = "";
|
||||
input.disabled = false;
|
||||
input.focus();
|
||||
|
||||
document.getElementById("checkBtn").disabled = false;
|
||||
document.getElementById("hintBtn").disabled = false;
|
||||
document.getElementById("hintBox").classList.add("hidden");
|
||||
document.getElementById("feedbackBox").innerHTML = "";
|
||||
|
||||
if (qData.question_type === "multiple_choice" && qData.options && qData.options.length > 0) {
|
||||
textGroup.classList.add("hidden");
|
||||
choiceGroup.classList.remove("hidden");
|
||||
choiceContainer.innerHTML = "";
|
||||
|
||||
const letters = ["A", "B", "C", "D", "E", "F"];
|
||||
qData.options.forEach((opt, idx) => {
|
||||
const btn = document.createElement("button");
|
||||
btn.className = "choice-btn";
|
||||
btn.type = "button";
|
||||
btn.innerHTML = `<span class="choice-letter">${letters[idx] || "•"}</span> <span class="choice-text">${opt}</span>`;
|
||||
btn.onclick = () => submitAnswer(opt, btn);
|
||||
choiceContainer.appendChild(btn);
|
||||
});
|
||||
} else {
|
||||
choiceGroup.classList.add("hidden");
|
||||
textGroup.classList.remove("hidden");
|
||||
input.value = "";
|
||||
input.disabled = false;
|
||||
document.getElementById("checkBtn").disabled = false;
|
||||
input.focus();
|
||||
}
|
||||
|
||||
const hintBtn = document.getElementById("hintBtn");
|
||||
if (hintBtn) hintBtn.disabled = false;
|
||||
const hintBtnMC = document.getElementById("hintBtnMC");
|
||||
if (hintBtnMC) hintBtnMC.disabled = false;
|
||||
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
@@ -121,17 +147,28 @@ function updateProgress() {
|
||||
document.getElementById("progressBar").style.width = percent + "%";
|
||||
}
|
||||
|
||||
async function checkAnswer() {
|
||||
function checkAnswer() {
|
||||
const input = document.getElementById("answerInput");
|
||||
const answer = input.value.trim();
|
||||
|
||||
if (!answer) {
|
||||
input.focus();
|
||||
return;
|
||||
}
|
||||
submitAnswer(answer);
|
||||
}
|
||||
|
||||
async function submitAnswer(answer, clickedBtn = null) {
|
||||
const checkBtn = document.getElementById("checkBtn");
|
||||
checkBtn.disabled = true;
|
||||
const input = document.getElementById("answerInput");
|
||||
if (checkBtn) checkBtn.disabled = true;
|
||||
if (input) input.disabled = true;
|
||||
|
||||
// Disable all choice buttons
|
||||
const choiceBtns = document.querySelectorAll(".choice-btn");
|
||||
choiceBtns.forEach(b => b.disabled = true);
|
||||
if (clickedBtn) {
|
||||
clickedBtn.classList.add("choice-selected");
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/game/check", {
|
||||
@@ -157,9 +194,12 @@ async function checkAnswer() {
|
||||
if (result.correct) {
|
||||
// Success!
|
||||
playSound('magic');
|
||||
if (clickedBtn) {
|
||||
clickedBtn.classList.remove("choice-selected");
|
||||
clickedBtn.classList.add("choice-correct");
|
||||
}
|
||||
frageBox.classList.add("sparkle-effect");
|
||||
feedbackBox.innerHTML = `<span class="feedback-correct">✨ Richtig! 1 Hauspunkt für dein Haus! ✨</span>`;
|
||||
input.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
frageBox.classList.remove("sparkle-effect");
|
||||
@@ -175,6 +215,10 @@ async function checkAnswer() {
|
||||
} else {
|
||||
// Incorrect
|
||||
playSound('wrong');
|
||||
if (clickedBtn) {
|
||||
clickedBtn.classList.remove("choice-selected");
|
||||
clickedBtn.classList.add("choice-wrong");
|
||||
}
|
||||
frageBox.classList.add("shake-effect");
|
||||
setTimeout(() => frageBox.classList.remove("shake-effect"), 500);
|
||||
|
||||
@@ -182,12 +226,11 @@ async function checkAnswer() {
|
||||
document.getElementById("attemptBadge").innerText = `Versuch ${Math.min(attemptsUsed + 1, maxAttempts)} von ${maxAttempts}`;
|
||||
|
||||
if (result.attempts_left === 0) {
|
||||
// Exhausted all 3 attempts
|
||||
// Exhausted all attempts
|
||||
feedbackBox.innerHTML = `
|
||||
<div class="feedback-wrong">Leider nicht richtig (3 Fehlversuche).</div>
|
||||
<div class="feedback-revealed">Richtige Lösung: <strong>${result.revealed_answer}</strong></div>
|
||||
`;
|
||||
input.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
if (result.is_finished) {
|
||||
@@ -202,14 +245,21 @@ async function checkAnswer() {
|
||||
} else {
|
||||
// Still attempts remaining
|
||||
feedbackBox.innerHTML = `<span class="feedback-wrong">Leider falsch! Noch ${result.attempts_left} Versuch(e).</span>`;
|
||||
checkBtn.disabled = false;
|
||||
input.select();
|
||||
if (checkBtn) checkBtn.disabled = false;
|
||||
if (input) {
|
||||
input.disabled = false;
|
||||
input.select();
|
||||
}
|
||||
// Re-enable choice buttons
|
||||
choiceBtns.forEach(b => b.disabled = false);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
alert("Netzwerkfehler: " + err.message);
|
||||
checkBtn.disabled = false;
|
||||
if (checkBtn) checkBtn.disabled = false;
|
||||
if (input) input.disabled = false;
|
||||
choiceBtns.forEach(b => b.disabled = false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user