start updating physics
This commit is contained in:
@@ -27,6 +27,8 @@ class CidUserAnswerForm(ModelForm):
|
||||
super(CidUserAnswerForm, self).__init__(*args, **kwargs)
|
||||
#self.fields['answer'].required = False
|
||||
|
||||
|
||||
|
||||
# This should be made generic?
|
||||
class ExamForm(ModelForm):
|
||||
class Meta:
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
CID: {{cid}}
|
||||
|
||||
<h2>Exam: {{exam.name}}</h2>
|
||||
|
||||
<div><p>Questions</p></div>
|
||||
{{answer_count}} out of {{exam_length}} questions answered. Click to go to question.
|
||||
<div class="sba-finish-list">
|
||||
{% for question, answer in question_answer_tuples %}
|
||||
<a href="{% url 'physics:exam_take' pk=exam.id sk=forloop.counter0 cid=cid %}"><button {% if not answer %}class="unanswered"{% endif %}>{{forloop.counter}}: {{answer.answer}}</button></a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2>{{exam.name}}</h2>
|
||||
|
||||
Enter your CID in the below box.<br />
|
||||
<input id="cid-box" type="text" value="Candidate ID">
|
||||
|
||||
<button>Start exam</button>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$("button").click(() => {
|
||||
let cid = $("#cid-box").val();
|
||||
|
||||
if (Number.isInteger(parseInt(cid))) {
|
||||
window.location.replace("{% url 'physics:exam_take' pk=exam.pk sk=0 cid='0000000' %}".replace("0000000", cid));
|
||||
} else {
|
||||
alert("Please enter a valid Candidate ID (CID).")
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Regular → Executable
+93
-269
@@ -1,280 +1,104 @@
|
||||
{% extends 'physics/base.html' %}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="physics">
|
||||
<h1>Exam: {{ exam.name }}</h1>
|
||||
|
||||
<div class="alert alert-info" role="alert">
|
||||
<details>
|
||||
<summary title="click to open"><h3>Instructions</h3></summary>
|
||||
<p>
|
||||
Please make sure you submit answers before closing or navigating from this page (as otherwise they will not
|
||||
be saved). The submit button is at the bottom of the page.
|
||||
</p>
|
||||
<p>
|
||||
Click on a question to toggle between true / false.
|
||||
</p>
|
||||
<p>
|
||||
Ensure your candidate number is entered in the below box.
|
||||
</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Candidate number: <input type="number" id="cid" name="cid" title="please enter your candidate number">
|
||||
</div>
|
||||
|
||||
<h2>Questions</h2>
|
||||
|
||||
{% autoescape off %}
|
||||
<ol id="full-question-list-physics">
|
||||
{% for question in questions.all %}
|
||||
|
||||
<li>
|
||||
{{ question.stem }}
|
||||
<ol type="a" class="abcde">
|
||||
<li>
|
||||
<span class="question-text">{{ question.a }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question a" id="{{question.pk}}-a-checkbox" data-q="{{question.pk}}"
|
||||
data-a="a">
|
||||
<div class="slider round a"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.b }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question b" id="{{question.pk}}-b-checkbox" data-q="{{question.pk}}"
|
||||
data-a="b">
|
||||
<div class="slider round b"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.c }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question c" id="{{question.pk}}-c-checkbox" data-q="{{question.pk}}"
|
||||
data-a="c">
|
||||
<div class="slider round c"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.d }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question d" id="{{question.pk}}-d-checkbox" data-q="{{question.pk}}"
|
||||
data-a="d">
|
||||
<div class="slider round d"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.e }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question e" id="{{question.pk}}-e-checkbox" data-q="{{question.pk}}"
|
||||
data-a="e">
|
||||
<div class="slider round e"></div>
|
||||
</label>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% endautoescape %}
|
||||
|
||||
|
||||
<button id="submit">Submit answers</button>
|
||||
|
||||
CID: {{cid}}
|
||||
<div class="no-select">
|
||||
<h2>Question [{{pos|add:1}}/{{exam_length}}]</h2>
|
||||
{% if exam.publish_results %}
|
||||
<div class="alert alert-primary" role="alert">
|
||||
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window({% url 'feedback_create' question_type='physicss' pk=question.pk %}">here</a>.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<p>{{question.stem|safe}}</p>
|
||||
</div>
|
||||
<ul class="physics-answer-list">
|
||||
<li data-ans="a">{{question.a_answer|safe}}</li>
|
||||
<li data-ans="b">{{question.b_answer|safe}}</li>
|
||||
<li data-ans="c">{{question.c_answer|safe}}</li>
|
||||
<li data-ans="d">{{question.d_answer|safe}}</li>
|
||||
<li data-ans="e">{{question.e_answer|safe}}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
<div>
|
||||
|
||||
window.answers_submitted = false;
|
||||
$(document).ready(function () {
|
||||
console.log($(".question-text"));
|
||||
$(".question-text").click(function (evt) {
|
||||
$(evt.target).parent().find("input").click();
|
||||
});
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
<div class="form-contents">
|
||||
{{form}}
|
||||
</div>
|
||||
|
||||
$("#submit").click(() => {
|
||||
let cid = $("#cid").val()
|
||||
if (cid == "") {
|
||||
alert("You need to enter a valid candidate number.");
|
||||
$("#cid").focus();
|
||||
return
|
||||
}
|
||||
{% if previous > -1 %}
|
||||
<button type="submit" name="previous" class="save btn btn-default">Previous</button>
|
||||
{% endif %}
|
||||
{% if next %}
|
||||
<button type="submit" name="next" class="save btn btn-default">Next</button>
|
||||
{% else %}
|
||||
{% if not exam.publish_results %}
|
||||
<button type="submit" name="save" class="save btn btn-default">Save</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
answers = [];
|
||||
{% if exam.publish_results and question.feedback %}
|
||||
<h3>Feedback</h3>
|
||||
<p>{{question.feedback|safe}}</p>
|
||||
{% endif %}
|
||||
<br />
|
||||
<button type="submit" name="finish" class="save btn btn-default">Overview</button>
|
||||
<button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Questions</h4>
|
||||
<div id="menu-list">
|
||||
|
||||
$("input.question").each((n, el) => {
|
||||
answers.push([el.dataset.q, el.dataset.a, el.checked]);
|
||||
|
||||
})
|
||||
|
||||
ans = {
|
||||
cid: parseInt(cid),
|
||||
eid: {{exam.pk}},
|
||||
ans: answers
|
||||
}
|
||||
|
||||
let json = {
|
||||
eid: {{exam.pk}},
|
||||
answers: JSON.stringify([ans]),
|
||||
};
|
||||
|
||||
postAnswers(json);
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
window.onbeforeunload = confirmExit;
|
||||
function confirmExit() {
|
||||
if (!window.answers_submitted) {
|
||||
return "You have attempted to leave this page. Are you sure?";
|
||||
}
|
||||
}
|
||||
|
||||
function postAnswers(ans) {
|
||||
console.log(ans);
|
||||
$.post("{% url 'physics:exam_answers_submit' %}", ans, null, "json").done((data) => {
|
||||
console.log(data);
|
||||
if (data.success) {
|
||||
let ret = confirm(
|
||||
`Answers sucessfully submitted. Click OK to finish the exam.`
|
||||
);
|
||||
|
||||
if (ret) {
|
||||
//window.saveSession();
|
||||
$("#exams-button-link").remove();
|
||||
$("#submit").after('<button id="exams-button-link">Return to exam list</button>');
|
||||
$("#exams-button-link").click(() => {
|
||||
window.location.href = "{% url 'physics:active_exams' %}";
|
||||
})
|
||||
window.answers_submitted = true;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
alert(`Error submitting answers: ${data.error}`);
|
||||
}
|
||||
});
|
||||
// $.post( "http://localhost:8000/submit_answers", JSON.stringify(ans));
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.truefalse-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
margin: 0px;
|
||||
margin-bottom: -5px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.truefalse-switch input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 4, 255, 0.5);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 2px;
|
||||
background-color: white;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked+.slider {
|
||||
background-color: rgba(162, 0, 255, 0.5);
|
||||
}
|
||||
|
||||
input:focus+.slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked+.slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(68px);
|
||||
}
|
||||
|
||||
/*------ ADDED CSS ---------*/
|
||||
.slider:after {
|
||||
color: white;
|
||||
display: block;
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
font-size: 10px;
|
||||
font-family: Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.a.slider:after {
|
||||
content: 'a) FALSE';
|
||||
}
|
||||
|
||||
.b.slider:after {
|
||||
content: 'b) FALSE';
|
||||
}
|
||||
|
||||
.c.slider:after {
|
||||
content: 'c) FALSE';
|
||||
}
|
||||
|
||||
.d.slider:after {
|
||||
content: 'd) FALSE';
|
||||
}
|
||||
|
||||
.e.slider:after {
|
||||
content: 'e) FALSE';
|
||||
}
|
||||
|
||||
input:checked+.slider.a:after {
|
||||
content: 'a )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.b:after {
|
||||
content: 'b )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.c:after {
|
||||
content: 'c )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.d:after {
|
||||
content: 'd )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.e:after {
|
||||
content: 'e )TRUE';
|
||||
}
|
||||
|
||||
.question-text {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
clear: both;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.abcde {
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
/* beautify ignore:start */
|
||||
{% if not exam.publish_results %}
|
||||
$("ul.physics-answer-list li").each((n, el) => {
|
||||
$(el).click((e) => {
|
||||
console.log(1, el.dataset.ans);
|
||||
$("#id_answer").val(el.dataset.ans);
|
||||
$("ul.physics-answer-list li").removeClass("selected");
|
||||
$(el).addClass("selected")
|
||||
})
|
||||
})
|
||||
{% else %}
|
||||
$("ul.physics-answer-list li[data-ans='{{question.best_answer}}']").addClass("correct");
|
||||
{% endif %}
|
||||
|
||||
{% if saved_answer %}
|
||||
$("ul.physics-answer-list li[data-ans='{{saved_answer}}']").addClass("selected"); {% endif %}
|
||||
|
||||
for (let i = 0; i < {{ exam_length }}; i++) {
|
||||
$("#menu-list").append($(
|
||||
`<button class="question-menu-item" name="goto-${i}" data-qn="${i}">${i+1}</button>`));
|
||||
|
||||
}
|
||||
$("button.question-menu-item").on("click", (e) => {
|
||||
console.log(e.currentTarget.dataset.qn);
|
||||
document.getElementById("goto-button").value = e.currentTarget.dataset.qn;
|
||||
$("#goto-button").click();
|
||||
});
|
||||
/* beautify ignore:end */
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block css %}
|
||||
<style type="text/css">
|
||||
.form-contents {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.selected {
|
||||
border: 1px solid purple;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,280 @@
|
||||
{% extends 'physics/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="physics">
|
||||
<h1>Exam: {{ exam.name }}</h1>
|
||||
|
||||
<div class="alert alert-info" role="alert">
|
||||
<details>
|
||||
<summary title="click to open"><h3>Instructions</h3></summary>
|
||||
<p>
|
||||
Please make sure you submit answers before closing or navigating from this page (as otherwise they will not
|
||||
be saved). The submit button is at the bottom of the page.
|
||||
</p>
|
||||
<p>
|
||||
Click on a question to toggle between true / false.
|
||||
</p>
|
||||
<p>
|
||||
Ensure your candidate number is entered in the below box.
|
||||
</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Candidate number: <input type="number" id="cid" name="cid" title="please enter your candidate number">
|
||||
</div>
|
||||
|
||||
<h2>Questions</h2>
|
||||
|
||||
{% autoescape off %}
|
||||
<ol id="full-question-list-physics">
|
||||
{% for question in questions.all %}
|
||||
|
||||
<li>
|
||||
{{ question.stem }}
|
||||
<ol type="a" class="abcde">
|
||||
<li>
|
||||
<span class="question-text">{{ question.a }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question a" id="{{question.pk}}-a-checkbox" data-q="{{question.pk}}"
|
||||
data-a="a">
|
||||
<div class="slider round a"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.b }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question b" id="{{question.pk}}-b-checkbox" data-q="{{question.pk}}"
|
||||
data-a="b">
|
||||
<div class="slider round b"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.c }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question c" id="{{question.pk}}-c-checkbox" data-q="{{question.pk}}"
|
||||
data-a="c">
|
||||
<div class="slider round c"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.d }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question d" id="{{question.pk}}-d-checkbox" data-q="{{question.pk}}"
|
||||
data-a="d">
|
||||
<div class="slider round d"></div>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<span class="question-text">{{ question.e }}:</span> <label class="truefalse-switch"> <input
|
||||
type="checkbox" class="question e" id="{{question.pk}}-e-checkbox" data-q="{{question.pk}}"
|
||||
data-a="e">
|
||||
<div class="slider round e"></div>
|
||||
</label>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% endautoescape %}
|
||||
|
||||
|
||||
<button id="submit">Submit answers</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
window.answers_submitted = false;
|
||||
$(document).ready(function () {
|
||||
console.log($(".question-text"));
|
||||
$(".question-text").click(function (evt) {
|
||||
$(evt.target).parent().find("input").click();
|
||||
});
|
||||
|
||||
$("#submit").click(() => {
|
||||
let cid = $("#cid").val()
|
||||
if (cid == "") {
|
||||
alert("You need to enter a valid candidate number.");
|
||||
$("#cid").focus();
|
||||
return
|
||||
}
|
||||
|
||||
answers = [];
|
||||
|
||||
|
||||
$("input.question").each((n, el) => {
|
||||
answers.push([el.dataset.q, el.dataset.a, el.checked]);
|
||||
|
||||
})
|
||||
|
||||
ans = {
|
||||
cid: parseInt(cid),
|
||||
eid: {{exam.pk}},
|
||||
ans: answers
|
||||
}
|
||||
|
||||
let json = {
|
||||
eid: {{exam.pk}},
|
||||
answers: JSON.stringify([ans]),
|
||||
};
|
||||
|
||||
postAnswers(json);
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
window.onbeforeunload = confirmExit;
|
||||
function confirmExit() {
|
||||
if (!window.answers_submitted) {
|
||||
return "You have attempted to leave this page. Are you sure?";
|
||||
}
|
||||
}
|
||||
|
||||
function postAnswers(ans) {
|
||||
console.log(ans);
|
||||
$.post("{% url 'physics:exam_answers_submit' %}", ans, null, "json").done((data) => {
|
||||
console.log(data);
|
||||
if (data.success) {
|
||||
let ret = confirm(
|
||||
`Answers sucessfully submitted. Click OK to finish the exam.`
|
||||
);
|
||||
|
||||
if (ret) {
|
||||
//window.saveSession();
|
||||
$("#exams-button-link").remove();
|
||||
$("#submit").after('<button id="exams-button-link">Return to exam list</button>');
|
||||
$("#exams-button-link").click(() => {
|
||||
window.location.href = "{% url 'physics:active_exams' %}";
|
||||
})
|
||||
window.answers_submitted = true;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
alert(`Error submitting answers: ${data.error}`);
|
||||
}
|
||||
});
|
||||
// $.post( "http://localhost:8000/submit_answers", JSON.stringify(ans));
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.truefalse-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
margin: 0px;
|
||||
margin-bottom: -5px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.truefalse-switch input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 4, 255, 0.5);
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 4px;
|
||||
bottom: 2px;
|
||||
background-color: white;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked+.slider {
|
||||
background-color: rgba(162, 0, 255, 0.5);
|
||||
}
|
||||
|
||||
input:focus+.slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked+.slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(68px);
|
||||
}
|
||||
|
||||
/*------ ADDED CSS ---------*/
|
||||
.slider:after {
|
||||
color: white;
|
||||
display: block;
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
font-size: 10px;
|
||||
font-family: Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.a.slider:after {
|
||||
content: 'a) FALSE';
|
||||
}
|
||||
|
||||
.b.slider:after {
|
||||
content: 'b) FALSE';
|
||||
}
|
||||
|
||||
.c.slider:after {
|
||||
content: 'c) FALSE';
|
||||
}
|
||||
|
||||
.d.slider:after {
|
||||
content: 'd) FALSE';
|
||||
}
|
||||
|
||||
.e.slider:after {
|
||||
content: 'e) FALSE';
|
||||
}
|
||||
|
||||
input:checked+.slider.a:after {
|
||||
content: 'a )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.b:after {
|
||||
content: 'b )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.c:after {
|
||||
content: 'c )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.d:after {
|
||||
content: 'd )TRUE';
|
||||
}
|
||||
|
||||
input:checked+.slider.e:after {
|
||||
content: 'e )TRUE';
|
||||
}
|
||||
|
||||
.question-text {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
clear: both;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.abcde {
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
+4
-1
@@ -13,7 +13,10 @@ urlpatterns = [
|
||||
#path("question/<int:pk>/update", views.QuestionUpdate.as_view(), name="anatomy_question_update"),
|
||||
#path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
#path("exam/<int:pk>/mark", views.mark_overview, name="mark_overview"),
|
||||
path("exam/<int:pk>/take", views.exam_take, name="exam_take"),
|
||||
path("exam/<int:pk>/take_old", views.exam_take_old, name="exam_take_old"),
|
||||
path("exam/<int:pk>/<int:sk>/<str:cid>/take", views.exam_take, name="exam_take"),
|
||||
path("exam/<int:pk>/start", views.exam_start, name="exam_start"),
|
||||
path("exam/<int:pk>/<str:cid>/finish", views.exam_finish, name="exam_finish"),
|
||||
path("exam/<int:pk>/", views.PhysicsExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/scores", views.exam_scores_cid,
|
||||
name="exam_scores_cid"),
|
||||
|
||||
+119
-3
@@ -46,7 +46,7 @@ from rest_framework.pagination import PageNumberPagination
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from .forms import ExamForm
|
||||
from .forms import CidUserAnswerForm, ExamForm
|
||||
from .decorators import user_is_author_or_physics_checker, user_is_exam_author_or_physics_checker
|
||||
|
||||
class AuthorOrCheckerRequiredMixin(object):
|
||||
@@ -240,7 +240,7 @@ def exam_scores_cid_user(request, pk, sk):
|
||||
)
|
||||
|
||||
|
||||
def exam_take(request, pk):
|
||||
def exam_take_old(request, pk):
|
||||
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
@@ -251,13 +251,129 @@ def exam_take(request, pk):
|
||||
|
||||
return render(
|
||||
request,
|
||||
"physics/exam_take.html",
|
||||
"physics/exam_take_old.html",
|
||||
{
|
||||
"exam": exam,
|
||||
"questions": questions,
|
||||
},
|
||||
)
|
||||
|
||||
def exam_start(request, pk):
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
if not exam.active:
|
||||
raise Http404("Exam not found")
|
||||
|
||||
return render(
|
||||
request,
|
||||
"physics/exam_start.html",
|
||||
{
|
||||
"exam": exam,
|
||||
},
|
||||
)
|
||||
|
||||
def exam_finish(request, pk, cid):
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
questions = exam.exam_questions.all()
|
||||
|
||||
answers = CidUserAnswer.objects.filter(
|
||||
cid=cid, exam=exam)
|
||||
|
||||
answer_question_map = {}
|
||||
for ans in answers:
|
||||
answer_question_map[ans.question] = ans
|
||||
|
||||
question_answer_tuples = []
|
||||
answer_count = 0
|
||||
for q in questions:
|
||||
if q in answer_question_map and answer_question_map[q].answer:
|
||||
question_answer_tuples.append((q, answer_question_map[q]))
|
||||
answer_count += 1
|
||||
else:
|
||||
question_answer_tuples.append((q, None))
|
||||
|
||||
if not exam.active:
|
||||
raise Http404("Exam not found")
|
||||
|
||||
return render(
|
||||
request,
|
||||
"physics/exam_finish.html",
|
||||
{
|
||||
"exam": exam,
|
||||
"cid": cid,
|
||||
"question_answer_tuples": question_answer_tuples,
|
||||
"answer_count": answer_count,
|
||||
"exam_length": len(questions),
|
||||
},
|
||||
)
|
||||
|
||||
def exam_take(request, pk, sk, cid):
|
||||
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
if not exam.active:
|
||||
raise Http404("Exam not found")
|
||||
|
||||
question = exam.exam_questions.all()[sk]
|
||||
|
||||
exam_length = len(exam.exam_questions.all())
|
||||
|
||||
pos = exam.get_question_index(question)
|
||||
|
||||
answer = question.cid_user_answers.filter(
|
||||
cid=cid, exam=exam).first()
|
||||
|
||||
if request.method == "POST":
|
||||
if answer:
|
||||
form = CidUserAnswerForm(request.POST, instance=answer)
|
||||
else:
|
||||
form = CidUserAnswerForm(request.POST)
|
||||
if form.is_valid():
|
||||
answer = form.save(commit=False)
|
||||
answer.cid = cid
|
||||
answer.question = question
|
||||
answer.exam = exam
|
||||
# answer.published_date = timezone.now()
|
||||
answer.save()
|
||||
if "next" in request.POST:
|
||||
return redirect("sbas:exam_take", pk=pk, sk=pos + 1, cid=cid)
|
||||
elif "previous" in request.POST:
|
||||
return redirect("sbas:exam_take", pk=pk, sk=pos - 1, cid=cid)
|
||||
elif "finish" in request.POST:
|
||||
return redirect("sbas:exam_finish", pk=pk, cid=cid)
|
||||
elif "goto" in request.POST:
|
||||
return redirect("sbas:exam_take", pk=pk, sk=int(request.POST.get("goto")), cid=cid)
|
||||
else:
|
||||
form = CidUserAnswerForm(instance=answer)
|
||||
|
||||
previous = -1
|
||||
if sk > 0:
|
||||
previous = sk - 1
|
||||
next = sk + 1
|
||||
if sk == exam_length - 1:
|
||||
next = False
|
||||
|
||||
saved_answer = False
|
||||
if answer is not None:
|
||||
saved_answer = answer.answer
|
||||
|
||||
|
||||
return render(
|
||||
request,
|
||||
"physics/exam_take.html",
|
||||
{
|
||||
"form": form,
|
||||
"cid": cid,
|
||||
"exam": exam,
|
||||
"question": question,
|
||||
"next": next,
|
||||
"previous": previous,
|
||||
"exam_length": exam_length,
|
||||
"pos": pos,
|
||||
"saved_answer": saved_answer,
|
||||
},
|
||||
)
|
||||
|
||||
def loadJsonAnswer(answer):
|
||||
# As access is not restricted make sure the data appears valid
|
||||
|
||||
Reference in New Issue
Block a user