From 2db246f7abb2b8781e60673edec9912166621f4c Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 18 Feb 2020 13:29:24 +0530 Subject: Change forms, views, models, templates - Fix UI in add question page - Add test case form for question formset with custom attributes - Add a model method in question class to get question test cases based on type and language of the question - Retain the state of the list view and grid view in courses page - Requested students list will be shown on top in the course detail page --- yaksh/forms.py | 14 +- yaksh/models.py | 54 +++++++ yaksh/static/yaksh/js/add_question.js | 159 ++++++++++--------- yaksh/static/yaksh/js/course.js | 1 + yaksh/static/yaksh/js/show_courses.js | 39 +++++ yaksh/templates/yaksh/add_question.html | 243 +++++++++++++++++------------ yaksh/templates/yaksh/course_students.html | 132 ++++++++-------- yaksh/templates/yaksh/courses.html | 14 +- yaksh/views.py | 25 +-- 9 files changed, 427 insertions(+), 254 deletions(-) create mode 100644 yaksh/static/yaksh/js/show_courses.js diff --git a/yaksh/forms.py b/yaksh/forms.py index 73d4b54..767e51f 100644 --- a/yaksh/forms.py +++ b/yaksh/forms.py @@ -1,7 +1,7 @@ from django import forms from yaksh.models import ( get_model_class, Profile, Quiz, Question, Course, QuestionPaper, Lesson, - LearningModule + LearningModule, TestCase ) from grades.models import GradingSystem from django.contrib.auth import authenticate @@ -537,3 +537,15 @@ class LearningModuleForm(forms.ModelForm): class Meta: model = LearningModule fields = ['name', 'description', 'active'] + + +class TestcaseForm(forms.ModelForm): + + type = forms.CharField( + widget=forms.TextInput( + attrs={'readonly': 'readonly', 'class': form_input_class}) + ) + + class Meta: + model = TestCase + fields = ["type"] diff --git a/yaksh/models.py b/yaksh/models.py index efd4fd7..e9c025f 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1268,6 +1268,42 @@ class Question(models.Model): # Solution for the question. solution = models.TextField(blank=True) + tc_code_types = { + "python": [ + ("standardtestcase", "Standard TestCase"), + ("stdiobasedtestcase", "StdIO TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "c": [ + ("standardtestcase", "Standard TestCase"), + ("stdiobasedtestcase", "StdIO TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "cpp": [ + ("standardtestcase", "Standard TestCase"), + ("stdiobasedtestcase", "StdIO TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "java": [ + ("standardtestcase", "Standard TestCase"), + ("stdiobasedtestcase", "StdIO TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "r": [ + ("standardtestcase", "Standard TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "bash": [ + ("standardtestcase", "Standard TestCase"), + ("stdiobasedtestcase", "StdIO TestCase"), + ("hooktestcase", "Hook TestCase") + ], + "scilab": [ + ("standardtestcase", "Standard TestCase"), + ("hooktestcase", "Hook TestCase") + ] + } + def consolidate_answer_data(self, user_answer, user=None): question_data = {} metadata = {} @@ -1469,6 +1505,24 @@ class Question(models.Model): files, extract_path = extract_files(zip_file_path) self.read_yaml(extract_path, user, files) + def get_test_case_options(self): + options = None + if self.type == "code": + options = self.tc_code_types.get(self.language) + elif self.type == "mcq" or self.type == "mcc": + options = [("mcqtestcase", "Mcq TestCase")] + elif self.type == "integer": + options = [("integertestcase", "Integer TestCase")] + elif self.type == "float": + options = [("floattestcase", "Float TestCase")] + elif self.type == "string": + options = [("stringtestcase", "String TestCase")] + elif self.type == "arrange": + options = [("arrangetestcase", "Arrange TestCase")] + elif self.type == "upload": + options = [("hooktestcase", "Hook TestCase")] + return options + def __str__(self): return self.summary diff --git a/yaksh/static/yaksh/js/add_question.js b/yaksh/static/yaksh/js/add_question.js index 2db5301..310fed5 100644 --- a/yaksh/static/yaksh/js/add_question.js +++ b/yaksh/static/yaksh/js/add_question.js @@ -1,41 +1,39 @@ function increase(frm) { - if(frm.points.value == "") - { - frm.points.value = "0.5"; - return; - } - frm.points.value = parseFloat(frm.points.value) + 0.5; + if(frm.points.value == "") + { + frm.points.value = "0.5"; + return; + } + frm.points.value = parseFloat(frm.points.value) + 0.5; } function decrease(frm) { - if(frm.points.value > 0) - { - frm.points.value = parseFloat(frm.points.value) - 0.5; - } - else - { - frm.points.value=0; - } - - + if(frm.points.value > 0) + { + frm.points.value = parseFloat(frm.points.value) - 0.5; + } + else + { + frm.points.value=0; + } } function setSelectionRange(input, selectionStart, selectionEnd) { if (input.setSelectionRange) { - input.focus(); - input.setSelectionRange(selectionStart, selectionEnd); + input.focus(); + input.setSelectionRange(selectionStart, selectionEnd); } else if (input.createTextRange) { - var range = input.createTextRange(); - range.collapse(true); - range.moveEnd('character', selectionEnd); - range.moveStart('character', selectionStart); - range.select(); + var range = input.createTextRange(); + range.collapse(true); + range.moveEnd('character', selectionEnd); + range.moveStart('character', selectionStart); + range.select(); } } @@ -43,76 +41,76 @@ function replaceSelection (input, replaceString) { if (input.setSelectionRange) { - var selectionStart = input.selectionStart; - var selectionEnd = input.selectionEnd; - input.value = input.value.substring(0, selectionStart)+ replaceString + input.value.substring(selectionEnd); - if (selectionStart != selectionEnd) - { - setSelectionRange(input, selectionStart, selectionStart + replaceString.length); - } - else - { - setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length); - } + var selectionStart = input.selectionStart; + var selectionEnd = input.selectionEnd; + input.value = input.value.substring(0, selectionStart)+ replaceString + input.value.substring(selectionEnd); + if (selectionStart != selectionEnd) + { + setSelectionRange(input, selectionStart, selectionStart + replaceString.length); + } + else + { + setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length); + } } else if (document.selection) { - var range = document.selection.createRange(); - if (range.parentElement() == input) - { - var isCollapsed = range.text == ''; - range.text = replaceString; - if (!isCollapsed) - { - range.moveStart('character', -replaceString.length); - range.select(); - } - } + var range = document.selection.createRange(); + if (range.parentElement() == input) + { + var isCollapsed = range.text == ''; + range.text = replaceString; + if (!isCollapsed) + { + range.moveStart('character', -replaceString.length); + range.select(); + } + } } } function textareaformat() { - document.getElementById('id_type').setAttribute('class','custom-select'); - document.getElementById('id_points').setAttribute('class','mini-text'); + document.getElementById('id_type').setAttribute('class','custom-select'); + document.getElementById('id_points').setAttribute('class','mini-text form-control'); document.getElementById('id_tags').setAttribute('class','form-control'); $("[id*="+'test_case_args'+"]").attr('placeholder', 'Command Line arguments for bash only'); - $('#id_snippet').bind('keydown', function( event ){ + $('#id_snippet').bind('keydown', function( event ){ if(navigator.userAgent.match("Gecko")) - { - c=event.which; - } - else - { - c=event.keyCode; - } - if(c==9) - { - replaceSelection(document.getElementById('id_snippet'),String.fromCharCode(9)); - setTimeout(document.getElementById('id_snippet'),0); - return false; - } + { + c=event.which; + } + else + { + c=event.keyCode; + } + if(c==9) + { + replaceSelection(document.getElementById('id_snippet'),String.fromCharCode(9)); + setTimeout(document.getElementById('id_snippet'),0); + return false; + } }); - - $('#id_description').bind('focus', function( event ){ + + $('#id_description').bind('focus', function( event ){ document.getElementById("id_description").rows=5; document.getElementById("id_description").cols=40; }); - $('#id_description').bind('blur', function( event ){ + $('#id_description').bind('blur', function( event ){ document.getElementById("id_description").rows=1; document.getElementById("id_description").cols=40; }); - - $('#id_description').bind('keypress', function (event){ - document.getElementById('my').innerHTML = document.getElementById('id_description').value ; - }); - $('#id_solution').bind('keypress', function (event){ - document.getElementById('rend_solution').innerHTML = document.getElementById('id_solution').value ; - }); + $('#id_description').bind('keypress', function (event){ + document.getElementById('rendered_text').innerHTML = document.getElementById('id_description').value ; + }); + + $('#id_solution').bind('keypress', function (event){ + document.getElementById('rend_solution').innerHTML = document.getElementById('id_solution').value ; + }); $('#id_type').bind('focus', function(event){ var type = document.getElementById('id_type'); @@ -123,8 +121,6 @@ function textareaformat() var language = document.getElementById('id_language'); language.style.border = '1px solid #ccc'; }); - document.getElementById('my').innerHTML = document.getElementById('id_description').value ; - document.getElementById('rend_solution').innerHTML = document.getElementById('id_solution').value ; var question_type = document.getElementById('id_type').value if (document.getElementById('id_grade_assignment_upload').checked || @@ -146,10 +142,17 @@ function textareaformat() $('#id_file_field').on('change',function(){ //get the file name - var fileName = $(this).val(); - //replace the "Choose a file" label - $(this).next('.custom-file-label').html(fileName); - }) + var files = []; + for (var i = 0; i < $(this)[0].files.length; i++) { + files.push($(this)[0].files[i].name); + } + $(this).next('.custom-file-label').html(files.join(', ')); + }); + + $("#question_form").each(function(){ + $(this).find('textarea').addClass("form-control"); + $(this).find('input[type=number]').addClass("form-control"); + }); } function autosubmit() @@ -165,6 +168,6 @@ function autosubmit() { type.style.border = 'solid red'; return false; - } + } } diff --git a/yaksh/static/yaksh/js/course.js b/yaksh/static/yaksh/js/course.js index a4b5579..19f8562 100644 --- a/yaksh/static/yaksh/js/course.js +++ b/yaksh/static/yaksh/js/course.js @@ -127,4 +127,5 @@ $(document).ready(function(){ animate: false, container: 'body' }); + }); // end document ready diff --git a/yaksh/static/yaksh/js/show_courses.js b/yaksh/static/yaksh/js/show_courses.js new file mode 100644 index 0000000..1209ce3 --- /dev/null +++ b/yaksh/static/yaksh/js/show_courses.js @@ -0,0 +1,39 @@ +window.onload = function() { + document.getElementById("listbtn").onclick = function() { + showListView(); + localStorage.setItem('.courseview', 'list'); + return false; + }; + + document.getElementById("gridbtn").onclick = function() { + showGridView(); + localStorage.setItem('.courseview', 'grid'); + return false; + }; + + let itemClass = localStorage.getItem('.courseview'); + + if(itemClass == "list") { + showListView(); + } else { + showGridView(); + } + + function showListView() { + $('#listview').addClass('active'); + $('#listview').removeClass('fade'); + $('#gridview').addClass('fade'); + $('#gridview').removeClass('active'); + $('#listbtn').addClass('active'); + $('#gridbtn').removeClass('active'); + } + + function showGridView() { + $('#listview').addClass('fade'); + $('#listview').removeClass('active'); + $('#gridview').addClass('active'); + $('#gridview').removeClass('fade'); + $('#gridbtn').addClass('active'); + $('#listbtn').removeClass('active'); + } +} \ No newline at end of file diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html index a400e35..1ad7deb 100644 --- a/yaksh/templates/yaksh/add_question.html +++ b/yaksh/templates/yaksh/add_question.html @@ -1,4 +1,5 @@ {% extends "manage.html" %} +{% load custom_filters %} {% load staticfiles %} {% block title %} Add Question {% endblock title %} {% block pagetitle %} Add Question {% endblock pagetitle %} @@ -8,6 +9,7 @@ {% endblock %} {% block script %} + {% endblock %} @@ -15,109 +17,156 @@ {% block onload %} onload='javascript:textareaformat();' {% endblock %} {% block content %} -