From dfa5ed407be7bc496b23a1d52c71a8282caa3997 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;