diff --git a/anatomy/templates/anatomy/view.html b/anatomy/templates/anatomy/view.html index 73605f08..942a302b 100755 --- a/anatomy/templates/anatomy/view.html +++ b/anatomy/templates/anatomy/view.html @@ -6,27 +6,31 @@ {% block content %} -
-

Filter Anatomy Questions

-
- {{ filter.form }} - -
-
-{% render_table table %} +
+

Filter Anatomy Questions

+
+ {{ filter.form }} + +
+
+ {% render_table table %} - -
+ +
- + }); + {% endblock %} \ No newline at end of file diff --git a/generic/urls.py b/generic/urls.py index 708c3164..77cf91fb 100755 --- a/generic/urls.py +++ b/generic/urls.py @@ -34,6 +34,11 @@ urlpatterns = [ views.generic_exam_json_edit, name="generic_exam_json_edit", ), + path( + "generic_exam_htmx", + views.generic_exam_htmx, + name="generic_exam_htmx", + ), path("bulk_delete_questions/", views.bulk_delete_questions, name="bulk_delete_questions"), path( "examination-autocomplete", diff --git a/generic/views.py b/generic/views.py index a04c5824..35b24a88 100644 --- a/generic/views.py +++ b/generic/views.py @@ -567,6 +567,63 @@ def generic_exam_json_edit(request): return JsonResponse(data, status=400) +@login_required +def generic_exam_htmx(request): + """HTMX-specific endpoint for selecting an exam and adding selected questions. + + GET: returns the exam selection fragment (same as earlier partial) + POST: expects 'type' and checkbox list 'selection' (or selection[]) and 'exam_id' + adds selected question ids to the chosen exam and returns a small HTML fragment + or JSON suitable for HTMX swapping. + """ + if request.method == "GET": + question_type = request.GET.get("type") + if not question_type: + return HttpResponse("Missing type", status=400) + try: + Exam = get_exam_model_from_app_name(question_type) + except Exception: + return HttpResponse("Unknown type", status=400) + + 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}) + + if request.method == "POST": + question_type = request.POST.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) + + exam = get_object_or_404(Exam, pk=request.POST.get("exam_id")) + + # read checkbox selections + 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 + + add_count = 0 + for i in question_ids: + if not exam.exam_questions.filter(pk=i).exists(): + add_count += 1 + exam.exam_questions.add(i) + + if add_count > 0: + exam.save() + + # return a small HTMX-friendly fragment summarising the result + return render(request, "generic/partials/exam_select_result.html", {"added": add_count, "exam": exam}) + + return HttpResponse(status=405) + + class ExamViews(View, LoginRequiredMixin): def __init__( self, diff --git a/rapids/templates/rapids/view.html b/rapids/templates/rapids/view.html index 2b842669..0e44b581 100755 --- a/rapids/templates/rapids/view.html +++ b/rapids/templates/rapids/view.html @@ -15,10 +15,12 @@ {% render_table table %} -
diff --git a/templates/generic/partials/exam_select_fragment.html b/templates/generic/partials/exam_select_fragment.html index fbf517fb..11f0884e 100644 --- a/templates/generic/partials/exam_select_fragment.html +++ b/templates/generic/partials/exam_select_fragment.html @@ -1,6 +1,6 @@
-
+
diff --git a/templates/generic/partials/exam_select_result.html b/templates/generic/partials/exam_select_result.html new file mode 100644 index 00000000..03f53f7e --- /dev/null +++ b/templates/generic/partials/exam_select_result.html @@ -0,0 +1,10 @@ + diff --git a/templates/question_table_view.html b/templates/question_table_view.html index e70f9fe1..aebe22e7 100644 --- a/templates/question_table_view.html +++ b/templates/question_table_view.html @@ -21,7 +21,7 @@