Formular mit Validierung
Ein responsives Kontaktformular mit clientseitiger Validierung und Feedback.
Demo
Code
HTML
CSS
JavaScript
<div class="form-container">
<form class="form" id="contact-form">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" placeholder="Ihr Name">
<div class="form-feedback"></div>
</div>
<div class="form-group">
<label for="email">E-Mail</label>
<input type="email" id="email" class="form-control" placeholder="ihre.email@beispiel.de">
<div class="form-feedback"></div>
</div>
<div class="form-group">
<label for="message">Nachricht</label>
<textarea id="message" class="form-control" rows="5" placeholder="Ihre Nachricht"></textarea>
<div class="form-feedback"></div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Senden</button>
</div>
</form>
</div>
.form-container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.form {
display: flex;
flex-direction: column;
gap: 20px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
label {
font-weight: 500;
color: #333;
}
.form-control {
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
transition: border-color 0.3s, box-shadow 0.3s;
}
.form-control:focus {
border-color: #4a6cf7;
box-shadow: 0 0 0 3px rgba(74, 108, 247, 0.2);
outline: none;
}
.form-control.is-invalid {
border-color: #dc3545;
}
.form-control.is-valid {
border-color: #28a745;
}
.form-feedback {
font-size: 0.85rem;
min-height: 20px;
}
.invalid-feedback {
color: #dc3545;
}
.valid-feedback {
color: #28a745;
}
textarea.form-control {
resize: vertical;
min-height: 100px;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 4px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
}
.btn:hover {
transform: translateY(-2px);
}
.btn:active {
transform: translateY(0);
}
.btn-primary {
background-color: #4a6cf7;
color: white;
}
.btn-primary:hover {
background-color: #3a5ce4;
}
.form-success-message {
padding: 15px;
border-radius: 4px;
background-color: #d4edda;
color: #155724;
margin-bottom: 20px;
display: none;
}
@media (max-width: 768px) {
.form-container {
padding: 15px;
}
.form-control, .btn {
padding: 10px;
}
}
class FormValidator {
constructor(formId, options = {}) {
this.form = document.getElementById(formId);
if (!this.form) return;
this.options = {
errorClass: options.errorClass || 'is-invalid',
validClass: options.validClass || 'is-valid',
errorFeedbackClass: options.errorFeedbackClass || 'invalid-feedback',
validFeedbackClass: options.validFeedbackClass || 'valid-feedback',
submitHandler: options.submitHandler || this.defaultSubmitHandler.bind(this)
};
this.validators = {
required: (value) => value.trim() !== '' ? true : 'Dieses Feld ist erforderlich',
email: (value) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(value) ? true : 'Bitte geben Sie eine gültige E-Mail-Adresse ein';
},
minLength: (value, length) => value.length >= length ? true : `Mindestens ${length} Zeichen erforderlich`
};
this.init();
}
init() {
this.form.addEventListener('submit', this.handleSubmit.bind(this));
// Optional: Live-Validierung bei Eingabe oder Änderung
this.form.querySelectorAll('.form-control').forEach(input => {
input.addEventListener('blur', () => this.validateField(input));
input.addEventListener('input', () => {
if (input.classList.contains(this.options.errorClass)) {
this.validateField(input);
}
});
});
}
handleSubmit(event) {
event.preventDefault();
let isValid = true;
// Alle Felder validieren
this.form.querySelectorAll('.form-control').forEach(input => {
if (!this.validateField(input)) {
isValid = false;
}
});
if (isValid) {
this.options.submitHandler(this.form);
}
}
validateField(field) {
// Validierungsregeln aus data-Attributen lesen
const rules = this.getValidationRules(field);
let isValid = true;
let errorMessage = '';
// Regeln überprüfen
for (const rule in rules) {
if (Object.prototype.hasOwnProperty.call(this.validators, rule)) {
const result = this.validators[rule](field.value, rules[rule]);
if (result !== true) {
isValid = false;
errorMessage = result;
break;
}
}
}
// Feedback anzeigen
this.showFeedback(field, isValid, errorMessage);
return isValid;
}
getValidationRules(field) {
const rules = {};
// Validierungsregeln basierend auf Feldtyp und ID
if (field.id === 'name') {
rules.required = true;
rules.minLength = 2;
} else if (field.id === 'email') {
rules.required = true;
rules.email = true;
} else if (field.id === 'message') {
rules.required = true;
rules.minLength = 10;
}
return rules;
}
showFeedback(field, isValid, message = '') {
const feedbackElement = field.nextElementSibling;
if (!feedbackElement || !feedbackElement.classList.contains('form-feedback')) return;
// CSS-Klassen und Feedback-Text aktualisieren
field.classList.remove(this.options.errorClass, this.options.validClass);
feedbackElement.classList.remove(this.options.errorFeedbackClass, this.options.validFeedbackClass);
if (field.value) { // Nur Feedback anzeigen, wenn ein Wert eingegeben wurde
if (isValid) {
field.classList.add(this.options.validClass);
feedbackElement.classList.add(this.options.validFeedbackClass);
feedbackElement.textContent = '';
} else {
field.classList.add(this.options.errorClass);
feedbackElement.classList.add(this.options.errorFeedbackClass);
feedbackElement.textContent = message;
}
} else {
feedbackElement.textContent = '';
}
}
defaultSubmitHandler(form) {
// Formular-Daten sammeln
const formData = new FormData(form);
const data = {};
for (const [key, value] of formData.entries()) {
data[key] = value;
}
// Hier würde normalerweise ein AJAX-Request stehen
console.log('Formular erfolgreich abgesendet', data);
// Erfolgsmeldung anzeigen
let successMessage = document.querySelector('.form-success-message');
if (!successMessage) {
successMessage = document.createElement('div');
successMessage.className = 'form-success-message';
successMessage.textContent = 'Vielen Dank für Ihre Nachricht! Wir werden uns so schnell wie möglich bei Ihnen melden.';
form.parentNode.insertBefore(successMessage, form);
}
successMessage.style.display = 'block';
form.reset();
// Validierungsmarkierungen zurücksetzen
form.querySelectorAll('.form-control').forEach(input => {
input.classList.remove(this.options.errorClass, this.options.validClass);
const feedbackElement = input.nextElementSibling;
if (feedbackElement && feedbackElement.classList.contains('form-feedback')) {
feedbackElement.textContent = '';
feedbackElement.classList.remove(this.options.errorFeedbackClass, this.options.validFeedbackClass);
}
});
}
}
document.addEventListener('DOMContentLoaded', function() {
const contactFormValidator = new FormValidator('contact-form');
});
Erklärung
Dieses Formular mit clientseitiger Validierung bietet eine hervorragende Benutzererfahrung durch sofortiges Feedback ohne Seitenneuladen:
- Umfassende Validierungsregeln für verschiedene Feldtypen (Text, E-Mail, etc.)
- Farbliche Hervorhebung der Felder (rot für ungültige, grün für gültige Eingaben)
- Spezifische Fehlermeldungen für unterschiedliche Validierungsfehler
- Live-Validierung während der Eingabe für sofortiges Feedback
- Einfache Anpassbarkeit und Erweiterbarkeit durch die Klassenstruktur
Die JavaScript-Klasse FormValidator
bietet eine modulare Lösung, die leicht auf verschiedene Formulare angewendet werden kann. Die Validierungslogik ist von der UI-Logik getrennt, was die Wartbarkeit erhöht.
Verwendung
Dieses validierte Formular eignet sich perfekt für Kontaktformulare, Anmeldeformulare, Bestellformulare oder Umfragen. Die clientseitige Validierung verbessert die Benutzererfahrung, indem sie sofortiges Feedback gibt, und reduziert ungültige Formulareinsendungen.