Trivia Quiz Maker

Trivia Quiz Maker

Welcome to the trivia quiz! Press Start when ready.

Add New Question

Current Questions

No questions added yet. Use the form above to create your first question.

"; return; } quizData.forEach((q) => { const item = document.createElement("div"); item.className = "tqm-question-item"; item.innerHTML = `

${escapeHTML(q.question)}

`; questionList.appendChild(item); }); // Add event listeners to new buttons questionList.querySelectorAll(".tqm-edit-btn").forEach((btn) => { btn.addEventListener("click", () => handleEditClick(btn.dataset.id)); }); questionList .querySelectorAll(".tqm-delete-btn") .forEach((btn) => { btn.addEventListener("click", () => handleDeleteClick(btn.dataset.id) ); }); } /** * Handles the form submission for adding or updating a question. */ function handleFormSubmit(e) { e.preventDefault(); const questionText = questionTextInput.value.trim(); const options = optionInputs.map((input) => input.value.trim()); const correctIndex = parseInt(correctAnswerSelect.value, 10); const id = questionIdInput.value; if (!questionText || options.some((opt) => !opt)) { alert("Please fill out the question and all four options."); return; } if (id) { // Update existing const index = quizData.findIndex((q) => q.id == id); if (index !== -1) { quizData[index] = { id: Number(id), question: questionText, options, correctIndex }; } } else { // Add new quizData.push({ id: Date.now(), question: questionText, options, correctIndex, }); } resetForm(); renderQuestionList(); initQuiz(); // Update the quiz in Tab 1 } /** * Resets the question form. */ function resetForm() { formTitle.textContent = "Add New Question"; questionIdInput.value = ""; questionForm.reset(); saveQuestionBtn.textContent = "Save Question"; } /** * Populates the form with a question's data for editing. */ function handleEditClick(id) { const question = quizData.find((q) => q.id == id); if (!question) return; formTitle.textContent = "Edit Question"; questionIdInput.value = question.id; questionTextInput.value = question.question; optionInputs.forEach( (input, index) => (input.value = question.options[index]) ); correctAnswerSelect.value = question.correctIndex; saveQuestionBtn.textContent = "Update Question"; questionTextInput.focus(); } /** * Deletes a question from the quiz. */ function handleDeleteClick(id) { if (confirm("Are you sure you want to delete this question?")) { quizData = quizData.filter((q) => q.id != id); renderQuestionList(); initQuiz(); // Update the quiz in Tab 1 } } // --- Tab 1: Quiz Taker Logic --- /** * Initializes the quiz, resets state, and shows the start screen. */ function initQuiz() { currentQuestionIndex = 0; userScore = 0; userAnswers = []; if (quizData.length === 0) { quizIntro.textContent = "No quiz questions have been configured yet. Please go to the 'Quiz Configuration' tab to add questions."; startBtn.disabled = true; } else { quizIntro.textContent = `This quiz has ${quizData.length} question(s). Press Start when ready.`; startBtn.disabled = false; } startScreen.style.display = "block"; questionScreen.style.display = "none"; resultsScreen.style.display = "none"; } /** * Starts the quiz, hiding the start screen and showing the first question. */ function startQuiz() { startScreen.style.display = "none"; questionScreen.style.display = "block"; showQuestion(); } /** * Displays the current question and its options. */ function showQuestion() { if (!quizQuestion || !quizOptions || !quizProgress) return; // Clear previous state quizFeedback.style.display = "none"; nextQuestionBtn.style.display = "none"; const q = quizData[currentQuestionIndex]; quizQuestion.textContent = q.question; quizProgress.textContent = `Question ${currentQuestionIndex + 1} of ${ quizData.length }`; quizOptions.innerHTML = ""; // Clear old options q.options.forEach((option, index) => { const button = document.createElement("button"); button.type = "button"; button.className = "tqm-quiz-option"; button.textContent = escapeHTML(option); button.dataset.index = index; button.addEventListener("click", handleOptionClick); quizOptions.appendChild(button); }); } /** * Handles the user clicking an answer option. */ function handleOptionClick(e) { const selectedIndex = parseInt(e.target.dataset.index, 10); const q = quizData[currentQuestionIndex]; const correctIndex = q.correctIndex; // Disable all option buttons quizOptions.querySelectorAll(".tqm-quiz-option").forEach((btn) => { btn.disabled = true; }); // Store answer for summary userAnswers.push({ question: q.question, selectedAnswer: q.options[selectedIndex], correctAnswer: q.options[correctIndex], isCorrect: selectedIndex === correctIndex, }); if (selectedIndex === correctIndex) { // Correct userScore++; e.target.classList.add("correct"); quizFeedback.textContent = "Correct!"; quizFeedback.className = "correct"; } else { // Incorrect e.target.classList.add("incorrect"); quizFeedback.textContent = "Incorrect!"; quizFeedback.className = "incorrect"; // Highlight the correct answer quizOptions .querySelector(`.tqm-quiz-option[data-index="${correctIndex}"]`) .classList.add("correct"); } quizFeedback.style.display = "block"; nextQuestionBtn.style.display = "inline-block"; // Update "Next" button text if last question if (currentQuestionIndex === quizData.length - 1) { nextQuestionBtn.textContent = "Show Results"; } else { nextQuestionBtn.textContent = "Next Question"; } } /** * Handles click on "Next Question" or "Show Results" button. */ function handleNextClick() { currentQuestionIndex++; if (currentQuestionIndex < quizData.length) { showQuestion(); } else { showResults(); } } /** * Displays the final results screen. */ function showResults() { questionScreen.style.display = "none"; resultsScreen.style.display = "block"; quizScore.textContent = `You got ${userScore} out of ${quizData.length} correct! (${( (userScore / quizData.length) * 100 ).toFixed(0)}%)`; renderResultsSummary(); } /** * Renders the detailed summary of answers. */ function renderResultsSummary() { if (!quizSummary) return; quizSummary.innerHTML = ""; userAnswers.forEach((answer, index) => { const item = document.createElement('div'); item.className = 'tqm-summary-item'; let answerHTML = ''; if (answer.isCorrect) { answerHTML = `
Your answer: ${escapeHTML(answer.selectedAnswer)} (Correct)
`; } else { answerHTML = `
Your answer: ${escapeHTML(answer.selectedAnswer)} (Incorrect)
Correct answer: ${escapeHTML(answer.correctAnswer)}
`; } item.innerHTML = `
Q${index+1}: ${escapeHTML(answer.question)}
${answerHTML} `; quizSummary.appendChild(item); }); } /** * Generates and downloads a PDF of the quiz results. */ function downloadPDF() { if (typeof jsPDF === "undefined") { alert("Error: PDF generation library failed to load."); return; } try { const doc = new jsPDF(); const pageMargin = 20; const pageWidth = doc.internal.pageSize.getWidth() - pageMargin * 2; let yPos = 25; const title = "Quiz Results"; const score = `Final Score: ${userScore} out of ${quizData.length} (${( (userScore / quizData.length) * 100 ).toFixed(0)}%)`; doc.setFont("helvetica", "bold"); doc.setFontSize(18); doc.setTextColor("#34495e"); doc.text(title, pageMargin, yPos); yPos += 10; doc.setFontSize(14); doc.setTextColor("#333333"); doc.text(score, pageMargin, yPos); yPos += 15; userAnswers.forEach((answer, index) => { const qText = `Q${index + 1}: ${answer.question}`; const aTextUser = `Your answer: ${answer.selectedAnswer}`; const aTextCorrect = `Correct answer: ${answer.correctAnswer}`; // Check for page break if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFont("helvetica", "bold"); doc.setFontSize(12); doc.setTextColor("#34495e"); const qLines = doc.splitTextToSize(qText, pageWidth); doc.text(qLines, pageMargin, yPos); yPos += (qLines.length * 5) + 2; // Adjust Y pos for lines doc.setFont("helvetica", "normal"); doc.setFontSize(11); if (answer.isCorrect) { doc.setTextColor("#155724"); // Green doc.text(`${aTextUser} (Correct)`, pageMargin + 5, yPos); yPos += 10; } else { doc.setTextColor("#721c24"); // Red doc.text(`${aTextUser} (Incorrect)`, pageMargin + 5, yPos); yPos += 7; doc.setTextColor("#333333"); doc.text(aTextCorrect, pageMargin + 5, yPos); yPos += 10; } yPos += 5; // Extra spacing }); doc.save("Trivia-Quiz-Results.pdf"); } catch (error) { console.error("Failed to generate PDF:", error); alert("An error occurred while generating the PDF."); } } /** * Utility to escape HTML for safe rendering. */ function escapeHTML(str) { return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /** * Loads sample data (USA-based). */ function loadSampleData() { quizData = [ { id: 1, question: "What is the capital of California?", options: ["Los Angeles", "Sacramento", "San Francisco", "San Diego"], correctIndex: 1 }, { id: 2, question: "Which U.S. state is known as the 'Sunshine State'?", options: ["Arizona", "Texas", "Florida", "Hawaii"], correctIndex: 2 } ]; } // --- Event Listeners --- if (tabButtons[1]) tabButtons[1].onclick = () => showTab(1); if (tabButtons[2]) tabButtons[2].onclick = () => showTab(2); if (prevBtn) prevBtn.onclick = () => showTab(currentTab - 1); if (nextBtn) nextBtn.onclick = () => showTab(currentTab + 1); // Tab 1 Listeners if (startBtn) startBtn.addEventListener("click", startQuiz); if (nextQuestionBtn) nextQuestionBtn.addEventListener("click", handleNextClick); if (restartBtn) restartBtn.addEventListener("click", initQuiz); if (downloadPdfBtn) downloadPdfBtn.addEventListener("click", downloadPDF); // Tab 2 Listeners if (questionForm) questionForm.addEventListener("submit", handleFormSubmit); if (clearFormBtn) clearFormBtn.addEventListener("click", resetForm); // --- Initialization --- function init() { loadSampleData(); renderQuestionList(); initQuiz(); showTab(1); // Set initial tab state } init(); });