app.js
| 1 | // Auto-submit selects marked with data-autosubmit |
| 2 | document.querySelectorAll("[data-autosubmit]").forEach((el) => { |
| 3 | el.addEventListener("change", () => el.closest("form").submit()); |
| 4 | }); |
| 5 | |
| 6 | // Confirm dialogs: <button data-confirm="Are you sure?"> |
| 7 | document.querySelectorAll("[data-confirm]").forEach((el) => { |
| 8 | el.addEventListener("click", (e) => { |
| 9 | if (!confirm(el.dataset.confirm)) e.preventDefault(); |
| 10 | }); |
| 11 | }); |
| 12 | |
| 13 | // Toggle visibility of a target element based on a checkbox: |
| 14 | // <input type="checkbox" data-toggle-target="some-id"> |
| 15 | document.querySelectorAll("[data-toggle-target]").forEach((cb) => { |
| 16 | const target = document.getElementById(cb.dataset.toggleTarget); |
| 17 | if (!target) return; |
| 18 | cb.addEventListener("change", () => { |
| 19 | target.style.display = cb.checked ? "" : "none"; |
| 20 | }); |
| 21 | }); |
| 22 | |
| 23 | // Paste-to-upload: paste an image anywhere on the settings page to fill the avatar input |
| 24 | document.addEventListener("paste", (e) => { |
| 25 | const input = document.querySelector('input[name="avatar"]'); |
| 26 | if (!input) return; |
| 27 | const file = [...(e.clipboardData?.items ?? [])] |
| 28 | .find((i) => i.kind === "file" && i.type.startsWith("image/")) |
| 29 | ?.getAsFile(); |
| 30 | if (!file) return; |
| 31 | const dt = new DataTransfer(); |
| 32 | dt.items.add(file); |
| 33 | input.files = dt.files; |
| 34 | input.closest("form").submit(); |
| 35 | }); |
| 36 |