This commit is contained in:
1 parent
a68a6a917c
commit
199264c0a6
3 files changed
+79
-28
No files matched your search
+64
-25
@@ -136,14 +136,37 @@ function setupContactForm() {
|
||||
|
||||
const fields = Array.from(form.querySelectorAll("[data-required], [type='email']"));
|
||||
const status = form.querySelector("[data-form-status]");
|
||||
const submitButton = form.querySelector("button[type='submit']");
|
||||
const action = (form.getAttribute("action") || "").trim();
|
||||
const hasExternalEndpoint = /^https?:\/\//i.test(action);
|
||||
const hasPlaceholderEndpoint = action.includes("YOUR_ID_HERE");
|
||||
const method = (form.getAttribute("method") || "post").toUpperCase();
|
||||
const buttonText = submitButton ? submitButton.textContent : "";
|
||||
|
||||
const validators = {
|
||||
email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
|
||||
};
|
||||
|
||||
const setStatus = (message, state = "") => {
|
||||
if (!status) {
|
||||
return;
|
||||
}
|
||||
|
||||
status.textContent = message;
|
||||
status.classList.toggle("is-success", state === "success");
|
||||
status.classList.toggle("is-error", state === "error");
|
||||
};
|
||||
|
||||
const setSubmitting = (isSubmitting) => {
|
||||
if (!submitButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
submitButton.disabled = isSubmitting;
|
||||
submitButton.setAttribute("aria-busy", String(isSubmitting));
|
||||
submitButton.textContent = isSubmitting ? "Sending..." : buttonText;
|
||||
};
|
||||
|
||||
const setFieldError = (field, message) => {
|
||||
const wrapper = field.closest(".form-field");
|
||||
const error = wrapper ? wrapper.querySelector(".form-field__error") : null;
|
||||
@@ -197,11 +220,7 @@ function setupContactForm() {
|
||||
|
||||
if (!isValid) {
|
||||
event.preventDefault();
|
||||
|
||||
if (status) {
|
||||
status.textContent = "Please review the highlighted fields and try again.";
|
||||
status.classList.remove("is-success");
|
||||
}
|
||||
setStatus("Please review the highlighted fields and try again.", "error");
|
||||
|
||||
const firstInvalid = form.querySelector("[aria-invalid='true']");
|
||||
|
||||
@@ -212,30 +231,50 @@ function setupContactForm() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
status.classList.remove("is-success");
|
||||
}
|
||||
|
||||
if (!hasExternalEndpoint || hasPlaceholderEndpoint) {
|
||||
event.preventDefault();
|
||||
|
||||
if (status) {
|
||||
status.textContent = hasPlaceholderEndpoint
|
||||
? "Replace the Formspree form ID to enable live message delivery."
|
||||
: "Thanks. Your message structure is validated and ready for backend integration.";
|
||||
status.classList.toggle("is-success", !hasPlaceholderEndpoint);
|
||||
}
|
||||
|
||||
if (!hasPlaceholderEndpoint) {
|
||||
form.reset();
|
||||
fields.forEach((field) => setFieldError(field, ""));
|
||||
}
|
||||
|
||||
setStatus("Contact form is currently unavailable. Please try again shortly.", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
status.textContent = "Submitting your message...";
|
||||
}
|
||||
event.preventDefault();
|
||||
setSubmitting(true);
|
||||
setStatus("Sending your message...");
|
||||
|
||||
fetch(action, {
|
||||
method,
|
||||
headers: {
|
||||
Accept: "application/json"
|
||||
},
|
||||
body: new FormData(form)
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (response.ok) {
|
||||
form.reset();
|
||||
fields.forEach((field) => setFieldError(field, ""));
|
||||
setStatus("Thank you. Your contact request was sent and noted.", "success");
|
||||
return;
|
||||
}
|
||||
|
||||
let errorMessage = "Sorry, your message could not be sent. Please try again shortly.";
|
||||
|
||||
try {
|
||||
const payload = await response.json();
|
||||
|
||||
if (payload && Array.isArray(payload.errors) && payload.errors.length > 0) {
|
||||
errorMessage = payload.errors.map((item) => item.message).join(" ");
|
||||
}
|
||||
} catch (parseError) {
|
||||
// Keep fallback message when response body is not JSON.
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
})
|
||||
.catch((error) => {
|
||||
setStatus(error.message, "error");
|
||||
})
|
||||
.finally(() => {
|
||||
setSubmitting(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user