Enhance form rendering with crispy forms and improve answer timestamp handling in collection views

This commit is contained in:
Ross
2025-10-13 13:22:26 +01:00
parent ed4bd95955
commit a3712959ec
3 changed files with 34 additions and 19 deletions
@@ -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
View File
@@ -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)
),
}, },
) )