Enhance exam review question fragment by ensuring safe rendering of question and answers, improving layout for answer feedback, and refining button alignment for better UI consistency.

This commit is contained in:
Ross
2025-11-10 09:14:17 +00:00
parent 3c31246636
commit 390f6f098d
@@ -2,19 +2,19 @@
<div class="card-body"> <div class="card-body">
<div class="mb-2"><span class="badge bg-dark">SBAs</span></div> <div class="mb-2"><span class="badge bg-dark">SBAs</span></div>
<h5 class="card-title">Question</h5> <h5 class="card-title">Question</h5>
<p class="lead">{{ question }}</p> <p class="lead">{{ question|safe }}</p>
{# Use per-field answers (a..e) from sbas Question model and highlight the best answer #} {# Use per-field answers (a..e) from sbas Question model and highlight the best answer #}
<div class="mt-3"> <div class="mt-3">
<h6>Answers</h6> <h6>Answers</h6>
<ul class="list-group"> <ul class="list-group">
{% if question.a_answer %} {% if question.a_answer %}
<li class="list-group-item d-flex justify-content-between align-items-start{% if question.best_answer == 'a' %} list-group-item-success{% endif %}"> <li class="list-group-item d-flex flex-column flex-md-row justify-content-between align-items-start{% if question.best_answer == 'a' %} list-group-item-success{% endif %}">
<div> <div class="mb-2 mb-md-0">
<strong class="me-2">A.</strong> <strong class="me-2">A.</strong>
<span>{{ question.a_answer }}</span> <span class="answer-content">{{ question.a_answer|safe }}</span>
{% if question.a_feedback %} {% if question.a_feedback %}
<div class="small text-muted">Feedback: {{ question.a_feedback }}</div> <div class="small text-muted mt-1">Feedback: <span class="feedback-content">{{ question.a_feedback|safe }}</span></div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
@@ -28,12 +28,12 @@
{% endif %} {% endif %}
{% if question.b_answer %} {% if question.b_answer %}
<li class="list-group-item d-flex justify-content-between align-items-start{% if question.best_answer == 'b' %} list-group-item-success{% endif %}"> <li class="list-group-item d-flex flex-column flex-md-row justify-content-between align-items-start{% if question.best_answer == 'b' %} list-group-item-success{% endif %}">
<div> <div class="mb-2 mb-md-0">
<strong class="me-2">B.</strong> <strong class="me-2">B.</strong>
<span>{{ question.b_answer }}</span> <span class="answer-content">{{ question.b_answer|safe }}</span>
{% if question.b_feedback %} {% if question.b_feedback %}
<div class="small text-muted">Feedback: {{ question.b_feedback }}</div> <div class="small text-muted mt-1">Feedback: <span class="feedback-content">{{ question.b_feedback|safe }}</span></div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
@@ -47,12 +47,12 @@
{% endif %} {% endif %}
{% if question.c_answer %} {% if question.c_answer %}
<li class="list-group-item d-flex justify-content-between align-items-start{% if question.best_answer == 'c' %} list-group-item-success{% endif %}"> <li class="list-group-item d-flex flex-column flex-md-row justify-content-between align-items-start{% if question.best_answer == 'c' %} list-group-item-success{% endif %}">
<div> <div class="mb-2 mb-md-0">
<strong class="me-2">C.</strong> <strong class="me-2">C.</strong>
<span>{{ question.c_answer }}</span> <span class="answer-content">{{ question.c_answer|safe }}</span>
{% if question.c_feedback %} {% if question.c_feedback %}
<div class="small text-muted">Feedback: {{ question.c_feedback }}</div> <div class="small text-muted mt-1">Feedback: <span class="feedback-content">{{ question.c_feedback|safe }}</span></div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
@@ -66,12 +66,12 @@
{% endif %} {% endif %}
{% if question.d_answer %} {% if question.d_answer %}
<li class="list-group-item d-flex justify-content-between align-items-start{% if question.best_answer == 'd' %} list-group-item-success{% endif %}"> <li class="list-group-item d-flex flex-column flex-md-row justify-content-between align-items-start{% if question.best_answer == 'd' %} list-group-item-success{% endif %}">
<div> <div class="mb-2 mb-md-0">
<strong class="me-2">D.</strong> <strong class="me-2">D.</strong>
<span>{{ question.d_answer }}</span> <span class="answer-content">{{ question.d_answer|safe }}</span>
{% if question.d_feedback %} {% if question.d_feedback %}
<div class="small text-muted">Feedback: {{ question.d_feedback }}</div> <div class="small text-muted mt-1">Feedback: <span class="feedback-content">{{ question.d_feedback|safe }}</span></div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
@@ -85,12 +85,12 @@
{% endif %} {% endif %}
{% if question.e_answer %} {% if question.e_answer %}
<li class="list-group-item d-flex justify-content-between align-items-start{% if question.best_answer == 'e' %} list-group-item-success{% endif %}"> <li class="list-group-item d-flex flex-column flex-md-row justify-content-between align-items-start{% if question.best_answer == 'e' %} list-group-item-success{% endif %}">
<div> <div class="mb-2 mb-md-0">
<strong class="me-2">E.</strong> <strong class="me-2">E.</strong>
<span>{{ question.e_answer }}</span> <span class="answer-content">{{ question.e_answer|safe }}</span>
{% if question.e_feedback %} {% if question.e_feedback %}
<div class="small text-muted">Feedback: {{ question.e_feedback }}</div> <div class="small text-muted mt-1">Feedback: <span class="feedback-content">{{ question.e_feedback|safe }}</span></div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
@@ -112,7 +112,7 @@
{# Aggregated summary: HTMX-loaded automatically on fragment load #} {# Aggregated summary: HTMX-loaded automatically on fragment load #}
<div class="mt-3"> <div class="mt-3">
<h6>Response summary</h6> <h6>Response summary</h6>
<div id="response-summary" <div id="response-summary"
hx-get="{% url 'sbas:exam_review_question_summary' exam.pk q_index %}" hx-get="{% url 'sbas:exam_review_question_summary' exam.pk q_index %}"
hx-trigger="load" hx-trigger="load"
hx-swap="innerHTML"> hx-swap="innerHTML">
@@ -124,7 +124,7 @@
<div class="mt-3"> <div class="mt-3">
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<div> <div>
<button class="btn btn-sm btn-outline-primary" <button class="btn btn-sm btn-outline-primary"
hx-get="{% url 'sbas:exam_review_question_responses' exam.pk q_index %}" hx-get="{% url 'sbas:exam_review_question_responses' exam.pk q_index %}"
hx-target="#responses-container" hx-target="#responses-container"
hx-swap="innerHTML">Show responses</button> hx-swap="innerHTML">Show responses</button>
@@ -134,26 +134,26 @@
<div class="text-muted small">Responses are hidden — click “Show responses” to load.</div> <div class="text-muted small">Responses are hidden — click “Show responses” to load.</div>
</div> </div>
<div class="d-flex justify-content-between mt-3"> <div class="d-flex justify-content-between mt-3">
{% if prev_index is not None %} {% if prev_index is not None %}
<a class="btn btn-outline-primary" <a class="btn btn-outline-primary"
hx-get="{% url app_name|add:':exam_review_question' exam.pk prev_index %}" hx-get="{% url app_name|add:':exam_review_question' exam.pk prev_index %}"
hx-target="#review-content" hx-target="#review-content"
hx-swap="innerHTML" hx-swap="innerHTML"
hx-push-url="true">&larr; Previous</a> hx-push-url="true">&larr; Previous</a>
{% else %} {% else %}
<span></span> <span></span>
{% endif %} {% endif %}
{% if next_index is not None %} {% if next_index is not None %}
<a class="btn btn-primary" <a class="btn btn-primary"
hx-get="{% url app_name|add:':exam_review_question' exam.pk next_index %}" hx-get="{% url app_name|add:':exam_review_question' exam.pk next_index %}"
hx-target="#review-content" hx-target="#review-content"
hx-swap="innerHTML" hx-swap="innerHTML"
hx-push-url="true">Next &rarr;</a> hx-push-url="true">Next &rarr;</a>
{% else %} {% else %}
<a class="btn btn-success" href="{% url app_name|add:':exam_overview' exam.pk %}">Complete review</a> <a class="btn btn-success" href="{% url app_name|add:':exam_overview' exam.pk %}">Complete review</a>
{% endif %} {% endif %}
</div>
</div> </div>
</div> </div>
</div>