|
|
@ -3,6 +3,30 @@
|
|
|
|
const form = document.getElementById("contact-form");
|
|
|
|
const form = document.getElementById("contact-form");
|
|
|
|
const resetButton = form.querySelector('button[type="reset"]');
|
|
|
|
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
|
|
|
|
// Utility: Show error for specific input
|
|
|
|
function showError(inputId, message) {
|
|
|
|
function showError(inputId, message) {
|
|
|
@ -12,10 +36,12 @@ function showError(inputId, message) {
|
|
|
|
if (errorSpan) errorSpan.textContent = message;
|
|
|
|
if (errorSpan) errorSpan.textContent = message;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Utility: Clear all errors
|
|
|
|
// Utility: Clear all errors and messages
|
|
|
|
function clearErrors() {
|
|
|
|
function clearErrors() {
|
|
|
|
document.querySelectorAll(".error-message").forEach(span => span.textContent = "");
|
|
|
|
document.querySelectorAll(".error-message").forEach(span => span.textContent = "");
|
|
|
|
document.querySelectorAll("input, textarea").forEach(input => input.classList.remove("error"));
|
|
|
|
document.querySelectorAll("input, textarea").forEach(input => input.classList.remove("error"));
|
|
|
|
|
|
|
|
messageDiv.style.display = 'none';
|
|
|
|
|
|
|
|
messageDiv.textContent = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
form.addEventListener("submit", function(event) {
|
|
|
|
form.addEventListener("submit", function(event) {
|
|
|
@ -24,15 +50,13 @@ form.addEventListener("submit", function(event) {
|
|
|
|
clearErrors(); // Clear previous errors
|
|
|
|
clearErrors(); // Clear previous errors
|
|
|
|
|
|
|
|
|
|
|
|
const honeypotField = document.getElementById("url").value.trim();
|
|
|
|
const honeypotField = document.getElementById("url").value.trim();
|
|
|
|
// Add the honeypot check at the top
|
|
|
|
|
|
|
|
if (honeypotField.length > 0) {
|
|
|
|
if (honeypotField.length > 0) {
|
|
|
|
console.warn("Honeypot field was filled. Blocking submission.");
|
|
|
|
console.warn("Honeypot field was filled. Blocking submission.");
|
|
|
|
// You might want to display a message to the user,
|
|
|
|
// Fail silently to avoid alerting the bot.
|
|
|
|
// but it's often better to fail silently to not alert the bot.
|
|
|
|
return;
|
|
|
|
return; // This is the most important part: stop the function here.
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get values
|
|
|
|
// Get values, including the hCaptcha response token
|
|
|
|
const firstName = document.getElementById("first-name").value.trim();
|
|
|
|
const firstName = document.getElementById("first-name").value.trim();
|
|
|
|
const lastName = document.getElementById("last-name").value.trim();
|
|
|
|
const lastName = document.getElementById("last-name").value.trim();
|
|
|
|
const organization = document.getElementById("organization").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 phone = document.getElementById("phone").value.trim();
|
|
|
|
const contactMethod = document.querySelector('input[name="contact-method"]:checked')?.value;
|
|
|
|
const contactMethod = document.querySelector('input[name="contact-method"]:checked')?.value;
|
|
|
|
const message = document.getElementById("message").value.trim();
|
|
|
|
const message = document.getElementById("message").value.trim();
|
|
|
|
|
|
|
|
// Get the hCaptcha token from the global hcaptcha object
|
|
|
|
|
|
|
|
const hCaptchaResponse = hcaptcha.getResponse();
|
|
|
|
|
|
|
|
|
|
|
|
let hasErrors = false;
|
|
|
|
let hasErrors = false;
|
|
|
|
|
|
|
|
|
|
|
|
// First Name
|
|
|
|
// Validation logic...
|
|
|
|
if (!firstName) {
|
|
|
|
if (!firstName) {
|
|
|
|
showError("first-name", "Please enter your first name.");
|
|
|
|
showError("first-name", "Please enter your first name.");
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
@ -52,7 +78,6 @@ form.addEventListener("submit", function(event) {
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Last Name
|
|
|
|
|
|
|
|
if (!lastName) {
|
|
|
|
if (!lastName) {
|
|
|
|
showError("last-name", "Please enter your last name.");
|
|
|
|
showError("last-name", "Please enter your last name.");
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
@ -67,28 +92,32 @@ form.addEventListener("submit", function(event) {
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Email
|
|
|
|
|
|
|
|
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
|
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
|
if (!emailPattern.test(email)) {
|
|
|
|
if (!emailPattern.test(email)) {
|
|
|
|
showError("email", "Please enter a valid email address.");
|
|
|
|
showError("email", "Please enter a valid email address.");
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Phone — match format: 123-456-7890
|
|
|
|
|
|
|
|
const phonePattern = /^(\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})$/;
|
|
|
|
const phonePattern = /^(\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})$/;
|
|
|
|
if (!phonePattern.test(phone)) {
|
|
|
|
if (!phonePattern.test(phone)) {
|
|
|
|
showError("phone", "Phone number must be in the format 123-456-7890.");
|
|
|
|
showError("phone", "Phone number must be in the format 123-456-7890.");
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Message
|
|
|
|
|
|
|
|
if (message.length < 10) {
|
|
|
|
if (message.length < 10) {
|
|
|
|
showError("message", "Message must be at least 10 characters long.");
|
|
|
|
showError("message", "Message must be at least 10 characters long.");
|
|
|
|
hasErrors = true;
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check for hCaptcha token
|
|
|
|
|
|
|
|
if (!hCaptchaResponse) {
|
|
|
|
|
|
|
|
showMessage("Please complete the CAPTCHA.", true);
|
|
|
|
|
|
|
|
hasErrors = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!hasErrors) {
|
|
|
|
if (!hasErrors) {
|
|
|
|
// Package the form data into an object
|
|
|
|
// Package the form data, including the hCaptcha token
|
|
|
|
const formData = {
|
|
|
|
const formData = {
|
|
|
|
firstName: firstName,
|
|
|
|
firstName: firstName,
|
|
|
|
lastName: lastName,
|
|
|
|
lastName: lastName,
|
|
|
@ -98,38 +127,37 @@ form.addEventListener("submit", function(event) {
|
|
|
|
contactMethod: contactMethod,
|
|
|
|
contactMethod: contactMethod,
|
|
|
|
message: message,
|
|
|
|
message: message,
|
|
|
|
url: honeypotField,
|
|
|
|
url: honeypotField,
|
|
|
|
|
|
|
|
hCaptchaResponse: hCaptchaResponse // <-- THIS IS THE NEW PART
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Send the data to the backend using fetch()
|
|
|
|
// Send the data to the backend using fetch()
|
|
|
|
fetch('/api/submit-form', {
|
|
|
|
fetch('/submit-form', {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
body: JSON.stringify(formData), // Convert the data object to a JSON string
|
|
|
|
body: JSON.stringify(formData),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(response => {
|
|
|
|
.then(response => {
|
|
|
|
if (response.ok) {
|
|
|
|
if (response.ok) {
|
|
|
|
return response.json(); // Parse the JSON response
|
|
|
|
return response.json();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw new Error('Network response was not ok.');
|
|
|
|
throw new Error('Network response was not ok.');
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(data => {
|
|
|
|
.then(data => {
|
|
|
|
// Success: handle the server's response
|
|
|
|
|
|
|
|
console.log('Success:', data);
|
|
|
|
console.log('Success:', data);
|
|
|
|
alert('Form submitted successfully!');
|
|
|
|
showMessage('Form submitted successfully!', false);
|
|
|
|
form.reset(); // Optionally, reset the form after successful submission
|
|
|
|
form.reset();
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
.catch((error) => {
|
|
|
|
// Error: handle any network or server errors
|
|
|
|
|
|
|
|
console.error('Error:', error);
|
|
|
|
console.error('Error:', error);
|
|
|
|
alert('An error occurred during submission. Please try again.');
|
|
|
|
showMessage('An error occurred during submission. Please try again.', true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
form.addEventListener("reset", function (event) {
|
|
|
|
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) {
|
|
|
|
if (!confirmed) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.preventDefault();
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|