class Quiz { constructor(wrapper, options) { this.wrapper = wrapper; Object.assign(this, options); this.questions = [] this.refresh(); } refresh() { this.get_quiz(); } get_quiz() { frappe.call('erpnext.education.utils.get_quiz', { quiz_name: this.name, course: this.course }).then(res => { this.make(res.message) }); } make(data) { if (data.is_time_bound) { $(".lms-timer").removeClass("hide"); if (!data.activity || (data.activity && !data.activity.is_complete)) { this.initialiseTimer(data.duration); this.is_time_bound = true; this.time_taken = 0; } } data.questions.forEach(question_data => { let question_wrapper = document.createElement('div'); let question = new Question({ wrapper: question_wrapper, ...question_data }); this.questions.push(question) this.wrapper.appendChild(question_wrapper); }) if (data.activity && data.activity.is_complete) { this.disable() let indicator = 'red' let message = 'Your are not allowed to attempt the quiz again.' if (data.activity.result == 'Pass') { indicator = 'green' message = 'You have already cleared the quiz.' } if (data.activity.time_taken) { this.calculate_and_display_time(data.activity.time_taken, "Time Taken - "); } this.set_quiz_footer(message, indicator, data.activity.score) } else { this.make_actions(); } window.addEventListener('beforeunload', (event) => { event.preventDefault(); event.returnValue = ''; }); } initialiseTimer(duration) { this.time_left = duration; var self = this; var old_diff; this.calculate_and_display_time(this.time_left, "Time Left - "); this.start_time = new Date().getTime(); this.timer = setInterval(function () { var diff = (new Date().getTime() - self.start_time)/1000; var variation = old_diff ? diff - old_diff : diff; old_diff = diff; self.time_left -= variation; self.time_taken += variation; self.calculate_and_display_time(self.time_left, "Time Left - "); if (self.time_left <= 0) { clearInterval(self.timer); self.time_taken -= 1; self.submit(); } }, 1000); } calculate_and_display_time(second, text) { var timer_display = document.getElementsByClassName("lms-timer")[0]; var hours = this.append_zero(Math.floor(second / 3600)); var minutes = this.append_zero(Math.floor(second % 3600 / 60)); var seconds = this.append_zero(Math.ceil(second % 3600 % 60)); timer_display.innerText = text + hours + ":" + minutes + ":" + seconds; } append_zero(time) { return time > 9 ? time : "0" + time; } make_actions() { const button = document.createElement("button"); button.classList.add("btn", "btn-primary", "mt-5", "mr-2"); button.id = 'submit-button'; button.innerText = 'Submit'; button.onclick = () => this.submit(); this.submit_btn = button this.wrapper.appendChild(button); } submit() { if (this.is_time_bound) { clearInterval(this.timer); $(".lms-timer").text(""); } this.submit_btn.innerText = 'Evaluating..' this.submit_btn.disabled = true this.disable() frappe.call('erpnext.education.utils.evaluate_quiz', { quiz_name: this.name, quiz_response: this.get_selected(), course: this.course, program: this.program, time_taken: this.is_time_bound ? this.time_taken : 0 }).then(res => { this.submit_btn.remove() if (!res.message) { frappe.throw(__("Something went wrong while evaluating the quiz.")) } let indicator = 'red' let message = 'Fail' if (res.message.status == 'Pass') { indicator = 'green' message = 'Congratulations, you cleared the quiz.' } this.set_quiz_footer(message, indicator, res.message.score) }); } set_quiz_footer(message, indicator, score) { const div = document.createElement("div"); div.classList.add("mt-5"); div.innerHTML = `