diff --git a/src/scripts/contact-form.js b/src/scripts/contact-form.js index 9247554..d993577 100644 --- a/src/scripts/contact-form.js +++ b/src/scripts/contact-form.js @@ -3,6 +3,30 @@ const form = document.getElementById("contact-form"); const resetButton = form.querySelector('button[type="reset"]'); +// Add a div for non-blocking messages +const messageDiv = document.createElement('div'); +messageDiv.id = 'form-message'; +messageDiv.style.display = 'none'; +messageDiv.style.padding = '10px'; +messageDiv.style.marginTop = '10px'; +messageDiv.style.border = '1px solid'; +form.parentNode.insertBefore(messageDiv, form); + + +// Utility: Show a message to the user +function showMessage(text, isError = false) { + messageDiv.textContent = text; + messageDiv.style.display = 'block'; + if (isError) { + messageDiv.style.backgroundColor = '#f8d7da'; + messageDiv.style.borderColor = '#f5c6cb'; + messageDiv.style.color = '#721c24'; + } else { + messageDiv.style.backgroundColor = '#d4edda'; + messageDiv.style.borderColor = '#c3e6cb'; + messageDiv.style.color = '#155724'; + } +} // Utility: Show error for specific input function showError(inputId, message) { @@ -12,10 +36,12 @@ function showError(inputId, message) { if (errorSpan) errorSpan.textContent = message; } -// Utility: Clear all errors +// Utility: Clear all errors and messages function clearErrors() { document.querySelectorAll(".error-message").forEach(span => span.textContent = ""); document.querySelectorAll("input, textarea").forEach(input => input.classList.remove("error")); + messageDiv.style.display = 'none'; + messageDiv.textContent = ''; } form.addEventListener("submit", function(event) { @@ -24,15 +50,13 @@ form.addEventListener("submit", function(event) { clearErrors(); // Clear previous errors const honeypotField = document.getElementById("url").value.trim(); - // Add the honeypot check at the top if (honeypotField.length > 0) { console.warn("Honeypot field was filled. Blocking submission."); - // You might want to display a message to the user, - // but it's often better to fail silently to not alert the bot. - return; // This is the most important part: stop the function here. + // Fail silently to avoid alerting the bot. + return; } - // Get values + // Get values, including the hCaptcha response token const firstName = document.getElementById("first-name").value.trim(); const lastName = document.getElementById("last-name").value.trim(); const organization = document.getElementById("organization").value.trim(); @@ -40,10 +64,12 @@ form.addEventListener("submit", function(event) { const phone = document.getElementById("phone").value.trim(); const contactMethod = document.querySelector('input[name="contact-method"]:checked')?.value; const message = document.getElementById("message").value.trim(); + // Get the hCaptcha token from the global hcaptcha object + const hCaptchaResponse = hcaptcha.getResponse(); let hasErrors = false; - // First Name + // Validation logic... if (!firstName) { showError("first-name", "Please enter your first name."); hasErrors = true; @@ -52,7 +78,6 @@ form.addEventListener("submit", function(event) { hasErrors = true; } - // Last Name if (!lastName) { showError("last-name", "Please enter your last name."); hasErrors = true; @@ -60,79 +85,82 @@ form.addEventListener("submit", function(event) { showError("last-name", "Last name must be at least 2 characters."); hasErrors = true; } - + // Organization (optional) if (organization.length > 0 && organization.length < 2) { showError("organization", "Organization name must be at least 2 characters."); hasErrors = true; } - // Email const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailPattern.test(email)) { showError("email", "Please enter a valid email address."); hasErrors = true; } - // Phone — match format: 123-456-7890 const phonePattern = /^(\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})$/; if (!phonePattern.test(phone)) { showError("phone", "Phone number must be in the format 123-456-7890."); hasErrors = true; } - // Message if (message.length < 10) { showError("message", "Message must be at least 10 characters long."); hasErrors = true; } + + // Check for hCaptcha token + if (!hCaptchaResponse) { + showMessage("Please complete the CAPTCHA.", true); + hasErrors = true; + } + if (!hasErrors) { - // Package the form data into an object - const formData = { - firstName: firstName, - lastName: lastName, - organization: organization, - email: email, - phone: phone, - contactMethod: contactMethod, - message: message, - url: honeypotField, - }; + // Package the form data, including the hCaptcha token + const formData = { + firstName: firstName, + lastName: lastName, + organization: organization, + email: email, + phone: phone, + contactMethod: contactMethod, + message: message, + url: honeypotField, + hCaptchaResponse: hCaptchaResponse // <-- THIS IS THE NEW PART + }; - // Send the data to the backend using fetch() - fetch('/api/submit-form', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(formData), // Convert the data object to a JSON string - }) - .then(response => { - if (response.ok) { - return response.json(); // Parse the JSON response - } - throw new Error('Network response was not ok.'); - }) - .then(data => { - // Success: handle the server's response - console.log('Success:', data); - alert('Form submitted successfully!'); - form.reset(); // Optionally, reset the form after successful submission - }) - .catch((error) => { - // Error: handle any network or server errors - console.error('Error:', error); - alert('An error occurred during submission. Please try again.'); - }); -} + // Send the data to the backend using fetch() + fetch('/submit-form', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }) + .then(response => { + if (response.ok) { + return response.json(); + } + throw new Error('Network response was not ok.'); + }) + .then(data => { + console.log('Success:', data); + showMessage('Form submitted successfully!', false); + form.reset(); + }) + .catch((error) => { + console.error('Error:', error); + showMessage('An error occurred during submission. Please try again.', true); + }); + } }); form.addEventListener("reset", function (event) { - const confirmed = confirm("Are you sure you want to clear the form?"); + const confirmed = window.confirm("Are you sure you want to clear the form?"); if (!confirmed) { - event.preventDefault(); - return; + event.preventDefault(); + return; } clearErrors(); }); \ No newline at end of file