add custom validation messages and bot prevention logic
All checks were successful
Build and Deploy Hugo Site / buildAndDeploy (push) Successful in 50s

This commit is contained in:
Andreas Hnida 2024-04-19 00:10:40 +02:00
commit c9a6748a8a

View file

@ -1,64 +1,82 @@
document.addEventListener("DOMContentLoaded", function() { document.addEventListener('DOMContentLoaded', function () {
console.log('bestellformular.js loaded'); console.log('bestellformular.js loaded')
// Rest of the code goes here // Rest of the code goes here
const FORMDEBUG = false; const FORMDEBUG = false
const btn = document.getElementById('bestellformular-btn'); const btn = document.getElementById('bestellformular-btn')
const bestellformular = document.getElementById('bestellformular'); const bestellformular = document.getElementById('bestellformular')
// initieiere Zeitmessung zur Botprevention
var startTime = Date.now();
// Messe ob mit der Seite agiert wird // custom Validation messages
var userInteracted = false; const messagesGerman = {
required: 'Bitte füllen Sie dieses Feld aus',
email: 'Bitte geben Sie eine gültige E-Mail-Adresse ein',
minlength: 'Bitte geben Sie mindestens {0} Zeichen ein',
maxlength: 'Bitte geben Sie maximal {0} Zeichen ein',
min: 'Bitte geben Sie mindestens {0} ein',
max: 'Bitte geben Sie maximal {0} ein',
range: 'Bitte geben Sie zwischen {0} und {1} ein',
}
const messagesFrench = {
required: 'Veuillez remplir ce champ',
email: 'Veuillez saisir une adresse email valide',
minlength: 'Veuillez saisir au moins {0} caractères',
maxlength: 'Veuillez saisir au plus {0} caractères',
min: 'Veuillez saisir au moins {0} caractères',
max: 'Veuillez saisir au plus {0} caractères',
range: 'Veuillez saisir au moins {0} et au plus {1} caractères',
}
// initieiere Zeitmessung zur Botprevention
var startTime = Date.now()
function setUserInteracted() { // Messe ob mit der Seite agiert wird
var timeSpent = (Date.now() - startTime) / 1000; // Zeit in Sekunden var userInteracted = false
if (timeSpent > 5) {
btn.disabled = false; function setUserInteracted() {
} var timeSpent = (Date.now() - startTime) / 1000 // Zeit in Sekunden
userInteracted = true; if (timeSpent > 5) {
btn.disabled = false
} }
setTimeout(function () { userInteracted = true
if (userInteracted) { }
btn.disabled = false; setTimeout(function () {
} if (userInteracted) {
}, 5000); btn.disabled = false
// Eventlistener für Interaktionen - setzt userInteracted auf true bei Interaktion }
document.addEventListener("mousedown", setUserInteracted); }, 5000)
document.addEventListener("touchstart", setUserInteracted); // Eventlistener für Interaktionen - setzt userInteracted auf true bei Interaktion
document.addEventListener("keydown", setUserInteracted); document.addEventListener('mousedown', setUserInteracted)
document.addEventListener('touchstart', setUserInteracted)
document.addEventListener('keydown', setUserInteracted)
bestellformular.addEventListener('submit', function (e) { bestellformular.addEventListener('submit', function (e) {
e.preventDefault()
e.preventDefault();
const form = e.target; const form = e.target
const notification = document.getElementById('notification'); const notification = document.getElementById('notification')
const zsrTooltip = document.getElementById('zsr-tooltip'); const zsrTooltip = document.getElementById('zsr-tooltip')
// Spinner und button disabled anzeigen // Spinner und button disabled anzeigen
var endTime = Date.now()
var timeSpent = (endTime - startTime) / 1000 // Zeit in Sekunden
var endTime = Date.now();
var timeSpent = (endTime - startTime) / 1000; // Zeit in Sekunden // Setze die Werte für die Botvalidierung zum Auswerten in PHP
document.getElementById('age').value = timeSpent
// Setze die Werte für die Botvalidierung zum Auswerten in PHP document.getElementById('hobbies').value = userInteracted ? 'true' : 'false'
document.getElementById("age").value = timeSpent;
document.getElementById("hobbies").value = userInteracted ? "true" : "false"; // Validierung der ZSR-Nummer
const zsrNummer = form.elements['zsr_nummer'].value
// Validierung der ZSR-Nummer const isNumberOrBeantragt = /^\d+$|^beantragt$/i.test(zsrNummer)
const zsrNummer = form.elements['zsr_nummer'].value; // TODO REGEX für ZSR-Nummer
const isNumberOrBeantragt = /^\d+$|^beantragt$/i.test(zsrNummer); if (!isNumberOrBeantragt) {
// TODO REGEX für ZSR-Nummer // Display error message for invalid zsr_nummer
if (!isNumberOrBeantragt) { zsrTooltip.className = 'input-tooltip'
// Display error message for invalid zsr_nummer // Scroll to the tooltip element
zsrTooltip.className = 'input-tooltip'; zsrTooltip.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'})
// Scroll to the tooltip element return
zsrTooltip.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }); }
return;
} btn.innerHTML = `
btn.innerHTML = `
<svg class="text-gray-300 animate-spin mx-auto" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg" <svg class="text-gray-300 animate-spin mx-auto" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg"
width="24" height="24"> width="24" height="24">
<path <path
@ -69,53 +87,53 @@ document.addEventListener("DOMContentLoaded", function() {
stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" class="text-gray-900"> stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" class="text-gray-900">
</path> </path>
</svg> </svg>
` `
btn.disabled = true; btn.disabled = true
if (FORMDEBUG) { if (FORMDEBUG) {
console.log("userInteracted: " + userInteracted); console.log('userInteracted: ' + userInteracted)
console.log("timeSpent: " + timeSpent); console.log('timeSpent: ' + timeSpent)
console.log("hobbies: " + document.getElementById("hobbies").value); console.log('hobbies: ' + document.getElementById('hobbies').value)
console.log("age: " + document.getElementById("age").value); console.log('age: ' + document.getElementById('age').value)
console.log("verify_email(honeypot): " + document.getElementById("verify_email").value); console.log('verify_email(honeypot): ' + document.getElementById('verify_email').value)
}
// Formulardaten an den Server senden
const data = new FormData(form)
fetch(form.action, {
method: 'POST',
mode: 'cors',
body: data,
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok')
} }
return response.json()
// Formulardaten an den Server senden })
const data = new FormData(form); .then(data => {
fetch(form.action, { // Erfolgsnachricht anzeigen
method: 'POST', // TODO Nachricht anpassen wenn französische Version
mode: 'cors', notification.textContent = 'Bestellformular erfolgreich gesendet!'
body: data, btn.className = 'submitbutton text-white mx-auto submit-after-valid-captchaaaa fadeOut'
}) setTimeout(() => {
.then(response => { btn.style.visibility = 'hidden'
if (!response.ok) { btn.style.display = 'none'
throw new Error('Network response was not ok'); notification.style.visibility = 'visible'
} notification.style.display = 'block'
return response.json(); notification.classList.remove('fadeIn') // Remove fadeIn class
}) void notification.offsetWidth
.then(data => { notification.className = 'bg-green-500 text-white px-4 py-2 rounded block fadeIn'
// Erfolgsnachricht anzeigen }, 1000)
// TODO Nachricht anpassen wenn französische Version // setTimeout(() => notification.className = 'bg-green-500 text-white px-4 py-2 rounded hidden', 5000); // Benachrichtigung nach 5 Sekunden ausblenden
notification.textContent = 'Bestellformular erfolgreich gesendet!'; })
btn.className = 'submitbutton text-white mx-auto submit-after-valid-captchaaaa fadeOut'; .catch(error => {
setTimeout(() => { // Fehlermeldung anzeigen
btn.style.visibility = 'hidden'; notification.textContent = 'Fehler beim Senden der Nachricht.'
btn.style.display = 'none'; console.log(error)
notification.style.visibility = 'visible'; notification.className = 'bg-red-500 text-white px-4 py-2 rounded block'
notification.style.display = 'block'; // setTimeout(() => notification.className = 'bg-red-500 text-white px-4 py-2 rounded hidden', 5000); // Benachrichtigung nach 5 Sekunden ausblenden
notification.classList.remove('fadeIn'); // Remove fadeIn class })
void notification.offsetWidth; })
notification.className = 'bg-green-500 text-white px-4 py-2 rounded block fadeIn'; })
}, 1000);
// setTimeout(() => notification.className = 'bg-green-500 text-white px-4 py-2 rounded hidden', 5000); // Benachrichtigung nach 5 Sekunden ausblenden
})
.catch((error) => {
// Fehlermeldung anzeigen
notification.textContent = 'Fehler beim Senden der Nachricht.';
console.log(error);
notification.className = 'bg-red-500 text-white px-4 py-2 rounded block';
// setTimeout(() => notification.className = 'bg-red-500 text-white px-4 py-2 rounded hidden', 5000); // Benachrichtigung nach 5 Sekunden ausblenden
});
});
})