Files
tsv08kulmbach-website/public/assets/js/form.js
2026-06-11 21:55:47 +02:00

95 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Formulare: Progressive Enhancement — ohne JS normales POST + Redirect.
Mit JS: Inline-Feldfehler (aria-describedby, Fokus aufs erste ungültige Feld),
fetch-Submit, Status in aria-live-Region, Button-Sperre während des Sendens. */
(function () {
'use strict';
var form = document.querySelector('.form');
if (!form || !window.fetch) {
return;
}
var status = form.querySelector('[data-form-status]');
var button = form.querySelector('button[type="submit"]');
var MESSAGES = {
success: 'Danke für deine Anfrage! Wir melden uns so schnell wie möglich bei dir.',
validation: 'Bitte prüfe deine Eingaben Pflichtfelder fehlen oder die E-Mail-Adresse ist ungültig.',
mail: 'Deine Nachricht konnte gerade nicht versendet werden. Bitte versuche es später erneut.'
};
function errorEl(field) {
return field.id ? document.getElementById(field.id + '-error') : null;
}
function showFieldError(field) {
var msg = errorEl(field);
field.setAttribute('aria-invalid', 'true');
if (msg) {
msg.textContent = field.validationMessage;
msg.hidden = false;
}
}
function clearFieldError(field) {
var msg = errorEl(field);
field.removeAttribute('aria-invalid');
if (msg) {
msg.textContent = '';
msg.hidden = true;
}
}
Array.prototype.forEach.call(form.elements, function (field) {
field.addEventListener('input', function () { clearFieldError(field); });
field.addEventListener('change', function () { clearFieldError(field); });
});
function show(type, text) {
var p = document.createElement('p');
p.className = type === 'success' ? 'form__success' : 'form__error';
p.textContent = text;
status.replaceChildren(p);
status.focus({ preventScroll: true });
status.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault();
var invalid = form.querySelectorAll(':invalid');
Array.prototype.forEach.call(invalid, showFieldError);
if (invalid.length) {
invalid[0].focus();
}
return;
}
event.preventDefault();
button.disabled = true;
button.textContent = 'Wird gesendet …';
fetch(form.action, {
method: 'POST',
body: new FormData(form),
headers: { Accept: 'application/json' }
})
.then(function (response) { return response.json(); })
.then(function (data) {
if (data.ok) {
show('success', MESSAGES.success);
form.reset();
} else {
show('error', MESSAGES[data.error] || MESSAGES.mail);
}
})
.catch(function () {
show('error', MESSAGES.mail);
})
.finally(function () {
button.disabled = false;
button.textContent = 'Nachricht senden';
});
});
})();