summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yaksh/forms.py13
-rw-r--r--yaksh/models.py4
-rw-r--r--yaksh/static/yaksh/css/question_paper_creation.css12
-rw-r--r--yaksh/static/yaksh/js/question_paper_creation.js218
-rw-r--r--yaksh/templates/manage.html6
-rw-r--r--yaksh/templates/yaksh/add_quiz.html2
-rw-r--r--yaksh/templates/yaksh/ajax_questions.html31
-rw-r--r--yaksh/templates/yaksh/courses.html25
-rw-r--r--yaksh/templates/yaksh/design_questionpaper.html178
-rw-r--r--yaksh/test_views.py4
-rw-r--r--yaksh/urls.py8
-rw-r--r--yaksh/views.py174
12 files changed, 260 insertions, 415 deletions
diff --git a/yaksh/forms.py b/yaksh/forms.py
index a12ce9a..bc9b4c0 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
@@ -199,7 +199,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))
@@ -215,6 +215,7 @@ class CourseForm(forms.ModelForm):
model = Course
fields = ['name', 'active', 'enrollment']
+
class ProfileForm(forms.ModelForm):
""" profile form for students and moderators """
@@ -236,3 +237,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 444df4a..f098cd2 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 +">&times;</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 +">&times;</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 &gt;</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">&lt; 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/test_views.py b/yaksh/test_views.py
index cf547b5..1d1c3f3 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -294,7 +294,7 @@ class TestAddQuiz(TestCase):
self.assertEqual(updated_quiz.course, self.course)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/exam/manage/')
+ self.assertRedirects(response, '/exam/manage/courses/')
def test_add_quiz_post_new_quiz(self):
"""
@@ -340,7 +340,7 @@ class TestAddQuiz(TestCase):
self.assertEqual(new_quiz.course, self.course)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/exam/manage/designquestionpaper/')
+ self.assertRedirects(response, '/exam/manage/courses/')
class TestAddTeacher(TestCase):
def setUp(self):
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 0ed5f5a..049788a 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -29,7 +29,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
@@ -246,7 +246,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',
@@ -259,7 +259,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)
@@ -631,7 +631,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)
@@ -813,6 +812,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."""
@@ -999,80 +1087,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 """
@@ -1151,7 +1165,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)
@@ -1180,7 +1193,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)
@@ -1188,7 +1200,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()):