left4me/l4d2web/static/js/modal.js
mwiegand 87d56a0910
fix(web): event-delegate modal triggers so HTMX-swapped buttons work
The previous wiring attached click listeners on DOMContentLoaded, so
any [data-modal-open] / [data-modal-close] / dialog.modal element
that came in via a later HTMX partial swap silently lost its
behaviour. The server-detail Actions partial reloads its reset/delete
triggers on every state change, so reset was unclickable after the
first state change post-load.

Switch to a single delegated click handler on document. Same logic,
but matches via Element.closest() so it works regardless of when an
element was added to the DOM. No re-bind needed after HTMX swaps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 15:18:27 +02:00

34 lines
1.2 KiB
JavaScript

// Event delegation on document so partials swapped in via HTMX (or any
// later DOM mutation) still get modal behaviour without re-binding. The
// previous per-element wiring on DOMContentLoaded silently broke for
// buttons that didn't exist at page load — e.g., the server-detail
// Actions partial reloads its reset/delete triggers on every state
// change, and only the very first ones were ever wired up.
document.addEventListener("click", (event) => {
const opener = event.target.closest("[data-modal-open]");
if (opener) {
const dialog = document.getElementById(opener.getAttribute("data-modal-open"));
if (dialog && typeof dialog.showModal === "function") {
event.preventDefault();
dialog.showModal();
}
return;
}
const closer = event.target.closest("[data-modal-close]");
if (closer) {
const dialog = closer.closest("dialog.modal");
if (dialog) {
event.preventDefault();
dialog.close();
}
return;
}
// Backdrop click: target IS the dialog (clicks on inner content
// don't bubble up as the dialog itself).
if (event.target.matches && event.target.matches("dialog.modal")) {
event.target.close();
}
});