186 lines
7.8 KiB
HTML
Executable File
186 lines
7.8 KiB
HTML
Executable File
{% extends 'base.html' %}
|
|
|
|
{% block content %}
|
|
<div class="py-3">
|
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
|
|
<span id="user-id" class="text-muted small">
|
|
{% if request.user.is_authenticated %}
|
|
User: {{ request.user }}
|
|
{% else %}
|
|
CID: {{ cid }}
|
|
{% endif %}
|
|
</span>
|
|
<h2 class="h5 mt-1">{{ exam }}: Question <small class="text-muted">[<span id="question-number">{{ pos|add:1 }}</span>/<span id="exam-length">{{ exam_length }}</span>]</small></h2>
|
|
|
|
<div class="">
|
|
{% include "exam_clock.html" %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if exam.publish_results %}
|
|
<div class="alert alert-primary review-mode-alert" role="alert">
|
|
Exam is in review mode. Add question feedback <a href="#" onclick="return window.create_popup_window('{% url 'feedback_create' question_type='sbas' pk=question.pk %}')">here</a>.
|
|
</div>
|
|
{% elif cid_user_exam.completed %}
|
|
<div class="alert alert-primary review-mode-alert" role="alert">Exam completed.</div>
|
|
{% endif %}
|
|
|
|
<div class="row flex-wrap">
|
|
{# Layout change: make both columns full-width so the right panel is not a sidebar #}
|
|
<div class="col-12 order-1 mb-3">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div id="question-stem" class="mb-3">{{ question.stem|safe }}</div>
|
|
|
|
<ul class="sba-answer-list list-group">
|
|
<li class="list-group-item" data-ans="a">{{ question.a_answer|safe }}</li>
|
|
<li class="list-group-item" data-ans="b">{{ question.b_answer|safe }}</li>
|
|
<li class="list-group-item" data-ans="c">{{ question.c_answer|safe }}</li>
|
|
<li class="list-group-item" data-ans="d">{{ question.d_answer|safe }}</li>
|
|
<li class="list-group-item" data-ans="e">{{ question.e_answer|safe }}</li>
|
|
</ul>
|
|
|
|
<form method="POST" class="post-form mt-3">{% csrf_token %}
|
|
<div class="form-contents visually-hidden">{{ form }}</div>
|
|
|
|
<div class="d-flex flex-column flex-sm-row gap-2 mt-2">
|
|
<div class="d-flex gap-2 flex-wrap">
|
|
{% if previous > -1 %}
|
|
<button type="submit" name="previous" class="btn btn-outline-secondary" title="Save and go to previous">Previous</button>
|
|
{% endif %}
|
|
|
|
{% if next %}
|
|
<button type="submit" name="next" class="btn btn-primary">Next</button>
|
|
{% else %}
|
|
{% if not exam.publish_results %}
|
|
<button type="submit" name="save" class="btn btn-success">Save</button>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="ms-sm-auto">
|
|
{% if exam.publish_results and question.feedback %}
|
|
<div class="mt-2 mt-sm-0">
|
|
<h6 class="mb-1">Feedback</h6>
|
|
<div>{{ question.feedback|safe }}</div>
|
|
</div>
|
|
{% endif %}
|
|
<button type="submit" name="finish" class="btn btn-outline-primary ms-0 ms-sm-2 mt-2 mt-sm-0">Overview</button>
|
|
<button type="submit" id="goto-button" value="test" name="goto" class="visually-hidden">goto</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 order-2 mb-3">
|
|
{% include "sbas/exam_take_help.html" %}
|
|
|
|
<div class="card mt-3">
|
|
<div class="card-body">
|
|
<h6 class="card-title">Questions</h6>
|
|
<p class="small text-muted mb-2">Tap a number to jump to that question.</p>
|
|
|
|
<!-- Collapsible for small screens -->
|
|
<div class="d-md-none mb-2">
|
|
<button class="btn btn-sm btn-outline-secondary w-100" type="button" data-bs-toggle="collapse" data-bs-target="#menu-list" aria-expanded="false" aria-controls="menu-list">
|
|
Show questions
|
|
</button>
|
|
</div>
|
|
|
|
<div id="menu-list" class="collapse d-md-block">
|
|
<div class="d-flex flex-wrap gap-1" id="menu-buttons" role="toolbar" aria-label="Question navigation">
|
|
<!-- Buttons injected by JS -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(() => {
|
|
/* beautify ignore:start */
|
|
{% if not exam.publish_results and not cid_user_exam.completed %}
|
|
|
|
let time_limit = '{{exam.time_limit}}'
|
|
if (time_limit != "None") {
|
|
let end_time = new Date({{cid_user_exam.start_time|date:"U"}}*1000+parseInt('{{exam.time_limit}}')*1000);
|
|
|
|
initializeClock("clockdiv", end_time);
|
|
}
|
|
|
|
$("ul.sba-answer-list li").each((n, el) => {
|
|
$(el).click((e) => {
|
|
$("#id_answer").val(el.dataset.ans);
|
|
$("ul.sba-answer-list li").removeClass("selected");
|
|
$(el).addClass("selected")
|
|
})
|
|
})
|
|
{% elif exam.publish_results %}
|
|
$("ul.sba-answer-list li[data-ans='{{question.best_answer}}']").addClass("correct");
|
|
{% endif %}
|
|
|
|
{% if saved_answer %}
|
|
$("ul.sba-answer-list li[data-ans='{{saved_answer}}']").addClass("selected"); {% endif %}
|
|
|
|
for (let i = 0; i < {{ exam_length }}; i++) {
|
|
// Create Bootstrap-styled buttons and append into the flex-wrap container
|
|
qbutton = $(`<button type="button" class="btn btn-sm btn-outline-secondary question-menu-item" name="goto-${i}" data-qn="${i}">${i+1}</button>`)
|
|
|
|
if (i == {{pos}}) {qbutton.addClass("current-question")}
|
|
$("#menu-buttons").append(qbutton);
|
|
|
|
}
|
|
$("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();
|
|
});
|
|
|
|
|
|
})
|
|
</script>
|
|
{% endblock %}
|
|
{% block css %}
|
|
<style type="text/css">
|
|
.form-contents {
|
|
display: none;
|
|
}
|
|
|
|
.selected {
|
|
border: 1px solid purple;
|
|
}
|
|
.sba-answer-list li:hover::before {
|
|
content: "Click to select";
|
|
float: right
|
|
}
|
|
|
|
.sba-answer-list li:hover.selected::before {
|
|
content: "Chosen answer";
|
|
float: right
|
|
}
|
|
|
|
/* Make question nav buttons consistent and allow wrapping on small screens */
|
|
.question-menu-item {
|
|
white-space: nowrap;
|
|
flex: 0 0 auto;
|
|
padding: .1rem .1rem;
|
|
}
|
|
|
|
/* Disable sticky behaviour on narrow viewports so the sidebar stacks naturally */
|
|
@media (max-width: 767.98px) {
|
|
.card.sticky-top {
|
|
position: static !important;
|
|
top: auto !important;
|
|
}
|
|
}
|
|
|
|
</style>
|
|
{% endblock %} |