diff --git a/physics/templates/physics/partials/exam_take_overview_fragment.html b/physics/templates/physics/partials/exam_take_overview_fragment.html new file mode 100644 index 00000000..79742fef --- /dev/null +++ b/physics/templates/physics/partials/exam_take_overview_fragment.html @@ -0,0 +1,68 @@ +
+

Overview: {{ exam }}

+

{{ answer_count }} / {{ exam_length }} answered

+ +
+
    + {% for q, ans in question_answer_tuples %} +
  1. +
    + +
    {{ q.stem|truncatechars:140|safe }}
    +
    + {% if ans %} + {% if ans.a or ans.b or ans.c or ans.d or ans.e %} + Answered + {% else %} + Unanswered + {% endif %} + {% else %} + Unanswered + {% endif %} +
    +
    +
  2. + {% endfor %} +
+
+ +
+ +
+ + +
diff --git a/physics/views.py b/physics/views.py index 7f4c26db..b09ec09c 100644 --- a/physics/views.py +++ b/physics/views.py @@ -282,6 +282,42 @@ def exam_take(request, pk: int, sk: int, cid: str | None = None, passcode: str | return exam_take_fragment(request, pk=pk, sk=pos - 1, cid=cid, passcode=passcode) return redirect(take_url, sk=pos - 1, **kwargs) elif "finish" in request.POST: + # For HTMX clients, return an overview fragment so the page can + # update in-place instead of performing a full-page redirect. + if is_htmx: + # Build the same context used by exam_take_overview + questions = exam.get_questions() + if cid is not None: + answers = UserAnswer.objects.filter(cid=cid, exam=exam) + else: + answers = UserAnswer.objects.filter(user=request.user, exam=exam) + + answer_question_map = {ans.question: ans for ans in answers} + + question_answer_tuples = [] + answer_count = 0 + for q in questions: + if q in answer_question_map: + question_answer_tuples.append((q, answer_question_map[q])) + answer_count += 1 + else: + question_answer_tuples.append((q, None)) + + cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user) + + return render( + request, + "physics/partials/exam_take_overview_fragment.html", + { + "exam": exam, + "cid": cid, + "question_answer_tuples": question_answer_tuples, + "answer_count": answer_count, + "exam_length": len(questions), + "passcode": passcode, + "cid_user_exam": cid_user_exam, + }, + ) return redirect(finish_url, **kwargs) elif "save" in request.POST: # Save action should not trigger a full-page load for HTMX clients.