From c9a6748a8af1276716433974a98749da13bf949e Mon Sep 17 00:00:00 2001 From: Andreas Hnida Date: Fri, 19 Apr 2024 00:10:40 +0200 Subject: [PATCH] add custom validation messages and bot prevention logic --- assets/js/bestellformular.js | 226 +++++++++++++++++++---------------- 1 file changed, 122 insertions(+), 104 deletions(-) diff --git a/assets/js/bestellformular.js b/assets/js/bestellformular.js index 49b16ab..09e1879 100644 --- a/assets/js/bestellformular.js +++ b/assets/js/bestellformular.js @@ -1,64 +1,82 @@ -document.addEventListener("DOMContentLoaded", function() { - console.log('bestellformular.js loaded'); - // Rest of the code goes here - const FORMDEBUG = false; - const btn = document.getElementById('bestellformular-btn'); - const bestellformular = document.getElementById('bestellformular'); - // initieiere Zeitmessung zur Botprevention - var startTime = Date.now(); +document.addEventListener('DOMContentLoaded', function () { + console.log('bestellformular.js loaded') + // Rest of the code goes here + const FORMDEBUG = false + const btn = document.getElementById('bestellformular-btn') + const bestellformular = document.getElementById('bestellformular') - // Messe ob mit der Seite agiert wird - var userInteracted = false; + // custom Validation messages + 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() { - var timeSpent = (Date.now() - startTime) / 1000; // Zeit in Sekunden - if (timeSpent > 5) { - btn.disabled = false; - } - userInteracted = true; + // Messe ob mit der Seite agiert wird + var userInteracted = false + + function setUserInteracted() { + var timeSpent = (Date.now() - startTime) / 1000 // Zeit in Sekunden + if (timeSpent > 5) { + btn.disabled = false } - setTimeout(function () { - if (userInteracted) { - btn.disabled = false; - } - }, 5000); - // Eventlistener für Interaktionen - setzt userInteracted auf true bei Interaktion - document.addEventListener("mousedown", setUserInteracted); - document.addEventListener("touchstart", setUserInteracted); - document.addEventListener("keydown", setUserInteracted); + userInteracted = true + } + setTimeout(function () { + if (userInteracted) { + btn.disabled = false + } + }, 5000) + // Eventlistener für Interaktionen - setzt userInteracted auf true bei Interaktion + document.addEventListener('mousedown', setUserInteracted) + document.addEventListener('touchstart', setUserInteracted) + document.addEventListener('keydown', setUserInteracted) - bestellformular.addEventListener('submit', function (e) { - - e.preventDefault(); + bestellformular.addEventListener('submit', function (e) { + e.preventDefault() - const form = e.target; - const notification = document.getElementById('notification'); - const zsrTooltip = document.getElementById('zsr-tooltip'); - - // Spinner und button disabled anzeigen - - - - 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; - document.getElementById("hobbies").value = userInteracted ? "true" : "false"; - - // Validierung der ZSR-Nummer - const zsrNummer = form.elements['zsr_nummer'].value; - const isNumberOrBeantragt = /^\d+$|^beantragt$/i.test(zsrNummer); - // TODO REGEX für ZSR-Nummer - if (!isNumberOrBeantragt) { - // Display error message for invalid zsr_nummer - zsrTooltip.className = 'input-tooltip'; - // Scroll to the tooltip element - zsrTooltip.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }); - return; - } - - btn.innerHTML = ` + const form = e.target + const notification = document.getElementById('notification') + const zsrTooltip = document.getElementById('zsr-tooltip') + + // Spinner und button disabled anzeigen + + 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 + document.getElementById('hobbies').value = userInteracted ? 'true' : 'false' + + // Validierung der ZSR-Nummer + const zsrNummer = form.elements['zsr_nummer'].value + const isNumberOrBeantragt = /^\d+$|^beantragt$/i.test(zsrNummer) + // TODO REGEX für ZSR-Nummer + if (!isNumberOrBeantragt) { + // Display error message for invalid zsr_nummer + zsrTooltip.className = 'input-tooltip' + // Scroll to the tooltip element + zsrTooltip.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'}) + return + } + + btn.innerHTML = ` - ` + ` - btn.disabled = true; - - if (FORMDEBUG) { - console.log("userInteracted: " + userInteracted); - console.log("timeSpent: " + timeSpent); - console.log("hobbies: " + document.getElementById("hobbies").value); - console.log("age: " + document.getElementById("age").value); - console.log("verify_email(honeypot): " + document.getElementById("verify_email").value); + btn.disabled = true + + if (FORMDEBUG) { + console.log('userInteracted: ' + userInteracted) + console.log('timeSpent: ' + timeSpent) + console.log('hobbies: ' + document.getElementById('hobbies').value) + console.log('age: ' + document.getElementById('age').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') } - - // 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(); - }) - .then(data => { - // Erfolgsnachricht anzeigen - // TODO Nachricht anpassen wenn französische Version - notification.textContent = 'Bestellformular erfolgreich gesendet!'; - btn.className = 'submitbutton text-white mx-auto submit-after-valid-captchaaaa fadeOut'; - setTimeout(() => { - btn.style.visibility = 'hidden'; - btn.style.display = 'none'; - notification.style.visibility = 'visible'; - notification.style.display = 'block'; - 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 - }); - }); -}) \ No newline at end of file + return response.json() + }) + .then(data => { + // Erfolgsnachricht anzeigen + // TODO Nachricht anpassen wenn französische Version + notification.textContent = 'Bestellformular erfolgreich gesendet!' + btn.className = 'submitbutton text-white mx-auto submit-after-valid-captchaaaa fadeOut' + setTimeout(() => { + btn.style.visibility = 'hidden' + btn.style.display = 'none' + notification.style.visibility = 'visible' + notification.style.display = 'block' + 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 + }) + }) +})