purinto-website/assets/js/kontakt.js
Denise Krölling 1a63f66463 Website der Purinto GmbH aufsetzen
Statische Website ohne Build-Schritt: reines HTML, CSS und Vanilla-JS,
lauffaehig auf beliebigem Webspace.

Neun Seiten: Startseite, Dienstleistungen, Projekte, Ueber uns, Kontakt
sowie Impressum, Datenschutz, Danke-Seite und 404.

Kernstueck der Startseite ist die Stueckzahl-Achse: ein logarithmischer
Regler von 1 bis 100.000 Stueck, der zur gewaehlten Menge Verfahren,
Werkzeugkosten, Lieferzeit und Anwendungsfall ausgibt. Die dritte Zone
ist optisch zurueckgenommen, weil Serienspritzguss ueber Partnerbetriebe
laeuft und nicht zum eigenen Leistungsumfang gehoert. Der Leistungsumfang
ist durchgehend auf FDM, SLA und SLA-gedruckte Formeinsaetze beschraenkt.

Gestaltung nach Vorgabe: Anthrazit, Salbeigruen und Flieder als Akzent.
Archivo, Public Sans und IBM Plex Mono werden lokal ausgeliefert statt
ueber die Google-CDN eingebunden.

Kontaktformular ueber Web3Forms mit Client-Validierung; der Access-Key
ist noch ein Platzhalter. Alle Firmen- und Projektinhalte sind sichtbar
als Platzhalter markiert, die Uebergabe-Checkliste steht in der README.

Geprueft: WCAG-AA-Kontraste auf allen Seiten, kein horizontaler Ueberlauf
von 320 bis 1920 px, Tastaturbedienung der Achse, feste Zeilenzahl der
Hero-Headline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 13:07:08 +02:00

204 lines
6.2 KiB
JavaScript

