From 28f9fc3fa8b6ad7866c7ef72f13883af7d6ab7e7 Mon Sep 17 00:00:00 2001 From: adityacp Date: Wed, 9 Sep 2020 17:07:21 +0530 Subject: Show the toc quiz on the student dashboard --- yaksh/forms.py | 2 +- yaksh/models.py | 13 ++- yaksh/static/yaksh/js/show_toc.js | 123 ++++++++++++++++++++++++++ yaksh/templates/base.html | 5 +- yaksh/templates/yaksh/show_lesson_quiz.html | 131 ++++++++++++++++++++++++++++ yaksh/templates/yaksh/show_video.html | 88 ++++++++++--------- yaksh/urls.py | 4 + yaksh/views.py | 51 +++++++++-- 8 files changed, 359 insertions(+), 58 deletions(-) create mode 100644 yaksh/static/yaksh/js/show_toc.js create mode 100644 yaksh/templates/yaksh/show_lesson_quiz.html (limited to 'yaksh') diff --git a/yaksh/forms.py b/yaksh/forms.py index ba8b7d5..440a535 100644 --- a/yaksh/forms.py +++ b/yaksh/forms.py @@ -704,7 +704,7 @@ class VideoQuizForm(forms.ModelForm): {'class': form_input_class, 'placeholder': 'Points'} ) self.fields['type'].widget.attrs.update( - {'class': form_input_class} + {'class': form_input_class, 'readonly': True} ) self.fields['type'].initial = question_type self.fields['description'].widget.attrs.update( diff --git a/yaksh/models.py b/yaksh/models.py index 9ba4afd..851e5c6 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2762,9 +2762,9 @@ class TableOfContents(models.Model): def get_toc_text(self): if self.content == 1: - content_name = Topic.objects.get(id=self.object_id).name + content_name = self.content_object.name else: - content_name = Question.objects.get(id=self.object_id).summary + content_name = self.content_object.summary return content_name def __str__(self): @@ -2779,6 +2779,15 @@ class Topic(models.Model): return f"{self.name}" +class VideoQuizAnswer(models.Model): + toc = models.ForeignKey(TableOfContents, on_delete=models.CASCADE) + student = models.ForeignKey(User, on_delete=models.CASCADE) + answer = models.ForeignKey(Answer, on_delete=models.CASCADE) + + def __str__(self): + return f"Lesson answer of {self.toc} by {self.user.get_full_name()}" + + class MicroManager(models.Model): manager = models.ForeignKey(User, on_delete=models.CASCADE, related_name='micromanaging', null=True) diff --git a/yaksh/static/yaksh/js/show_toc.js b/yaksh/static/yaksh/js/show_toc.js new file mode 100644 index 0000000..121d9e3 --- /dev/null +++ b/yaksh/static/yaksh/js/show_toc.js @@ -0,0 +1,123 @@ +$(document).ready(function() { + $('#sidebarCollapse').on('click', function () { + $('#sidebar').toggleClass('active'); + }); + player = new Plyr('#player'); + var totalSeconds; + store_video_time(contents_by_time); + var time_arr_length = video_time.length; + player.on('timeupdate', event => { + if (time_arr_length > 0 && player.currentTime >= video_time[loc]) { + var content = contents_by_time[loc]; + loc += 1; + if(content.content != 1) { + player.pause(); + url = $("#toc_"+content.id).val(); + ajax_call(url, "GET"); + } + } + }); +}); + +function store_video_time(contents) { + for (var j = 0; j < contents.length; j++) + video_time.push(get_time_in_seconds(contents[j].time)); +} + +function get_time_in_seconds(time) { + var time = time.split(":"); + var hh = parseInt(time[0]); + var mm = parseInt(time[1]); + var ss = parseInt(time[2]); + return hh * 3600 + mm * 60 + ss; +} + +function lock_screen() { + document.getElementById("ontop").style.display = "block"; +} + +function unlock_screen() { + document.getElementById("ontop").style.display = "none"; +} + +function show_error(error) { + var err_msg = ""; + Object.keys(err).forEach(function(key) { + var value = err[key]; + err_msg = err_msg + key + " : " + value[0].message + "\n"; + }); + alert(err_msg); +} + +function show_question(data) { + $("#dialog").html(data); + $("#dialog").dialog({ + width: 600, + height: 500, + }); + $("#submit-quiz-form").submit(function(e) { + e.preventDefault(); + lock_screen(); + var csrf = document.getElementById("submit-quiz-form").elements[0].value; + ajax_call($(this).attr("action"), $(this).attr("method"), $(this).serialize(), csrf); + }); +} + +function select_toc(element) { + var toc_id = element.getAttribute("data-toc"); + var toc_time = $("#toc_time_"+toc_id).val(); + player.currentTime = get_time_in_seconds(toc_time); + url = $("#toc_"+toc_id).val(); + ajax_call(url, "GET"); +} + +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} + +function ajax_call(url, method, data, csrf) { + lock_screen(); + $.ajax({ + url: url, + timeout: 15000, + method: method, + data: data, + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", csrf); + } + }, + success: function(msg) { + unlock_screen(); + if (msg.data) { + show_question(msg.data); + } else { + $("#dialog").dialog("close"); + } + if(msg.message) alert(msg.message); + }, + error: function(xhr, data) { + unlock_screen(); + switch(xhr.status) { + case 400: { + err = JSON.parse(xhr.responseJSON.message); + show_error(err); + break; + } + case 500: { + alert('500 status code! server error'); + break; + } + case 404: { + alert('404 status code! server error'); + break; + } + default: { + alert('Unable to perform action. Please try again'); + break; + } + } + } + }); +} \ No newline at end of file diff --git a/yaksh/templates/base.html b/yaksh/templates/base.html index 7ce653d..53edbee 100644 --- a/yaksh/templates/base.html +++ b/yaksh/templates/base.html @@ -55,9 +55,8 @@