enhance rota_options view to support typed form submissions and improve error handling

This commit is contained in:
Ross
2025-12-09 20:43:46 +00:00
parent 724e3ab6bd
commit 48c219281e
+35 -27
View File
@@ -330,41 +330,49 @@ def rota_options(request, rota_id):
is_hx = request.headers.get("HX-Request", "false").lower() == "true" is_hx = request.headers.get("HX-Request", "false").lower() == "true"
if request.method == "POST": if request.method == "POST":
options_json = request.POST.get("options_json", "") # Support two POST modes: legacy `options_json` textarea, or the typed
try: # form generated by `RotaScheduleForm` (fields prefixed with `opt__`).
parsed = json.loads(options_json) if options_json.strip() else {} if "options_json" in request.POST:
except Exception as exc: options_json = request.POST.get("options_json", "")
if is_hx: try:
parsed = json.loads(options_json) if options_json.strip() else {}
except Exception as exc:
if is_hx:
return HttpResponseBadRequest(f"Invalid JSON: {exc}")
return HttpResponseBadRequest(f"Invalid JSON: {exc}") return HttpResponseBadRequest(f"Invalid JSON: {exc}")
return HttpResponseBadRequest(f"Invalid JSON: {exc}")
rota.options = parsed rota.options = parsed
rota.save(update_fields=["options"]) rota.save(update_fields=["options"])
if is_hx:
return _oob_update_options_display(request, rota)
return redirect(reverse("rota:rota_detail", args=(rota.id,)))
# Typed form submission
from .forms import RotaScheduleForm
form = RotaScheduleForm(request.POST, instance=rota)
if not form.is_valid():
if is_hx:
# Re-render modal with errors
modal_html = render_to_string(
"rota/partials/rota_options_modal.html",
{"form_action": reverse("rota:rota_options", args=(rota.id,)), "form": form, "rota": rota},
request=request,
)
return HttpResponse(modal_html)
return HttpResponseBadRequest("Invalid form submission")
form.save()
if is_hx: if is_hx:
# render display snippet and send OOB swap to update it and clear modal return _oob_update_options_display(request, rota)
options_pretty = json.dumps(rota.options or {}, indent=4)
options_html = render_to_string(
"rota/partials/rota_options_display.html",
{"rota": rota, "options_pretty": options_pretty},
request=request,
)
resp = '<div id="rota-options-display" hx-swap-oob="true">' + options_html + '</div>' + '<div id="modal" hx-swap-oob="true"></div>'
response = HttpResponse(resp)
response["HX-Trigger"] = "closeModal"
return response
return redirect(reverse("rota:rota_detail", args=(rota.id,))) return redirect(reverse("rota:rota_detail", args=(rota.id,)))
# GET: return modal partial # GET: render modal with typed form populated from the rota instance
try: from .forms import RotaScheduleForm
initial = {"options_json": json.dumps(rota.options or {}, indent=4)} form = RotaScheduleForm(instance=rota)
except Exception:
initial = {"options_json": "{}"}
modal_html = render_to_string( modal_html = render_to_string(
"rota/partials/rota_options_modal.html", "rota/partials/rota_options_modal.html",
{"form_action": reverse("rota:rota_options", args=(rota.id,)), "initial": initial, "rota": rota}, {"form_action": reverse("rota:rota_options", args=(rota.id,)), "form": form, "rota": rota},
request=request, request=request,
) )
return HttpResponse(modal_html) return HttpResponse(modal_html)