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 updateSubmitTimer() {
var button = document.getElementById('quizSubmitButton')
if (state.submitTimer > 0) {
timetext = state.submitTimer > 60 ?
Math.floor(state.submitTimer/60)+':'+(('0' + (state.submitTimer%60)).slice(-2)) :
state.submitTimer + 's'
button.value = 'Wait ' + timetext
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() {
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 = `
`
html += `
Question #${i+1}
`
html += `
${q.question}
`
if (q.picture)
html += ``
if (q.type == 'ChooseOne' || q.type == 'ChooseAny') {
var choices = Array.from(q.choices.entries())
var shuffled = choices.sort(() => Math.random() - 0.5)
for ([ci, c] of shuffled)
html += (q.type == 'ChooseOne')
? ` `
: ` `
} else if (q.type == 'Text') {
// If choices were given, use them as labels, otherwise use generic label
for ([ai, a] of q.answers.entries())
html += ``
}
html += '
'
quizForm.innerHTML += html
}
}
function startQuiz() {
state.success = false
console.log('Starting/Resuming quiz. State:')
console.log(state)
renderQuiz()
changeView('quiz')
if (getRule('sequential'))
showSequentialQuestion(state.currentQuestion)
if (state.submitTimer > 0)
startSubmitTimer(state.submitTimer)
else if (getRule('questionTimeout'))
startSubmitTimer()
else
resetSubmitButton()
startTotalTimer()
state.running = true
console.log('Quiz started/resumed')
}
function reStartQuiz() {
console.log('Restarting quiz');
state.responses = defaultState.responses
state.currentQuestion = defaultState.currentQuestion
state.success = defaultState.success
state.submitTry = defaultState.submitTry
state.submitTimer = defaultState.submitTimer
state.submitInterval = defaultState.submitInterval
state.totalTimer = defaultState.totalTimer
state.totalInterval = defaultState.totalInterval
changeView('prescreen')
}
function createQuiz(e) {
e.preventDefault()
console.log('Creating new quiz')
clearState()
removeLink()
state.title = document.getElementById('titleField').value
state.style = document.getElementById('styleField').value
// After state.style is set
applyRuleSettingsFromForm()
if (parseSpreadsheet().success == false) {
alert('Quiz creation failed.')
return
}
console.log('Spreadsheet parsing successful')
updateTitles()
changeView('prescreen')
console.log('Quiz created:')
console.log(state)
return false
}
function endQuiz() {
console.log('Ending quiz')
state.running = false
localStorage.removeItem('state')
//document.querySelector('#quiz form').innerHTML = ''
changeView('postscreen')
if (state.submitInterval)
clearInterval(state.submitInterval)
clearInterval(state.totalInterval)
console.log('Quiz ended')
}
function showQuizResults() {
var quizForm = document.querySelector('#quiz form')
quizForm.className = ''
console.log('Showing quiz results...')
changeView('quiz')
for (var [idx, value] of state.responses.entries()) {
console.log(idx + ':', value)
var el = document.getElementById('question' + idx)
// Mark question correct or incorrect
el.classList.add(value.correct ? 'correct' : 'incorrect')
var q = state.questions[idx]
// traverse correct answers
if (state.questions[idx].type == 'Text') {
for (var [i, ans] of q.answers.entries()) {
var inp = el.querySelectorAll('input')[i]
if (inp.value == ans)
inp.classList.add('right')
else {
var note = document.createElement('p')
note.innerHTML = ans
inp.parentElement.appendChild(note)
}
}
} else {
for (var ans of q.answers)
el.querySelector(`input[value="${ans}"]`).classList.add('trueans')
}
var meta = document.createElement('div')
meta.className = 'meta'
meta.innerHTML = `