diff options
author | prathamesh | 2016-10-04 16:57:25 +0530 |
---|---|---|
committer | prathamesh | 2016-10-04 16:57:25 +0530 |
commit | c5ae3d4589a71c3f3b9f622c7b67a04277269cde (patch) | |
tree | 78bd889cb40f647db6ba152063dce47ae7b8f430 /yaksh | |
parent | 64bb8507cbfbaf8b4558926a0c3206eb85547ed1 (diff) | |
download | online_test-c5ae3d4589a71c3f3b9f622c7b67a04277269cde.tar.gz online_test-c5ae3d4589a71c3f3b9f622c7b67a04277269cde.tar.bz2 online_test-c5ae3d4589a71c3f3b9f622c7b67a04277269cde.zip |
Edit Question Paper Feature.
Can edit question paper.
For creating new and editing existing question paper, same UI and view is used.
Ajax previously used for creation is removed. Not necessary as post
request handles the same.
Removed unnecessary js.
Diffstat (limited to 'yaksh')
-rw-r--r-- | yaksh/forms.py | 13 | ||||
-rw-r--r-- | yaksh/models.py | 4 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/question_paper_creation.css | 12 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/question_paper_creation.js | 218 | ||||
-rw-r--r-- | yaksh/templates/manage.html | 6 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_quiz.html | 2 | ||||
-rw-r--r-- | yaksh/templates/yaksh/ajax_questions.html | 31 | ||||
-rw-r--r-- | yaksh/templates/yaksh/courses.html | 25 | ||||
-rw-r--r-- | yaksh/templates/yaksh/design_questionpaper.html | 178 | ||||
-rw-r--r-- | yaksh/urls.py | 8 | ||||
-rw-r--r-- | yaksh/views.py | 174 |
11 files changed, 258 insertions, 413 deletions
diff --git a/yaksh/forms.py b/yaksh/forms.py index 23131b7..7d4a0d3 100644 --- a/yaksh/forms.py +++ b/yaksh/forms.py @@ -1,6 +1,6 @@ from django import forms -from yaksh.models import get_model_class, Profile, Quiz, Question, TestCase, Course, StandardTestCase, StdioBasedTestCase - +from yaksh.models import get_model_class, Profile, Quiz, Question, TestCase, Course,\ + QuestionPaper, StandardTestCase, StdioBasedTestCase from django.contrib.auth import authenticate from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType @@ -195,7 +195,7 @@ class QuestionFilterForm(forms.Form): super(QuestionFilterForm, self).__init__(*args, **kwargs) questions = Question.objects.filter(user_id=user.id) points_list = questions.values_list('points', flat=True).distinct() - points_options = [('select', 'Select Marks')] + points_options = [(None, 'Select Marks')] points_options.extend([(point, point) for point in points_list]) self.fields['marks'] = forms.FloatField(widget=forms.Select\ (choices=points_options)) @@ -211,6 +211,7 @@ class CourseForm(forms.ModelForm): model = Course fields = ['name', 'active', 'enrollment'] + class ProfileForm(forms.ModelForm): """ profile form for students and moderators """ @@ -232,3 +233,9 @@ class ProfileForm(forms.ModelForm): class UploadFileForm(forms.Form): file = forms.FileField() + + +class QuestionPaperForm(forms.ModelForm): + class Meta: + model = QuestionPaper + fields = ['shuffle_questions'] diff --git a/yaksh/models.py b/yaksh/models.py index 7c4d5c4..a6537e1 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -604,10 +604,10 @@ class QuestionPaper(models.Model): random_questions = models.ManyToManyField("QuestionSet") # Option to shuffle questions, each time a new question paper is created. - shuffle_questions = models.BooleanField(default=False) + shuffle_questions = models.BooleanField(default=False, blank=False) # Total marks for the question paper. - total_marks = models.FloatField() + total_marks = models.FloatField(default=0.0, blank=True) objects = QuestionPaperManager() diff --git a/yaksh/static/yaksh/css/question_paper_creation.css b/yaksh/static/yaksh/css/question_paper_creation.css index c915320..588b65c 100644 --- a/yaksh/static/yaksh/css/question_paper_creation.css +++ b/yaksh/static/yaksh/css/question_paper_creation.css @@ -5,9 +5,6 @@ body { line-height: 18px; color: #404040; } -.clearfix { - clear: both; -} .tabs li { text-align: center; width: 33%; @@ -48,7 +45,7 @@ body { padding: 7px 0; border: 2px solid #f5f5f5; } -#selectors .span4 { +#selectors .col-md-6 { margin-left: 0; } #id_question_type { @@ -57,8 +54,8 @@ body { #id_marks { width: 100%; } -#fixed-questions .span7 > div, -#random-questions .span7 > div{ +#fixed-questions .col-md-6 > div, +#random-questions .col-md-6 > div{ background: #f5f5f5; height: 200px; border: 1px solid #333333; @@ -111,9 +108,6 @@ body { .red-alert { border: 2px solid red; } -#myModal .qcard .remove{ - display: none; -} .well{ padding: 5px; } diff --git a/yaksh/static/yaksh/js/question_paper_creation.js b/yaksh/static/yaksh/js/question_paper_creation.js index a144540..898e491 100644 --- a/yaksh/static/yaksh/js/question_paper_creation.js +++ b/yaksh/static/yaksh/js/question_paper_creation.js @@ -1,204 +1,33 @@ $(document).ready(function(){ - /* selectors for the 3 step tabs*/ - $fixed_tab = $("#fixed-tab"); - $random_tab = $("#random-tab"); - $finish_tab = $("#finish-tab"); - - $question_type = $("#id_question_type"); - $marks = $("#id_marks"); - - $total_marks = $("#total_marks"); + $question_type = $('#id_question_type'); + $qpaper_id = $('#qpaper_id'); + $marks = $('#id_marks'); + $show = $('#show'); /* ajax requsts on selectors change */ $question_type.change(function() { - $.ajax({ - url: "/exam/ajax/questionpaper/marks/", - type: "POST", - data: { - question_type: $question_type.val() - }, - dataType: "html", - success: function(output) { - $marks.html(output); - } - }); + this.form.submit(); }); $marks.change(function() { - var fixed_question_list = []; - var fixed_inputs = $("input[name=fixed]"); - var random_question_list = []; - var random_inputs = $("input[name=random]"); - for(var i = 0; i < fixed_inputs.length; i++){ - fixed_question_list.push($(fixed_inputs[i]).val()); - } - for(var i = 0; i < random_inputs.length; i++){ - random_question_list.push($(random_inputs[i]).val()); - } - $.ajax({ - url: "/exam/ajax/questionpaper/questions/", - type: "POST", - data: { - question_type: $question_type.val(), - marks: $marks.val(), - fixed_list: fixed_question_list, - random_list: random_question_list - }, - dataType: "html", - success: function(output) { - if($fixed_tab.hasClass("active")) { - var questions = $(output).filter("#questions").html(); - $("#fixed-available").html(questions); - } else if($random_tab.hasClass("active")) { - var questions = $(output).filter("#questions").html(); - var numbers = $(output).filter("#num").html(); - $("#random-available").html(questions); - $("#number-wrapper").html(numbers); - } - } - }); - }); - - /* adding fixed questions */ - $("#add-fixed").click(function(e) { - var count = 0; - var selected = []; - var html = ""; - var $element; - var total_marks = parseFloat($total_marks.text()); - var marks_per = parseFloat($marks.val()) - $("#fixed-available input:checkbox").each(function(index, element) { - if($(this).attr("checked")) { - qid = $(this).attr("data-qid"); - if(!$(this).hasClass("ignore")) { - selected.push(qid); - $element = $("<div class='qcard'></div>"); - html += "<li>" + $(this).next().html() + "</li>"; - count++; - } - } - }); - html = "<ul>" + html + "</ul>"; - selected = selected.join(","); - var $input = $("<input type='hidden'>"); - $input.attr({ - value: selected, - name: "fixed" - }); - $remove = $("<a href='#' class='remove' data-num="+count+" data-marks = "+marks_per +">×</div>"); - $element.html(count + " question(s) added").append(html).append($input).append($remove); - $("#fixed-added").prepend($element); - total_marks = total_marks + count * marks_per; - $total_marks.text(total_marks) - e.preventDefault(); - }); - - /* adding random questions */ - $("#add-random").click(function(e) { - $numbers = $("#numbers"); - random_number = $numbers.val() - if($numbers.val()) { - $numbers.removeClass("red-alert"); - var count = 0; - var selected = []; - var html = ""; - var $element; - var total_marks = parseFloat($total_marks.text()); - var marks_per = parseFloat($marks.val()) - $("#random-available input:checkbox").each(function(index, element) { - if($(this).attr("checked")) { - qid = $(this).attr("data-qid"); - if(!$(this).hasClass("ignore")) { - selected.push(qid); - $element = $("<div class='qcard'></div>"); - html += "<li>" + $(this).next().html() + "</li>"; - count++; - } - } - }); - html = "<ul>" + html + "</ul>"; - selected = selected.join(","); - var $input_random = $("<input type='hidden'>"); - $input_random.attr({ - value: selected, - name: "random" - }); - var $input_number = $("<input type='hidden'>"); - $input_number.attr({ - value: $numbers.val(), - name: "number" - }); - $remove = $("<a href='#' class='remove' data-num="+random_number+" data-marks = "+marks_per +">×</div>"); - $element.html(random_number + " question(s) will be selected from " + count + " question(s)").append(html).append($input_random).append($input_number).append($remove); - $("#random-added").prepend($element); - total_marks = total_marks + random_number * marks_per; - $total_marks.text(total_marks) - } else { - $numbers.addClass("red-alert"); - } - e.preventDefault(); - }); - - /* removing added questions */ - $(".qcard .remove").live("click", function(e) { - var marks_per = $(this).attr('data-marks'); - var num_question = $(this).attr('data-num'); - var sub_marks = marks_per*num_question; - var total_marks = parseFloat($total_marks.text()); - total_marks = total_marks - sub_marks; - $total_marks.text(total_marks); - - $(this).parent().slideUp("normal", function(){ $(this).remove(); }); - e.preventDefault(); + this.form.submit(); }); /* showing/hiding selectors on tab click */ $(".tabs li").click(function() { if($(this).attr("id") == "finish-tab") { $("#selectors").hide(); + $('#is_active').val("finish"); } else { - $question_type.val('select'); - $marks.val('select') - $("#selectors").show(); - } - }); - /* check all questions on checked*/ - $("#checkall").live("click", function(){ - if($(this).attr("checked")) { - if($("#fixed-tab").hasClass("active")) { - $("#fixed-available input:checkbox").each(function(index, element) { - $(this).attr('checked','checked'); - }); + if($(this).attr("id") == "fixed-tab") { + $('#is_active').val("fixed"); } - else { - $("#random-available input:checkbox").each(function(index, element) { - $(this).attr('checked','checked'); - }); + if($(this).attr("id") == "random-tab") { + $('#is_active').val("random"); } - } - else { - if($("#fixed-tab").hasClass("active")) { - $("#fixed-available input:checkbox").each(function(index, element) { - $(this).removeAttr('checked'); - }); - } - else { - $("#random-available input:checkbox").each(function(index, element) { - $(this).removeAttr('checked'); - }); - } - } - }); - - /* show preview on preview click */ - $("#preview").click(function(){ - questions = getQuestions() - if(questions.trim() == ""){ - $('#modal_body').html("No questions selected"); + $question_type.val('select'); + $marks.val('select') + $("#selectors").show(); } - else { - $('#modal_body').html(questions); - } - $("#myModal").modal('show'); }); /* tab change on next or previous button click */ @@ -217,21 +46,4 @@ $(document).ready(function(){ $("#random").click(); }); - /* Check at least one question is present before saving */ - $('#save').click(function(){ - questions = getQuestions(); - if(questions.trim() == ""){ - $("#modalSave").modal("show"); - } - else { - document.forms["frm"].submit(); - } - }); - - /* Fetch selected questions */ - function getQuestions(){ - var fixed_div = $("#fixed-added").html(); - var random_div = $("#random-added").html(); - return fixed_div+random_div; - } -}); //document +});//document diff --git a/yaksh/templates/manage.html b/yaksh/templates/manage.html index 63c0ea7..f4c524e 100644 --- a/yaksh/templates/manage.html +++ b/yaksh/templates/manage.html @@ -46,6 +46,12 @@ <div class="page-header"> <h3><center>{% block subtitle %}Welcome {{ user.first_name.title }} {{user.last_name.title}} !{% endblock %}</center></h3><br> </div> + <div class="row"> + <div class="col-md-12"> + {% block new_manage %} + {% endblock %} + </div> + </div> <div class=row> <div class=span14> {% block manage %} diff --git a/yaksh/templates/yaksh/add_quiz.html b/yaksh/templates/yaksh/add_quiz.html index 5a0bee4..1c73e12 100644 --- a/yaksh/templates/yaksh/add_quiz.html +++ b/yaksh/templates/yaksh/add_quiz.html @@ -20,7 +20,7 @@ </table> </center> - <center><button class="btn" type="submit" id="submit" name="questionpaper">Design Question Paper</button> + <center><button class="btn" type="submit" id="submit" name="questionpaper"> Save </button> <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/courses/");'>Cancel</button> </center> diff --git a/yaksh/templates/yaksh/ajax_questions.html b/yaksh/templates/yaksh/ajax_questions.html deleted file mode 100644 index e343f9b..0000000 --- a/yaksh/templates/yaksh/ajax_questions.html +++ /dev/null @@ -1,31 +0,0 @@ -<div id="questions"> - {% if questions %} - <input type="checkbox" id="checkall" class="ignore"> - <span><b> <font size="3"> Select All </font></b></span> - {% endif %} - <ul class="inputs-list"> - - {% for question in questions %} - <li> - <label> - <input type="checkbox" name="questions" data-qid="{{question.id}}"> - <span> {{ question.summary }} </span> - </label> - </li> - {% endfor %} - </ul> -</div> - -<div id="num"> - <select id="numbers"> - <option value="">Number of questions to be picked from the pool</option> - {% for q in questions %} - {% if forloop.counter0 != 0 %} - <option value={{forloop.counter0}}>{{ forloop.counter0}}</option> - {% endif %} - {% if questions|length == 1%} - <option value=1>1</option> - {% endif %} - {% endfor %} - </select> -</div> diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html index 43f323b..dcf9af5 100644 --- a/yaksh/templates/yaksh/courses.html +++ b/yaksh/templates/yaksh/courses.html @@ -18,11 +18,10 @@ {% if user != course.creator %} <h4> {{course.creator.get_full_name}} added you to this course</h4> {% endif %} - <div class="row show-grid"> <div class="span14"> <div class="row"> - <div class="span6"> + <div class="span4"> <p> <b><u>Course</u></b> {% if course.active %} @@ -35,7 +34,7 @@ </br></br> {% if user == course.creator %} <div class="row"> - <div class="span6 wrap"> + <div class="span3 wrap"> <center><b><u>Teacher(s) Added to {{ course }}</u></b></center> {% if course.get_teachers %} <div align="left"> @@ -65,12 +64,23 @@ <p><b><a href="{{URL_ROOT}}/exam/manage/searchteacher/{{course.id}}/">Add Teacher</a></b></p> </div> {% endif %} - <div class="span6"> - <p><b><u>Quiz(zes)</u></b></p> + <div class="span4" style="text-align:left"> {% if course.get_quizzes %} - {% for quiz in course.get_quizzes %} + <p><b><u>Quiz(zes)</u></b></p> + {% for quiz in course.get_quizzes %} <a href="{{URL_ROOT}}/exam/manage/addquiz/{{course.id}}/{{quiz.id}}/">{{ quiz.description }}</a><br> - + {% endfor %} + </div> + <div class="span4" style="text-align:left"> + <p><b><u>Question Paper(s)</u></b></p> + {% for quiz in course.get_quizzes %} + {% if quiz.questionpaper_set.get %} + <a href="{{URL_ROOT}}/exam/manage/designquestionpaper/{{ quiz.id }}/{{quiz.questionpaper_set.get.id}}/">Question Paper for {{ quiz.description }}</a><br> + {% else %} + <p><b>No Question Paper </b> + <button class="btn small primary" type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/quiz/designquestionpaper/{{ quiz.id }}/");'>Add</button> + </p> + {% endif %} {% endfor %} {% else %} <p><b>No quiz </b></p> @@ -79,7 +89,6 @@ </div> <br/> <button class="btn primary"type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/addquiz/{{course.id}}/");'>Add New Quiz</button> - </div> </div> <br><br> diff --git a/yaksh/templates/yaksh/design_questionpaper.html b/yaksh/templates/yaksh/design_questionpaper.html index 2aa169b..435de83 100644 --- a/yaksh/templates/yaksh/design_questionpaper.html +++ b/yaksh/templates/yaksh/design_questionpaper.html @@ -1,12 +1,12 @@ {% extends "manage.html" %} -{% block subtitle %}Design Question Paper{% endblock %} +{% block title %} Design Question Paper {% endblock title %} + +{% block subtitle %} Design Question Paper {% endblock %} {% block css %} -<link rel="stylesheet" href="{{ URL_ROOT }}/static/yaksh/css/base.css" type="text/css" /> -<link rel="stylesheet" href="{{ URL_ROOT }}/static/yaksh/css/question_quiz.css" type="text/css" /> -<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/yaksh/css/autotaggit.css" /> -<link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/yaksh/css/question_paper_creation.css" /> + <link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/yaksh/css/bootstrap.css" /> + <link rel="stylesheet" media="all" type="text/css" href="{{ URL_ROOT }}/static/yaksh/css/question_paper_creation.css" /> <style> select { @@ -14,17 +14,19 @@ select } </style> {% endblock %} -{% block script %} -<script src="{{ URL_ROOT }}/static/yaksh/js/jquery-1.4.2.min.js" type="text/javascript"></script> -<script src="{{ URL_ROOT }}/static/yaksh/js/bootstrap-tabs.js"></script> -<script src="{{ URL_ROOT }}/static/yaksh/js/add_questionpaper.js"></script> -<script src="{{ URL_ROOT }}/static/yaksh/js/question_paper_creation.js"></script> -<script src="{{ URL_ROOT }}/static/yaksh/js/bootstrap-modal.js"></script> +{% block script %} + <script src="{{ URL_ROOT }}/static/yaksh/js/jquery-1.9.1.min.js"></script> + <script src="{{ URL_ROOT }}/static/yaksh/js/bootstrap.js"></script> + <script src="{{ URL_ROOT }}/static/yaksh/js/bootstrap-tabs.js"></script> + <script src="{{ URL_ROOT }}/static/yaksh/js/question_paper_creation.js"></script> {% endblock %} -{% block manage %} -<input type=hidden id="url_root" value={{ URL_ROOT }}> +{% block new_manage %} +<form action="{{ URL_ROOT }}/exam/manage/designquestionpaper/{{ qpaper.quiz.id }}/{{ qpaper.id }}/" method="POST"> +<input class ="btn primary small" type="submit" name="back" id="back" value="Cancel"> + {% csrf_token %} + <input type=hidden name="is_active" id="is_active" value="{{ state }}"> <center><b>Manual mode to design the {{lang}} Question Paper</center><br> <ul class="tabs" data-tabs="tabs"> <li class="active" id="fixed-tab"> @@ -46,42 +48,62 @@ select </a></li> </ul> -<form action="{{URL_ROOT}}/exam/manage/designquestionpaper/" method="post" name=frm > {% csrf_token %} <div> - <h3>Total Marks: <span id="total_marks" class="well">0</span></h3> + <h3>Total Marks: <span id="total_marks" class="well"> {{ qpaper.total_marks }} </span></h3> </div> <div class="tab-content"> <!-- common to fixed and random questions --> <div class="row" id="selectors"> <h5 style="padding-left: 20px;">Please select Question type and Marks</h5> - <div class="span4"> - {{ form.question_type }} - </div> <!-- /.span4 --> - <div class="span4"> - {{ form.marks }} - </div> <!-- /.span4 --> - <div class="span4"> - <div class="pull-left" id="number-wrapper"></div> - </div> <!-- /.span4 --> + <div class="col-md-6"> + {{ filter_form.question_type }} + </div> + <div class="col-md-6"> + {{ filter_form.marks }} + </div> </div> <!-- /.row --> <br><br> - <div class="tab-pane active" id="fixed-questions"> <div class="row"> - <div class="span7"> + <div class="col-md-6"> <div id="fixed-available-wrapper"> <p><u>Select questions to add:</u></p> <div id="fixed-available"> + {% if state == "fixed" or state == "None" %} + <ul class="inputs-list"> + {% for question in questions %} + <li> + <label> + <input type="checkbox" name="questions" data-qid="{{question.id}}" value={{question.id}}> + <span> {{ question.summary }} </span> <span> {{ question.points }} </span> + </label> + </li> + {% endfor %} + </ul> + {% endif %} </div> - <a id="add-fixed" class="btn small primary pull-right" href="#">Add to paper</a> + <br /><br /> + <button id="add-fixed" name="add-fixed" class="btn small primary pull-right" type="submit">Add to paper</button> </div> </div> - <div class="span7"> + <div class="col-md-6"> <div id="fixed-added-wrapper"> <p><u>Fixed questions currently in paper:</u></p> <div id="fixed-added"> + <ul class="inputs-list"> + {% for question in fixed_questions %} + <li> + <label> + <input type="checkbox" name="added-questions" data-qid="{{question.id}}" value={{question.id}}> + <span> {{ question.summary }} </span> <span> {{ question.points }} </span> + </label> + </li> + {% endfor %} + </ul> </div> + <br /> + <button id="remove-fixed" name="remove-fixed" class="btn small primary pull-right" type="submit"> Remove from paper</button> </div> </div> </div> <!-- /.row --> @@ -89,25 +111,66 @@ select <div class="pull-right"> <a class="btn" id="fixed-next">Next ></a> </div> - </div> <!-- /#fixed-questions --> - <div class="tab-pane" id="random-questions"> <div class="row"> - <div class="span7"> + <div class="col-md-6"> <div id="random-available-wrapper"> <p><u>Select questions to add to the pool:</u></p> <div id="random-available"> + {% if state == "random" %} + <select id="num_of_questions" name="num_of_questions"> + <option value="1">Number of questions to be picked from the pool</option> + {% for q in questions %} + {% if forloop.counter0 != 0 %} + <option value={{forloop.counter0}}>{{ forloop.counter0}}</option> + {% endif %} + {% if questions|length == 1%} + <option value=1>1</option> + {% endif %} + {% endfor %} + </select> + <ul class="inputs-list"> + {% for question in questions %} + <li> + <label> + <input type="checkbox" name="random_questions" data-qid="{{question.id}}" value={{question.id}}> + <span> {{ question.summary }} </span> <span> {{ question.points }} </span> + </label> + </li> + {% endfor %} + </ul> + {% endif %} </div> - <a id="add-random" class="btn small primary pull-right" href="#">Add to paper</a> + <br /><br /> + <button id="add-random" name="add-random" class="btn small primary pull-right" type="submit">Add to paper</button> </div> </div> - <div class="span7"> + <div class="col-md-6"> <div id="random-added-wrapper"> <p><u>Pool of questions currently in paper:</u></p> <div id="random-added"> + <ul class="inputs-list"> + {% for random_set in random_sets %} + <li> + <label> + <input type="checkbox" name="random_sets" data-qid="{{random_set.id}}" value={{random_set.id}}> + <span> Random Set {{ forloop.counter }} (will take {{ random_set.num_questions }} randomly out of {{ random_set.questions.count }})</span> + </label> + </li> + {% for question in random_set.questions.all %} + <li> + <label> + <span> {{ question.summary }} </span> <span> {{ question.points }} </span> + </label> + </li> + {% endfor %} + {% endfor %} + </ul> </div> + <br /> + <button id="remove-random" name="remove-random" class="btn small primary pull-right" type="submit"> Remove from paper</button> </div> </div> </div> <!-- /.row --> @@ -124,11 +187,10 @@ select <center> <h5>Almost finished creating your question paper</h5> <label style="float: none;"> - {{ form.shuffle_questions }} + {{ qpaper_form.shuffle_questions }} <span>Auto shuffle.</span> </label> <br><br> - <input class ="btn primary large" type="button" id="preview" value="Preview question paper"> - <input class ="btn primary large" type="button" id="save" value="Save question paper"> + <input class ="btn primary large" type="submit" name="save" id="save" value="Save question paper"> <br> <div class="pull-left"> <a class="btn" id="finish-prev">< Previous</a> @@ -139,44 +201,18 @@ select <!-- /.tab-content --> </form> <br> -<div class="clearfix"></div> - -<!-- Modal --> -<div class="modal fade " id="myModal" > - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title" id="myModalLabel">Question Paper Preview</h4> - </div> - <div id = "modal_body"class="modal-body"> - </div> - <div class="modal-footer"> - <button type="button" class="btn primary close" data-dismiss="modal">OK</button> - </div> - </div> - </div> -</div> - -<div class="modal fade " id="modalSave" > - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title" id="myModalLabel">Cannot Save</h4> - </div> - <div class="modal-body"> - Please select questions for your paper - </div> - <div class="modal-footer"> - <button type="button" class="btn primary close" data-dismiss="modal">OK</button> - </div> - </div> - </div> -</div> -</div> - <script> $(function () { $('.tabs').tabs() + {% if state == "fixed" %} + $('#fixed').tab('show'); + {% elif state == "random" %} + $("#random").tab('show'); + {% elif state == "finish" %} + $('#finished').tab('show'); + {% endif %} }) </script> {% endblock %} +{% block manage %} +{% endblock %} diff --git a/yaksh/urls.py b/yaksh/urls.py index c4619b6..bb8cf2e 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -68,9 +68,10 @@ urlpatterns += [ url(r'^manage/user_data/(?P<user_id>\d+)/(?P<questionpaper_id>\d+)/$', views.user_data), url(r'^manage/user_data/(?P<user_id>\d+)/$', views.user_data), - url(r'^manage/designquestionpaper/$', views.design_questionpaper, name='design_questionpaper'), - url(r'^manage/designquestionpaper/(?P<questionpaper_id>\d+)/$',\ - views.design_questionpaper), + url(r'^manage/quiz/designquestionpaper/(?P<quiz_id>\d+)/$', views.design_questionpaper, + name='design_questionpaper'), + url(r'^manage/designquestionpaper/(?P<quiz_id>\d+)/(?P<questionpaper_id>\d+)/$', + views.design_questionpaper, name='designquestionpaper'), url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/$', views.show_statistics), url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/(?P<attempt_number>\d+)/$', @@ -87,7 +88,6 @@ urlpatterns += [ url(r'manage/enrolled/reject/(?P<course_id>\d+)/(?P<user_id>\d+)/$', views.reject, {'was_enrolled': True}), url(r'manage/toggle_status/(?P<course_id>\d+)/$', views.toggle_course_status), - url(r'^ajax/questionpaper/(?P<query>.+)/$', views.ajax_questionpaper), url(r'^ajax/questions/filter/$', views.ajax_questions_filter), url(r'^editprofile/$', views.edit_profile, name='edit_profile'), url(r'^viewprofile/$', views.view_profile, name='view_profile'), diff --git a/yaksh/views.py b/yaksh/views.py index 4c5b9b8..f25a685 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -28,7 +28,7 @@ from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase, FileUploa from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\ QuestionForm, RandomQuestionForm,\ QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\ - get_object_form, FileForm + get_object_form, FileForm, QuestionPaperForm from settings import URL_ROOT from yaksh.models import AssignmentUpload from file_utils import extract_files @@ -245,7 +245,7 @@ def add_quiz(request, course_id, quiz_id=None): form = QuizForm(request.POST, user=user, course=course_id) if form.is_valid(): form.save() - return my_redirect(reverse('yaksh:design_questionpaper')) + return my_redirect("/exam/manage/courses/") else: context["form"] = form return my_render_to_response('yaksh/add_quiz.html', @@ -258,7 +258,7 @@ def add_quiz(request, course_id, quiz_id=None): if form.is_valid(): form.save() context["quiz_id"] = quiz_id - return my_redirect("/exam/manage/") + return my_redirect("/exam/manage/courses/") else: if quiz_id is None: form = QuizForm(course=course_id, user=user) @@ -630,7 +630,6 @@ def courses(request): raise Http404('You are not allowed to view this page') courses = Course.objects.filter(creator=user, is_trial=False) allotted_courses = Course.objects.filter(teachers=user, is_trial=False) - context = {'courses': courses, "allotted_courses": allotted_courses} return my_render_to_response('yaksh/courses.html', context, context_instance=ci) @@ -812,6 +811,95 @@ def ajax_questions_filter(request): {'questions': questions}) +def _get_questions(user, question_type, marks): + if question_type is None and marks is None: + return None + if question_type: + questions = Question.objects.filter(type=question_type, user=user) + if marks: + questions = questions.filter(points=marks) + return questions + + +def _remove_already_present(questionpaper_id, questions): + if questionpaper_id is None: + return questions + questionpaper = QuestionPaper.objects.get(pk=questionpaper_id) + questions = questions.exclude( + id__in=questionpaper.fixed_questions.values_list('id', flat=True)) + for random_set in questionpaper.random_questions.all(): + questions = questions.exclude( + id__in=random_set.questions.values_list('id', flat=True)) + return questions + + +@login_required +def design_questionpaper(request, quiz_id, questionpaper_id=None): + user = request.user + + if not is_moderator(user): + raise Http404('You are not allowed to view this page!') + + filter_form = QuestionFilterForm(user=user) + questions = None + marks = None + state = None + if questionpaper_id is None: + question_paper = QuestionPaper.objects.get_or_create(quiz_id=quiz_id)[0] + else: + question_paper = get_object_or_404(QuestionPaper, id=questionpaper_id) + qpaper_form = QuestionPaperForm(instance=question_paper) + + if request.method == 'POST': + + filter_form = QuestionFilterForm(request.POST, user=user) + qpaper_form = QuestionPaperForm(request.POST, instance=question_paper) + question_type = request.POST.get('question_type', None) + marks = request.POST.get('marks', None) + state = request.POST.get('is_active', None) + + if 'add-fixed' in request.POST: + question_ids = request.POST.getlist('questions', None) + for question in Question.objects.filter(id__in=question_ids): + question_paper.fixed_questions.add(question) + + if 'remove-fixed' in request.POST: + question_ids = request.POST.getlist('added-questions', None) + question_paper.fixed_questions.remove(*question_ids) + + if 'add-random' in request.POST: + question_ids = request.POST.getlist('random_questions', None) + num_of_questions = request.POST.get('num_of_questions', 1) + if question_ids and marks: + random_set = QuestionSet(marks=marks, num_questions=num_of_questions) + random_set.save() + for question in Question.objects.filter(id__in=question_ids): + random_set.questions.add(question) + question_paper.random_questions.add(random_set) + + if 'remove-random' in request.POST: + random_set_ids = request.POST.getlist('random_sets', None) + question_paper.random_questions.remove(*random_set_ids) + + if 'save' in request.POST or 'back' in request.POST: + qpaper_form.save() + return my_redirect('/exam/manage/courses/') + + if marks: + questions = _get_questions(user, question_type, marks) + questions = _remove_already_present(questionpaper_id, questions) + + question_paper.update_total_marks() + question_paper.save() + random_sets = question_paper.random_questions.all() + fixed_questions = question_paper.fixed_questions.all() + context = {'qpaper_form': qpaper_form, 'filter_form': filter_form, 'qpaper': + question_paper, 'questions': questions, 'fixed_questions': fixed_questions, + 'state': state, 'random_sets': random_sets} + return my_render_to_response('yaksh/design_questionpaper.html', context, + context_instance=RequestContext(request)) + + @login_required def show_all_questions(request): """Show a list of all the questions currently in the database.""" @@ -998,80 +1086,6 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None): ) -@csrf_exempt -def ajax_questionpaper(request, query): - """ - During question paper creation, ajax call made to get question details. - """ - - user = request.user - if query == 'marks': - question_type = request.POST.get('question_type') - questions = Question.objects.filter(type=question_type, user=user) - marks = questions.values_list('points').distinct() - return my_render_to_response('yaksh/ajax_marks.html', {'marks': marks}) - elif query == 'questions': - question_type = request.POST['question_type'] - marks_selected = request.POST['marks'] - fixed_questions = request.POST.getlist('fixed_list[]') - fixed_question_list = ",".join(fixed_questions).split(',') - random_questions = request.POST.getlist('random_list[]') - random_question_list = ",".join(random_questions).split(',') - question_list = fixed_question_list + random_question_list - questions = list(Question.objects.filter(type=question_type, - points=marks_selected, user=user)) - questions = [question for question in questions \ - if not str(question.id) in question_list] - return my_render_to_response('yaksh/ajax_questions.html', - {'questions': questions}) - - -@login_required -def design_questionpaper(request): - user = request.user - ci = RequestContext(request) - - if not is_moderator(user): - raise Http404('You are not allowed to view this page!') - - if request.method == 'POST': - fixed_questions = request.POST.getlist('fixed') - random_questions = request.POST.getlist('random') - random_number = request.POST.getlist('number') - is_shuffle = request.POST.get('shuffle_questions', False) - if is_shuffle == 'on': - is_shuffle = True - - question_paper = QuestionPaper(shuffle_questions=is_shuffle) - quiz = Quiz.objects.order_by("-id")[0] - tot_marks = 0 - question_paper.quiz = quiz - question_paper.total_marks = tot_marks - question_paper.save() - if fixed_questions: - fixed_questions_ids = ",".join(fixed_questions) - fixed_questions_ids_list = fixed_questions_ids.split(',') - for question_id in fixed_questions_ids_list: - question_paper.fixed_questions.add(question_id) - if random_questions: - for random_question, num in zip(random_questions, random_number): - qid = random_question.split(',')[0] - question = Question.objects.get(id=int(qid)) - marks = question.points - question_set = QuestionSet(marks=marks, num_questions=num) - question_set.save() - for question_id in random_question.split(','): - question_set.questions.add(question_id) - question_paper.random_questions.add(question_set) - question_paper.update_total_marks() - question_paper.save() - return my_redirect('/exam/manage/courses') - else: - form = RandomQuestionForm() - context = {'form': form, 'questionpaper':True} - return my_render_to_response('yaksh/design_questionpaper.html', - context, context_instance=ci) - @login_required def view_profile(request): """ view moderators and users profile """ @@ -1150,7 +1164,6 @@ def search_teacher(request, course_id): Q(id=course.creator.id)) context['success'] = True context['teachers'] = teachers - return my_render_to_response('yaksh/addteacher.html', context, context_instance=ci) @@ -1179,7 +1192,6 @@ def add_teacher(request, course_id): course.add_teachers(*teachers) context['status'] = True context['teachers_added'] = teachers - return my_render_to_response('yaksh/addteacher.html', context, context_instance=ci) @@ -1187,7 +1199,7 @@ def add_teacher(request, course_id): @login_required def remove_teachers(request, course_id): """ remove user from a course """ - + user = request.user course = get_object_or_404(Course, pk=course_id) if not is_moderator(user) and (user != course.creator and user not in course.teachers.all()): |