Formularverarbeitung mit Vanilla JavaScript: Kein Framework erforderlich

Formulare sind das Rückgrat der Benutzerinteraktion im Web. Während Frameworks wie React und Vue praktische Abstraktionen bieten, verschafft Ihnen das Verständnis für die Formularverarbeitung mit Vanilla JavaScript vollständige Kontrolle und eliminiert unnötige Abhängigkeiten.
Dieser Leitfaden führt Sie durch alles, was Sie über native Formularverarbeitung in JavaScript wissen müssen – von der Elementauswahl und Werteerfassung bis hin zur Eingabevalidierung und Verarbeitung von Übermittlungen.
Wichtige Erkenntnisse
- Vanilla JavaScript bietet alle erforderlichen Werkzeuge für vollständige Formularverarbeitung ohne Frameworks
- Verwenden Sie
event.preventDefault()
, um das Verhalten der Formularübermittlung zu steuern - Nutzen Sie die HTML5-Constraint-Validierung für grundlegende Validierung mit minimalem Code
- Implementieren Sie Echtzeit-Validierung mit den
input
- undblur
-Events für bessere Benutzererfahrung - Die FormData-API vereinfacht das Sammeln und Verarbeiten von Formularwerten
- Berücksichtigen Sie immer die Barrierefreiheit bei der Implementierung benutzerdefinierter Formularvalidierung
Grundlegende Formularverarbeitung mit JavaScript
Beginnen wir mit einem einfachen HTML-Formular:
<form id="signup-form">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email">
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
</div>
<button type="submit">Sign Up</button>
</form>
Auswahl von Formularelementen
Sie können auf ein Formular und seine Elemente auf verschiedene Weise zugreifen:
// Auswahl über ID (empfohlen für spezifische Formulare)
const form = document.getElementById('signup-form');
// Auswahl mit querySelector
const form = document.querySelector('#signup-form');
// Zugriff auf die Formularelemente-Sammlung
const forms = document.forms;
const signupForm = forms['signup-form']; // über id/name
const firstForm = forms[0]; // über Index
Erfassen des Submit-Events
Um die Formularübermittlung zu verarbeiten, fügen Sie einen Event-Listener zum Formular hinzu:
const form = document.getElementById('signup-form');
form.addEventListener('submit', function(event) {
// Verhindert die Standard-Formularübermittlung
event.preventDefault();
// Formulardaten hier verarbeiten
console.log('Formular übermittelt!');
});
Die preventDefault()
-Methode verhindert, dass der Browser das Formular übermittelt und die Seite aktualisiert, wodurch Sie die Kontrolle über das weitere Vorgehen erhalten.
Zugriff auf Formulareingabewerte
Es gibt mehrere Möglichkeiten, auf Formulareingabewerte zuzugreifen:
Methode 1: Zugriff auf einzelne Elemente
form.addEventListener('submit', function(event) {
event.preventDefault();
// Werte von einzelnen Formularelementen abrufen
const username = document.getElementById('username').value;
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
console.log(username, email, password);
});
Methode 2: Verwendung von form.elements
Die elements
-Eigenschaft bietet Zugriff auf alle Formularsteuerelemente:
form.addEventListener('submit', function(event) {
event.preventDefault();
// Zugriff über die elements-Sammlung
const username = form.elements.username.value;
const email = form.elements.email.value;
const password = form.elements.password.value;
console.log(username, email, password);
});
Methode 3: Verwendung der FormData-API
Die FormData
-API bietet eine saubere Möglichkeit, alle Formularwerte zu erfassen:
form.addEventListener('submit', function(event) {
event.preventDefault();
// FormData-Objekt aus dem Formular erstellen
const formData = new FormData(form);
// Zugriff auf einzelne Werte
const username = formData.get('username');
const email = formData.get('email');
// In ein reguläres Objekt konvertieren
const formObject = Object.fromEntries(formData);
console.log(formObject); // {username: '...', email: '...', password: '...'}
});
Formularvalidierung mit HTML5-Constraints
Modernes HTML5 bietet eingebaute Validierungsattribute, die ohne JavaScript funktionieren:
<form id="signup-form">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required minlength="3">
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required minlength="8"
pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).*$">
<small>Das Passwort muss mindestens 8 Zeichen enthalten, einschließlich Groß-, Kleinbuchstaben und Zahlen</small>
</div>
<button type="submit">Sign Up</button>
</form>
Häufige Validierungsattribute umfassen:
required
: Feld muss ausgefüllt werdenminlength
/maxlength
: Minimale/maximale Textlängemin
/max
: Minimal-/Maximalwerte für Zahleneingabenpattern
: Regulärer Ausdruck-Pattern zum Abgleichtype="email"
: Validiert E-Mail-Formattype="url"
: Validiert URL-Format
Nutzung der Constraint Validation API
JavaScript kann auf das eingebaute Validierungssystem des Browsers zugreifen:
form.addEventListener('submit', function(event) {
// Prüft, ob das Formular gültig ist, mit der Constraint Validation API
if (!form.checkValidity()) {
// Formular ist ungültig - lassen Sie den Browser die Fehleranzeige handhaben
return;
}
// Wenn wir hier ankommen, ist das Formular gültig
event.preventDefault();
// Verarbeitung der gültigen Formulardaten
console.log('Formular ist gültig, verarbeite Daten...');
});
Sie können auch die Gültigkeit spezifischer Eingaben prüfen:
const emailInput = document.getElementById('email');
// Prüft, ob die E-Mail gültig ist
if (emailInput.validity.valid) {
console.log('E-Mail ist gültig');
} else {
// Prüft spezifische Validierungsfehler
if (emailInput.validity.typeMismatch) {
console.log('E-Mail-Format ist falsch');
}
if (emailInput.validity.valueMissing) {
console.log('E-Mail ist erforderlich');
}
}
Benutzerdefinierte Validierung und Fehlermeldungen
Während HTML5-Validierung praktisch ist, benötigen Sie oft benutzerdefinierte Validierungslogik und Fehlermeldungen:
form.addEventListener('submit', function(event) {
event.preventDefault();
const username = document.getElementById('username');
const email = document.getElementById('email');
const password = document.getElementById('password');
// Vorherige Fehlermeldungen löschen
clearErrors();
let isValid = true;
// Benutzerdefinierte Benutzernamen-Validierung
if (username.value.trim() === '') {
displayError(username, 'Benutzername ist erforderlich');
isValid = false;
} else if (username.value.length < 3) {
displayError(username, 'Benutzername muss mindestens 3 Zeichen haben');
isValid = false;
}
// Benutzerdefinierte E-Mail-Validierung
if (!isValidEmail(email.value)) {
displayError(email, 'Bitte geben Sie eine gültige E-Mail-Adresse ein');
isValid = false;
}
// Benutzerdefinierte Passwort-Validierung
if (password.value.length < 8) {
displayError(password, 'Passwort muss mindestens 8 Zeichen haben');
isValid = false;
} else if (!/[A-Z]/.test(password.value)) {
displayError(password, 'Passwort muss mindestens einen Großbuchstaben enthalten');
isValid = false;
}
// Wenn gültig, Formular verarbeiten
if (isValid) {
console.log('Formular ist gültig, übermittle...');
// Formulardaten übermitteln
}
});
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function displayError(input, message) {
const formControl = input.parentElement;
const errorElement = document.createElement('div');
errorElement.className = 'error-message';
errorElement.textContent = message;
formControl.appendChild(errorElement);
input.classList.add('error-input');
}
function clearErrors() {
document.querySelectorAll('.error-message').forEach(error => error.remove());
document.querySelectorAll('.error-input').forEach(input => {
input.classList.remove('error-input');
});
}
Echtzeit-Validierung mit Input-Events
Für eine bessere Benutzererfahrung validieren Sie Eingaben während der Eingabe:
const emailInput = document.getElementById('email');
emailInput.addEventListener('input', function() {
if (this.value && !isValidEmail(this.value)) {
this.setCustomValidity('Bitte geben Sie eine gültige E-Mail-Adresse ein');
} else {
this.setCustomValidity('');
}
});
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
Das input
-Event wird ausgelöst, wann immer der Benutzer den Wert ändert, während das change
-Event ausgelöst wird, wenn die Eingabe den Fokus verliert, nachdem sie geändert wurde.
Umgang mit verschiedenen Eingabetypen
Radio-Buttons
<div>
<p>Abonnement-Plan:</p>
<label>
<input type="radio" name="plan" value="free" checked> Kostenlos
</label>
<label>
<input type="radio" name="plan" value="premium"> Premium
</label>
</div>
// Ausgewählten Radio-Button-Wert abrufen
const selectedPlan = document.querySelector('input[name="plan"]:checked').value;
// Auf Änderungen hören
document.querySelectorAll('input[name="plan"]').forEach(radio => {
radio.addEventListener('change', function() {
console.log('Ausgewählter Plan:', this.value);
});
});
Checkboxen
<div>
<p>Interessen:</p>
<label>
<input type="checkbox" name="interests" value="javascript"> JavaScript
</label>
<label>
<input type="checkbox" name="interests" value="html"> HTML
</label>
<label>
<input type="checkbox" name="interests" value="css"> CSS
</label>
</div>
// Alle ausgewählten Werte abrufen
function getSelectedInterests() {
const checkboxes = document.querySelectorAll('input[name="interests"]:checked');
const values = Array.from(checkboxes).map(cb => cb.value);
return values;
}
// Bei Formularübermittlung
form.addEventListener('submit', function(event) {
event.preventDefault();
const interests = getSelectedInterests();
console.log('Ausgewählte Interessen:', interests);
});
Select-Dropdowns
<div>
<label for="country">Land:</label>
<select id="country" name="country">
<option value="">Land auswählen</option>
<option value="us">Vereinigte Staaten</option>
<option value="ca">Kanada</option>
<option value="uk">Vereinigtes Königreich</option>
</select>
</div>
// Ausgewählten Wert abrufen
const country = document.getElementById('country').value;
// Auf Änderungen hören
document.getElementById('country').addEventListener('change', function() {
console.log('Ausgewähltes Land:', this.value);
});
Vollständiges Beispiel für Formularverarbeitung
Lassen Sie uns alles in einem vollständigen Beispiel zusammenfassen:
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('signup-form');
// Echtzeit-Validierung einrichten
setupRealTimeValidation();
form.addEventListener('submit', function(event) {
event.preventDefault();
if (validateForm()) {
// Objekt mit Formulardaten erstellen
const formData = new FormData(form);
const userData = Object.fromEntries(formData);
// Hier würden Sie normalerweise die Daten an einen Server senden
console.log('Übermittle Benutzerdaten:', userData);
// API-Aufruf simulieren
submitFormData(userData)
.then(response => {
showSuccessMessage('Konto erfolgreich erstellt!');
form.reset();
})
.catch(error => {
showErrorMessage('Fehler beim Erstellen des Kontos. Bitte versuchen Sie es erneut.');
});
}
});
function validateForm() {
// Vorherige Fehler löschen
clearErrors();
let isValid = true;
const username = form.elements.username;
const email = form.elements.email;
const password = form.elements.password;
// Benutzername validieren
if (username.value.trim() === '') {
displayError(username, 'Benutzername ist erforderlich');
isValid = false;
} else if (username.value.length < 3) {
displayError(username, 'Benutzername muss mindestens 3 Zeichen haben');
isValid = false;
}
// E-Mail validieren
if (email.value.trim() === '') {
displayError(email, 'E-Mail ist erforderlich');
isValid = false;
} else if (!isValidEmail(email.value)) {
displayError(email, 'Bitte geben Sie eine gültige E-Mail-Adresse ein');
isValid = false;
}
// Passwort validieren
if (password.value === '') {
displayError(password, 'Passwort ist erforderlich');
isValid = false;
} else if (password.value.length < 8) {
displayError(password, 'Passwort muss mindestens 8 Zeichen haben');
isValid = false;
} else if (!/[A-Z]/.test(password.value) || !/[a-z]/.test(password.value) || !/[0-9]/.test(password.value)) {
displayError(password, 'Passwort muss Groß-, Kleinbuchstaben und Zahlen enthalten');
isValid = false;
}
return isValid;
}
function setupRealTimeValidation() {
const inputs = form.querySelectorAll('input');
inputs.forEach(input => {
input.addEventListener('input', function() {
// Fehler löschen, wenn Benutzer zu tippen beginnt
const errorElement = this.parentElement.querySelector('.error-message');
if (errorElement) {
errorElement.remove();
this.classList.remove('error-input');
}
});
});
// E-Mail-spezifische Validierung
form.elements.email.addEventListener('blur', function() {
if (this.value && !isValidEmail(this.value)) {
displayError(this, 'Bitte geben Sie eine gültige E-Mail-Adresse ein');
}
});
}
// Hilfsfunktionen
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function displayError(input, message) {
const formControl = input.parentElement;
const errorElement = document.createElement('div');
errorElement.className = 'error-message';
errorElement.textContent = message;
formControl.appendChild(errorElement);
input.classList.add('error-input');
}
function clearErrors() {
document.querySelectorAll('.error-message').forEach(error => error.remove());
document.querySelectorAll('.error-input').forEach(input => {
input.classList.remove('error-input');
});
}
function showSuccessMessage(message) {
const messageElement = document.createElement('div');
messageElement.className = 'success-message';
messageElement.textContent = message;
form.parentElement.insertBefore(messageElement, form);
// Nach 3 Sekunden entfernen
setTimeout(() => {
messageElement.remove();
}, 3000);
}
function showErrorMessage(message) {
const messageElement = document.createElement('div');
messageElement.className = 'error-banner';
messageElement.textContent = message;
form.parentElement.insertBefore(messageElement, form);
// Nach 3 Sekunden entfernen
setTimeout(() => {
messageElement.remove();
}, 3000);
}
// API-Übermittlung simulieren
function submitFormData(data) {
return new Promise((resolve, reject) => {
// Netzwerk-Anfrage simulieren
setTimeout(() => {
// 90% Erfolgsrate für Demo
if (Math.random() > 0.1) {
resolve({ success: true, message: 'Benutzer erstellt' });
} else {
reject({ success: false, message: 'Server-Fehler' });
}
}, 1500);
});
}
});
Überlegungen zur Barrierefreiheit von Formularen
Bei der Verarbeitung von Formularen mit JavaScript stellen Sie sicher, dass sie barrierefrei bleiben:
- Fokus-Management beibehalten: Bei der Anzeige von Fehlern setzen Sie den Fokus auf das erste ungültige Feld
- ARIA-Attribute verwenden: Fügen Sie
aria-invalid="true"
zu ungültigen Feldern hinzu - Fehlermeldungen verknüpfen: Verwenden Sie
aria-describedby
, um Eingaben mit ihren Fehlermeldungen zu verbinden - Klare Anweisungen bereitstellen: Verwenden Sie
<label>
-Elemente und beschreibende Fehlermeldungen - Tastaturnavigation unterstützen: Stellen Sie sicher, dass alle Formularsteuerelemente über die Tastatur zugänglich sind
Beispiel für barrierefreie Fehlerbehandlung:
function displayError(input, message) {
const formControl = input.parentElement;
const errorId = `${input.id}-error`;
const errorElement = document.createElement('div');
errorElement.id = errorId;
errorElement.className = 'error-message';
errorElement.textContent = message;
formControl.appendChild(errorElement);
// Barrierefreiheits-Attribute hinzufügen
input.setAttribute('aria-invalid', 'true');
input.setAttribute('aria-describedby', errorId);
// Fokus auf die erste ungültige Eingabe setzen
if (!document.querySelector('.error-input')) {
input.focus();
}
input.classList.add('error-input');
}
Häufig gestellte Fragen
Verwenden Sie die eingebaute reset-Methode auf dem Formularelement: document.getElementById('myForm').reset();
Verwenden Sie die checkValidity-Methode der Constraint Validation API: const isValid = form.checkValidity();
Um Formulardaten asynchron zu übermitteln, verwenden Sie die Fetch API zusammen mit dem FormData-Objekt. Erstellen Sie zunächst eine FormData-Instanz aus Ihrem Formular. Senden Sie sie dann mit fetch und der POST-Methode. Stellen Sie sicher, dass Sie die Antwort verarbeiten und alle Fehler während der Übermittlung abfangen.
Um Datei-Uploads zu behandeln, greifen Sie auf die files-Eigenschaft des Datei-Eingabeelements zu, rufen Sie die ausgewählte Datei ab und fügen Sie sie einem FormData-Objekt hinzu, bevor Sie sie mit fetch oder einer anderen Methode übermitteln.
Das `input`-Event wird ausgelöst, wann immer sich der Eingabewert ändert, während das `change`-Event nur ausgelöst wird, wenn die Eingabe den Fokus verliert und sich der Wert seit dem Erhalt des Fokus geändert hat.
Um Formularfelder dynamisch hinzuzufügen, erstellen Sie neue Eingabeelemente mit document.createElement, setzen Sie deren Typ und Namen und fügen Sie sie einem Container-Element im Formular hinzu.
Fazit
Durch die Beherrschung der Vanilla JavaScript-Formularverarbeitung erhalten Sie vollständige Kontrolle über Ihre Formulare, ohne auf externe Bibliotheken angewiesen zu sein. Dieser Ansatz reduziert Abhängigkeiten, verbessert die Performance und vertieft Ihr Verständnis dafür, wie Web-Formulare tatsächlich funktionieren.