/* ==========================================================================
Purinto GmbH — Kontaktformular
Validierung mit konkreten Fehlermeldungen und Versand über Web3Forms.
Ohne JavaScript funktioniert das Formular ebenfalls: Es postet dann direkt
an Web3Forms und landet auf danke.html. Diese Datei verbessert das nur um
Inline-Prüfung und eine Rückmeldung ohne Seitenwechsel.
========================================================================== */
(function () {
"use strict";
var formular = document.querySelector("[data-formular]");
if (!formular) return;
var meldungErfolg = document.querySelector("[data-meldung-erfolg]");
var meldungFehler = document.querySelector("[data-meldung-fehler]");
var meldungFehlerText = document.querySelector("[data-meldung-fehler-text]");
var absendeKnopf = formular.querySelector("[data-absenden]");
var PLATZHALTER_KEY = "DEIN-WEB3FORMS-ACCESS-KEY";
/* ----------------------------------------------------------------------
Prüfregeln. Die Meldungen sagen, was zu tun ist — nicht, was falsch war.
---------------------------------------------------------------------- */
var REGELN = {
name: function (feld) {
if (!feld.value.trim()) {
return "Bitte geben Sie Ihren Namen an, damit wir Sie ansprechen können.";
}
return null;
},
email: function (feld) {
var wert = feld.value.trim();
if (!wert) {
return "Bitte geben Sie eine E-Mail-Adresse an, an die wir antworten können.";
}
// Bewusst großzügig: Die endgültige Prüfung macht der Mailserver.
if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(wert)) {
return "Diese Adresse scheint unvollständig zu sein. Bitte prüfen Sie sie noch einmal.";
}
return null;
},
nachricht: function (feld) {
var wert = feld.value.trim();
if (!wert) {
return "Beschreiben Sie kurz Ihr Bauteil oder Ihre Frage — zwei Sätze genügen.";
}
if (wert.length < 10) {
return "Ein paar Worte mehr helfen uns, die Anfrage richtig einzuschätzen.";
}
return null;
},
datenschutz: function (feld) {
if (!feld.checked) {
return "Ohne diese Zustimmung dürfen wir Ihre Anfrage nicht verarbeiten.";
}
return null;
}
};
function fehlerElement(feld) {
return document.querySelector('[data-fehler-fuer="' + feld.name + '"]');
}
function fehlerZeigen(feld, text) {
var el = fehlerElement(feld);
feld.setAttribute("aria-invalid", "true");
if (el) {
el.textContent = text;
el.classList.add("ist-sichtbar");
}
}
function fehlerLoeschen(feld) {
var el = fehlerElement(feld);
feld.removeAttribute("aria-invalid");
if (el) {
el.textContent = "";
el.classList.remove("ist-sichtbar");
}
}
function feldPruefen(feld) {
var regel = REGELN[feld.name];
if (!regel) return true;
var fehler = regel(feld);
if (fehler) {
fehlerZeigen(feld, fehler);
return false;
}
fehlerLoeschen(feld);
return true;
}
// Nach dem ersten Fehlversuch direkt beim Verlassen des Feldes prüfen,
// vorher nicht — sonst meckert das Formular beim ersten Tippen.
var schonAbgeschickt = false;
Object.keys(REGELN).forEach(function (name) {
var feld = formular.elements[name];
if (!feld) return;
feld.addEventListener("blur", function () {
if (schonAbgeschickt) feldPruefen(feld);
});
feld.addEventListener("input", function () {
if (schonAbgeschickt && feld.getAttribute("aria-invalid") === "true") {
feldPruefen(feld);
}
});
feld.addEventListener("change", function () {
if (schonAbgeschickt) feldPruefen(feld);
});
});
/* ----------------------------------------------------------------------
Absenden
---------------------------------------------------------------------- */
function meldungenAusblenden() {
if (meldungErfolg) meldungErfolg.classList.remove("ist-sichtbar");
if (meldungFehler) meldungFehler.classList.remove("ist-sichtbar");
}
function fehlerMelden(text) {
if (!meldungFehler) return;
if (meldungFehlerText) meldungFehlerText.textContent = text;
meldungFehler.classList.add("ist-sichtbar");
meldungFehler.scrollIntoView({ block: "nearest" });
}
formular.addEventListener("submit", function (e) {
e.preventDefault();
schonAbgeschickt = true;
meldungenAusblenden();
// Alle Regeln prüfen, damit der Besucher alle Fehler auf einmal sieht.
var ersterFehler = null;
Object.keys(REGELN).forEach(function (name) {
var feld = formular.elements[name];
if (!feld) return;
if (!feldPruefen(feld) && !ersterFehler) ersterFehler = feld;
});
if (ersterFehler) {
ersterFehler.focus();
return;
}
var key = formular.elements["access_key"];
if (key && key.value === PLATZHALTER_KEY) {
fehlerMelden(
"Das Formular ist noch nicht mit einem Web3Forms-Zugangsschlüssel verbunden. " +
"Bis dahin erreichen Sie uns direkt per E-Mail."
);
return;
}
absendeKnopf.disabled = true;
var beschriftung = absendeKnopf.textContent;
absendeKnopf.textContent = "Wird gesendet …";
fetch(formular.action, {
method: "POST",
body: new FormData(formular)
})
.then(function (antwort) {
return antwort.json().catch(function () {
return { success: antwort.ok };
});
})
.then(function (ergebnis) {
if (!ergebnis.success) {
throw new Error(ergebnis.message || "Unbekannter Fehler");
}
formular.reset();
if (meldungErfolg) {
meldungErfolg.classList.add("ist-sichtbar");
meldungErfolg.setAttribute("tabindex", "-1");
meldungErfolg.focus();
}
})
.catch(function () {
fehlerMelden(
"Die Anfrage konnte nicht gesendet werden. Bitte versuchen Sie es " +
"noch einmal oder schreiben Sie uns direkt eine E-Mail."
);
})
.then(function () {
absendeKnopf.disabled = false;
absendeKnopf.textContent = beschriftung;
});
});
})();