Back

Formularverarbeitung mit Vanilla JavaScript: Kein Framework erforderlich

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- und blur-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 werden
  • minlength/maxlength: Minimale/maximale Textlänge
  • min/max: Minimal-/Maximalwerte für Zahleneingaben
  • pattern: Regulärer Ausdruck-Pattern zum Abgleich
  • type="email": Validiert E-Mail-Format
  • type="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:

  1. Fokus-Management beibehalten: Bei der Anzeige von Fehlern setzen Sie den Fokus auf das erste ungültige Feld
  2. ARIA-Attribute verwenden: Fügen Sie aria-invalid="true" zu ungültigen Feldern hinzu
  3. Fehlermeldungen verknüpfen: Verwenden Sie aria-describedby, um Eingaben mit ihren Fehlermeldungen zu verbinden
  4. Klare Anweisungen bereitstellen: Verwenden Sie <label>-Elemente und beschreibende Fehlermeldungen
  5. 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.

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers