enhance rota_options view to support typed form submissions and improve error handling
This commit is contained in:
+35
-27
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user