Compare commits
No commits in common. "13e64304d4790a4bc9eeca97050138fd50611996" and "2cd537a54712eeb2738cb33b5a33f682cf4ebab6" have entirely different histories.
13e64304d4
...
2cd537a547
|
@ -117,8 +117,6 @@ pageScripts:
|
||||||
<button type="reset">Reset Form</button>
|
<button type="reset">Reset Form</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-captcha" data-sitekey="b63e5b64-c6f2-4154-b5a6-77169a924022E"></div>
|
|
||||||
|
|
||||||
<div class="honeypot-field" aria-hidden="true">
|
<div class="honeypot-field" aria-hidden="true">
|
||||||
<label for="url">Website URL</label>
|
<label for="url">Website URL</label>
|
||||||
<input type="text" name="url" id="url" autocomplete="off" tabindex="-1">
|
<input type="text" name="url" id="url" autocomplete="off" tabindex="-1">
|
||||||
|
|
|
@ -3,30 +3,6 @@
|
||||||
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) {
|
||||||
|
@ -36,12 +12,10 @@ function showError(inputId, message) {
|
||||||
if (errorSpan) errorSpan.textContent = message;
|
if (errorSpan) errorSpan.textContent = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility: Clear all errors and messages
|
// Utility: Clear all errors
|
||||||
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) {
|
||||||
|
@ -50,13 +24,15 @@ 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.");
|
||||||
// Fail silently to avoid alerting the bot.
|
// You might want to display a message to the user,
|
||||||
return;
|
// but it's often better to fail silently to not alert the bot.
|
||||||
|
return; // This is the most important part: stop the function here.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get values, including the hCaptcha response token
|
// Get values
|
||||||
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();
|
||||||
|
@ -64,12 +40,10 @@ 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;
|
||||||
|
|
||||||
// Validation logic...
|
// First Name
|
||||||
if (!firstName) {
|
if (!firstName) {
|
||||||
showError("first-name", "Please enter your first name.");
|
showError("first-name", "Please enter your first name.");
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
|
@ -78,6 +52,7 @@ 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;
|
||||||
|
@ -85,82 +60,79 @@ form.addEventListener("submit", function(event) {
|
||||||
showError("last-name", "Last name must be at least 2 characters.");
|
showError("last-name", "Last name must be at least 2 characters.");
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Organization (optional)
|
// Organization (optional)
|
||||||
if (organization.length > 0 && organization.length < 2) {
|
if (organization.length > 0 && organization.length < 2) {
|
||||||
showError("organization", "Organization name must be at least 2 characters.");
|
showError("organization", "Organization name must be at least 2 characters.");
|
||||||
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, including the hCaptcha token
|
// Package the form data into an object
|
||||||
const formData = {
|
const formData = {
|
||||||
firstName: firstName,
|
firstName: firstName,
|
||||||
lastName: lastName,
|
lastName: lastName,
|
||||||
organization: organization,
|
organization: organization,
|
||||||
email: email,
|
email: email,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
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('/submit-form', {
|
fetch('/api/submit-form', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(formData),
|
body: JSON.stringify(formData), // Convert the data object to a JSON string
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.json();
|
return response.json(); // Parse the JSON response
|
||||||
}
|
}
|
||||||
throw new Error('Network response was not ok.');
|
throw new Error('Network response was not ok.');
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('Success:', data);
|
// Success: handle the server's response
|
||||||
showMessage('Form submitted successfully!', false);
|
console.log('Success:', data);
|
||||||
form.reset();
|
alert('Form submitted successfully!');
|
||||||
})
|
form.reset(); // Optionally, reset the form after successful submission
|
||||||
.catch((error) => {
|
})
|
||||||
console.error('Error:', error);
|
.catch((error) => {
|
||||||
showMessage('An error occurred during submission. Please try again.', true);
|
// Error: handle any network or server errors
|
||||||
});
|
console.error('Error:', error);
|
||||||
}
|
alert('An error occurred during submission. Please try again.');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
form.addEventListener("reset", function (event) {
|
form.addEventListener("reset", function (event) {
|
||||||
const confirmed = window.confirm("Are you sure you want to clear the form?");
|
const confirmed = confirm("Are you sure you want to clear the form?");
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearErrors();
|
clearErrors();
|
||||||
});
|
});
|
Loading…
Reference in New Issue