Enhance form rendering with crispy forms and improve answer timestamp handling in collection views
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
{% extends 'atlas/base.html' %}
|
{% extends 'atlas/base.html' %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<span class="collection-name-blend">Collection: {{collection}}</span>
|
<span class="collection-name-blend">Collection: {{collection}}</span>
|
||||||
@@ -218,7 +219,7 @@
|
|||||||
{{form.json.errors}}
|
{{form.json.errors}}
|
||||||
<div class="form-contents">
|
<div class="form-contents">
|
||||||
<fieldset {% if question_completed %}disabled="disabled"{% endif %}>
|
<fieldset {% if question_completed %}disabled="disabled"{% endif %}>
|
||||||
{{form}}
|
{{form | crispy}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -345,6 +346,24 @@
|
|||||||
|
|
||||||
// Question time limit countdown + auto-submit
|
// Question time limit countdown + auto-submit
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
function lockQuestion() {
|
||||||
|
// Only disable save buttons to prevent further saves
|
||||||
|
$form = $('form.post-form');
|
||||||
|
var $saveBtns = $form.find('button[name="save"], #id_answer');
|
||||||
|
if ($saveBtns.length) {
|
||||||
|
$saveBtns.prop('disabled', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visual feedback: set timer to Locked and progress to red
|
||||||
|
$progressInner = $('#question-timer-progress-inner');
|
||||||
|
$('#question-timer').text('Locked');
|
||||||
|
$progressInner.css('background', '#dc3545');
|
||||||
|
$progressInner.css('width', '0%');
|
||||||
|
|
||||||
|
$("#question-timer-progress-outer").hide();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var timeLimit = {{ collection.question_time_limit|default:'null' }};
|
var timeLimit = {{ collection.question_time_limit|default:'null' }};
|
||||||
var questionCompleted = {{ question_completed|yesno:"true,false" }};
|
var questionCompleted = {{ question_completed|yesno:"true,false" }};
|
||||||
@@ -354,6 +373,15 @@
|
|||||||
if (!timeLimit || questionCompleted) {
|
if (!timeLimit || questionCompleted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{% if answer %}
|
||||||
|
if ({{answer.completed|yesno:"true,false"}}) {
|
||||||
|
lockQuestion();
|
||||||
|
console.debug('Timer: answer already completed, aborting timer init');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
var $timer = $('#question-timer');
|
var $timer = $('#question-timer');
|
||||||
var $form = $('form.post-form');
|
var $form = $('form.post-form');
|
||||||
|
|
||||||
@@ -434,16 +462,7 @@
|
|||||||
console.debug('No JSON response from timed_out request', e);
|
console.debug('No JSON response from timed_out request', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only disable save buttons to prevent further saves
|
lockQuestion();
|
||||||
var $saveBtns = $form.find('button[name="save"], #id_answer');
|
|
||||||
if ($saveBtns.length) {
|
|
||||||
$saveBtns.prop('disabled', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visual feedback: set timer to Locked and progress to red
|
|
||||||
$('#question-timer').text('Locked');
|
|
||||||
$progressInner.css('background', '#dc3545');
|
|
||||||
$progressInner.css('width', '0%');
|
|
||||||
|
|
||||||
var msg = 'Answer auto-submitted';
|
var msg = 'Answer auto-submitted';
|
||||||
if (resp && resp.submitted_at) {
|
if (resp && resp.submitted_at) {
|
||||||
|
|||||||
@@ -34,13 +34,13 @@
|
|||||||
<ul>
|
<ul>
|
||||||
{% for cidexam in cidexams %}
|
{% for cidexam in cidexams %}
|
||||||
<li id="cid-history-{{ cidexam.cid_user.pk }}">
|
<li id="cid-history-{{ cidexam.cid_user.pk }}">
|
||||||
<b><a href="{% url 'atlas:collection_history_ciduser' collection.pk cidexam.cid_user.pk %}">{{cidexam.cid_user}}</a><b><br/>
|
<b><a href="{% url 'atlas:collection_history_ciduser' collection.pk cidexam.cid_user.cid %}">{{cidexam.cid_user}}</a><b><br/>
|
||||||
Completed: {{cidexam.completed}}<br/>
|
Completed: {{cidexam.completed}}<br/>
|
||||||
Started: {{cidexam.start_time}}, Ended: {{cidexam.end_time}}<br/>
|
Started: {{cidexam.start_time}}, Ended: {{cidexam.end_time}}<br/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
hx-post="{% url 'atlas:collection_reset_answers_ciduser' collection.pk cidexam.cid_user.pk %}"
|
hx-post="{% url 'atlas:collection_reset_answers_ciduser' collection.pk cidexam.cid_user.cid %}"
|
||||||
hx-target="#cid-history-{{ cidexam.cid_user.pk }}"
|
hx-target="#cid-history-{{ cidexam.cid_user.cid }}"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
hx-confirm="Are you sure you want to delete this CID user's collection history?"
|
hx-confirm="Are you sure you want to delete this CID user's collection history?"
|
||||||
class="btn btn-danger btn-sm remove-button">
|
class="btn btn-danger btn-sm remove-button">
|
||||||
|
|||||||
+1
-5
@@ -2947,11 +2947,7 @@ def collection_case_view_take(
|
|||||||
"cid_user_exam": cid_user_exam,
|
"cid_user_exam": cid_user_exam,
|
||||||
"question_completed": question_completed,
|
"question_completed": question_completed,
|
||||||
"self_review": self_review,
|
"self_review": self_review,
|
||||||
# Provide a canonical start timestamp (prefer answer.started_at, then cid_user_exam.start_time)
|
"answer_started_at_iso": answer.started_at.isoformat() if answer and getattr(answer, 'started_at', None) else None,
|
||||||
"answer_started_at_iso": (
|
|
||||||
(answer.started_at.isoformat() if getattr(answer, 'started_at', None) else None)
|
|
||||||
or (cid_user_exam.start_time.isoformat() if getattr(cid_user_exam, 'start_time', None) else None)
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user