Implement exam selection feature with HTMX support in exam edit view and add exam selection fragment template
This commit is contained in:
@@ -433,6 +433,22 @@ def get_examination_id(request):
|
|||||||
# Generic view to dispatch to indivuals app views
|
# Generic view to dispatch to indivuals app views
|
||||||
@login_required
|
@login_required
|
||||||
def generic_exam_json_edit(request):
|
def generic_exam_json_edit(request):
|
||||||
|
# GET: return a small fragment with an exam selector for the given type
|
||||||
|
if request.method == "GET":
|
||||||
|
question_type = request.GET.get("type")
|
||||||
|
if not question_type:
|
||||||
|
return JsonResponse({"status": "error", "message": "missing type"}, status=400)
|
||||||
|
try:
|
||||||
|
Exam = get_exam_model_from_app_name(question_type)
|
||||||
|
except Exception:
|
||||||
|
return JsonResponse({"status": "error", "message": "unknown type"}, status=400)
|
||||||
|
|
||||||
|
# Limit to exams that are not archived and are exam_mode
|
||||||
|
exams = Exam.objects.filter(archive=False, exam_mode=True).order_by("name")[:200]
|
||||||
|
return render(request, "generic/partials/exam_select_fragment.html", {"exams": exams, "type": question_type})
|
||||||
|
|
||||||
|
# Support POST additions via either an explicit JSON 'add_exam_questions' or
|
||||||
|
# via a list of checkboxes named 'selection' sent by HTMX from the question list.
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
question_type = request.POST.get("type")
|
question_type = request.POST.get("type")
|
||||||
|
|
||||||
@@ -468,6 +484,16 @@ def generic_exam_json_edit(request):
|
|||||||
|
|
||||||
if "add_exam_questions" in request.POST:
|
if "add_exam_questions" in request.POST:
|
||||||
question_ids = json.loads(request.POST.get("add_exam_questions"))
|
question_ids = json.loads(request.POST.get("add_exam_questions"))
|
||||||
|
else:
|
||||||
|
# Support HTMX flow where checkboxes named 'selection' are posted
|
||||||
|
# (multiple values). Convert to list of ints.
|
||||||
|
sel = request.POST.getlist("selection") or request.POST.getlist("selection[]")
|
||||||
|
question_ids = []
|
||||||
|
for s in sel:
|
||||||
|
try:
|
||||||
|
question_ids.append(int(s))
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
# question_objects = Question.objects.filter(pk__in=question_ids)
|
# question_objects = Question.objects.filter(pk__in=question_ids)
|
||||||
|
|
||||||
add_count = 0
|
add_count = 0
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form hx-post="{% url 'generic:generic_exam_json_edit' %}" hx-target="#action-result" hx-swap="innerHTML">
|
||||||
|
<input type="hidden" name="type" value="{{ type }}" />
|
||||||
|
<div class="mb-2">
|
||||||
|
<label for="id_exam_id">Choose exam</label>
|
||||||
|
<select name="exam_id" id="id_exam_id" class="form-select form-select-sm">
|
||||||
|
{% for ex in exams %}
|
||||||
|
<option value="{{ ex.pk }}">{{ ex.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<label>Selected questions</label>
|
||||||
|
<div class="selected-placeholder small text-muted">(will be taken from selected checkboxes)</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<button class="btn btn-primary btn-sm" type="submit" name="add_from_selection">Add selected</button>
|
||||||
|
<button class="btn btn-secondary btn-sm" type="button" onclick="document.querySelector('#action-result').innerHTML='';">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button id="button-select-add-exam" class="btn btn-outline-primary btn-sm"
|
<button id="button-select-add-exam" class="btn btn-outline-primary btn-sm"
|
||||||
data-exam_json_edit_url="{% url 'generic:generic_exam_json_edit' %}"
|
hx-get="{% url 'generic:generic_exam_json_edit' %}?type={{ app_name }}"
|
||||||
data-exam_list_url="{% url 'api-1:'|add:app_name|add:'_user_exams' %}"
|
hx-target="#action-result"
|
||||||
data-type={{app_name}} data-csrf="{{ csrf_token }}">Add to exam</button>
|
hx-swap="innerHTML">Add to exam</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user