function updateTotalTimer() { var timerEls = document.querySelectorAll('.totaltimer') var minutes = Math.floor(state.totalTimer / 60) var seconds = state.totalTimer % 60 var text = minutes + ':' + ('0' + seconds).slice(-2) for (timerEl of timerEls) timerEl.innerHTML = text state.totalTimer++ localStorage.setItem('state', JSON.stringify(state)) } function startTotalTimer() { console.log('Setting totalTimer to ' + state.totalTimer + ' seconds.') updateTotalTimer() state.totalInterval = setInterval(updateTotalTimer, 1000) } function updateSubmitButton() { var button = document.getElementById('quizSubmitButton') var lastQuestion = (state.currentQuestion == (state.questions.length - 1)) button.value = lastQuestion || !getRule('sequential') ? 'Submit Answers' : 'Next Question' } function resetSubmitButton() { updateSubmitButton() document.getElementById('quizSubmitButton').disabled = false } function formatTime(seconds) { return (seconds > 60) ? Math.floor(seconds / 60) + ':' + (('0' + (seconds % 60)).slice(-2)) : seconds + 's' } function updateSubmitTimer() { var button = document.getElementById('quizSubmitButton') if (state.submitTimer > 0) { button.value = 'Wait ' + formatTime(state.submitTimer) button.disabled = true state.submitTimer -= 1 } else { resetSubmitButton() clearInterval(state.submitInterval) if (getRule('sequential') && !getRule('allowQOvertime')) submitQuiz() } } function startSubmitTimer(time) { state.submitTimer = time || state.questions[state.currentQuestion].time || state.submitTime if (state.submitTimer == null) return console.log('Setting submitTimer to ' + state.submitTimer + ' seconds.') updateSubmitTimer() state.submitInterval = setInterval(updateSubmitTimer, 1000) } function showSequentialQuestion() { var questions = document.querySelectorAll('.question') for (q of questions) q.style.display = null updateSubmitButton() if (state.currentQuestion !== null) { var q = document.querySelector('#quiz form #question' + state.currentQuestion) q.style.display = 'block' } } function nextQuestion() { // Save time taken state.questions[state.currentQuestion].timeTaken = state.totalTimer - state.questionStartTotalTimer state.questionStartTotalTimer = state.totalTimer state.currentQuestion++ if (state.currentQuestion == state.questions.length) state.currentQuestion = null showSequentialQuestion() if (state.currentQuestion !== null && getRule('questionTimeout')) startSubmitTimer() return state.currentQuestion } function renderQuiz() { var quizForm = document.querySelector('#quiz form') quizForm.className = '' if (getRule('sequential')) quizForm.classList.add('sequential') quizForm.innerHTML = '' for (const [i, q] of state.questions.entries()) { var html = `
Source/Author: ${q.author || '[No source/author provided]'}
${q.explanation || '[No explanation provided]'}
` el.appendChild(meta) var qinfo = (value.correct) ? '✅ Correct' : '❌ Incorrect' if (q.timeTaken) qinfo += ('. Time taken: ' + formatTime(q.timeTaken)) el.querySelector('h3').innerHTML += ` ` } document.querySelector('#quizSubmitButton').value = 'Back' } function mergeKeyReducer(acc, entry) { if (!acc[entry[0]]) acc[entry[0]] = {answers: [], correct: false} acc[entry[0]].answers.push(entry[1]) return acc } function submitQuiz() { // If not running, we're most likely in review mode. Just switch back. if (state.running == false) changeView('postscreen') if (getRule('sequential')) { var n = nextQuestion() if (n !== null) return } console.log('Submitting quiz. State:') console.log(state) var quizForm = document.querySelector('#quiz form') var data = new FormData(quizForm) var responses = Array.from(data.entries()).reduce(mergeKeyReducer, {}) console.log(responses) var correct = 0 state.responses = [] for (var idx = 0; idx < state.questions.length; idx++) { var value = responses['q'+idx] || {answers: [], correct: false} console.log(idx + ":", value) if (state.questions[idx].type == 'ChooseOne' || state.questions[idx].type == 'ChooseAny') { state.questions[idx].answers.sort() value.answers.sort() } var correctAnswer = JSON.stringify(state.questions[idx].answers) var givenAnswer = JSON.stringify(value.answers) console.log('Comparing: ' + givenAnswer + ' == ' + correctAnswer + '?: ' + (givenAnswer == correctAnswer)) if (givenAnswer == correctAnswer) { value.correct = true correct++ } state.responses.push(value) } console.log(state.responses) var text = '' + correct + '/' + state.questions.length + ' questions answered correctly.' state.success = (correct == state.questions.length) if (!state.success) { state.submitTry++ if (getRule('submitTries') && state.submitTry < state.submitTries) { alert(text + `\nThis was try ${state.submitTry}/${state.submitTries}\nClick OK to Try Again`) renderQuiz() if (getRule('sequential')) { state.currentQuestion = 0 showSequentialQuestion(state.currentQuestion) } if (getRule('submitTimeout')) startSubmitTimer(state.submitTime) } else { document.querySelector('#postscreen h1').innerHTML = (text + '