fix(lms): js timer form auto-submit and late POST saving

This commit is contained in:
Dmitry Belan
2026-09-20 18:09:29 +03:00
parent f15a584ddc
commit 93a5ed9af7
2 changed files with 53 additions and 46 deletions
+41 -39
View File
@@ -125,52 +125,54 @@
</div> </div>
</div> </div>
<script> <script>
let timeLeft = {{ time_left_seconds }}; document.addEventListener('DOMContentLoaded', function() {
const display = document.getElementById('countdown-display'); let timeLeft = {{ time_left_seconds }};
const form = document.getElementById('assignment-form'); const display = document.getElementById('countdown-display');
const form = document.getElementById('assignment-form');
function updateTimer() { function updateTimer() {
if (timeLeft <= 0) { if (timeLeft <= 0) {
display.textContent = '00:00:00'; display.textContent = '00:00:00';
display.classList.add('text-red-300'); display.classList.add('text-red-300');
// Auto submit // Auto submit
if (form) { if (form) {
// Prevent multiple submissions // Prevent multiple submissions
form.onsubmit = null; form.onsubmit = null;
const btn = form.querySelector('button[type="submit"]'); const btn = form.querySelector('button[type="submit"]');
if (btn) btn.disabled = true; if (btn) btn.disabled = true;
// Append a hidden flag // Append a hidden flag
const input = document.createElement('input'); const input = document.createElement('input');
input.type = 'hidden'; input.type = 'hidden';
input.name = 'auto_submit'; input.name = 'auto_submit';
input.value = '1'; input.value = '1';
form.appendChild(input); form.appendChild(input);
form.submit(); form.submit();
}
return;
} }
return;
const h = Math.floor(timeLeft / 3600);
const m = Math.floor((timeLeft % 3600) / 60);
const s = timeLeft % 60;
display.textContent =
(h > 0 ? (h < 10 ? '0' + h : h) + ':' : '') +
(m < 10 ? '0' + m : m) + ':' +
(s < 10 ? '0' + s : s);
if (timeLeft < 60) {
display.classList.add('text-red-300', 'animate-pulse');
}
timeLeft--;
setTimeout(updateTimer, 1000);
} }
const h = Math.floor(timeLeft / 3600); if (timeLeft > 0) {
const m = Math.floor((timeLeft % 3600) / 60); updateTimer();
const s = timeLeft % 60;
display.textContent =
(h > 0 ? (h < 10 ? '0' + h : h) + ':' : '') +
(m < 10 ? '0' + m : m) + ':' +
(s < 10 ? '0' + s : s);
if (timeLeft < 60) {
display.classList.add('text-red-300', 'animate-pulse');
} }
});
timeLeft--;
setTimeout(updateTimer, 1000);
}
if (timeLeft > 0) {
updateTimer();
}
</script> </script>
{% endif %} {% endif %}
+9 -4
View File
@@ -82,10 +82,15 @@ def assignment_detail(request, pk):
elapsed = (now - submission.started_at).total_seconds() elapsed = (now - submission.started_at).total_seconds()
allowed = assignment.time_limit * 60 allowed = assignment.time_limit * 60
if elapsed > allowed + 60: # 1 minute grace period for network latency if elapsed > allowed + 60: # 1 minute grace period for network latency
can_submit = False if request.method == 'POST':
submission.is_time_expired = True # Allow saving this final POST, but mark it as expired
submission.status = 'PENDING' # Or graded with 0 submission.is_time_expired = True
submission.save() # We don't set can_submit = False here so the POST is processed
else:
can_submit = False
submission.is_time_expired = True
submission.status = 'PENDING' # Or graded with 0
submission.save()
else: else:
time_left_seconds = int(allowed - elapsed) time_left_seconds = int(allowed - elapsed)
if time_left_seconds < 0: if time_left_seconds < 0: