From 2337f1751e887f4dab545030dc1d08e1adbe5343 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Tue, 11 Mar 2025 21:05:52 -0500 Subject: [PATCH] receipt-form: Prompt before leaving unfinished form Whenever any of the fields on the page are changed, the form will be marked as "dirty" until it is submitted. If the form is "dirty" and the user tries to navigate away from the page, the browser will prompt for confirmation before leaving the page. --- js/receipt-form.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/js/receipt-form.ts b/js/receipt-form.ts index a2a6cae..30c29e2 100644 --- a/js/receipt-form.ts +++ b/js/receipt-form.ts @@ -30,6 +30,23 @@ const imgPreview = document.getElementById( ) as HTMLImageElement; const xactselect = document.getElementById("transactions") as SlSelect; +let dirty = false; + +window.addEventListener("beforeunload", function(evt) { + if (dirty) { + evt.preventDefault(); + } +}); + +form.querySelectorAll("sl-input, sl-textarea, input").forEach((inp) => { + let eventName = inp.tagName == "input" ? "cange" : "sl-change"; + inp.addEventListener(eventName, (evt) => { + if ((evt.target as HTMLInputElement).value) { + dirty = true; + } + }); +}); + form.addEventListener("submit", async (evt) => { evt.preventDefault(); btnSubmit.loading = true; @@ -55,6 +72,7 @@ form.addEventListener("submit", async (evt) => { } if (r.ok) { notify("Successfully uploaded receipt", undefined, undefined, null); + dirty = false; window.location.href = "/receipts"; } else { const err = await getResponseError(r); @@ -62,6 +80,10 @@ form.addEventListener("submit", async (evt) => { } }); +form.addEventListener("reset", () => { + dirty = false; +}); + cameraInput.addEventListener("ready", ((evt: CustomEvent) => { btnSubmit.disabled = !evt.detail.hasPhoto; btnUpload.disabled = !!evt.detail.hasPhoto;