Signatur
Beschreibung
Das formdata-Ereignis wird an einem HTMLFormElement ausgelöst, sobald der Browser die Eintragsliste (entry list) des Formulars aufgebaut hat. Das passiert in zwei Fällen: wenn das Formular abgeschickt wird (normal oder per form.requestSubmit()) und wenn ein FormData-Objekt mit new FormData(form) erzeugt wird. Das Ereignisobjekt ist ein FormDataEvent. Seine Eigenschaft formData enthält das FormData-Objekt mit den gesammelten Feldwerten.
Der wichtigste Einsatzzweck: Die Daten lassen sich unmittelbar vor dem Versand verändern oder ergänzen, ohne versteckte <input type="hidden">-Felder anlegen zu müssen. Typische Fälle sind Werte aus contenteditable-Bereichen, Canvas-Inhalte, Werte eigener Web Components ohne ElementInternals, Zeitstempel oder Client-Metadaten. Änderungen an event.formData landen direkt in den gesendeten Daten bzw. im erzeugten FormData-Objekt.
Registrieren kannst du den Handler mit form.addEventListener("formdata", handler) oder über die Eigenschaft form.onformdata = handler. Das Ereignis läuft synchron, steigt im DOM auf (bubbles) und ist nicht abbrechbar. preventDefault() verhindert also weder das Absenden noch das Erzeugen der Daten. Dafür ist das submit-Ereignis zuständig, das vor formdata ausgelöst wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, immer "formdata". |
|
| $handler Pflicht | (event: FormDataEvent) => void | Callback, der ein FormDataEvent erhält. Über event.formData greifst du auf das FormData-Objekt zu und kannst es verändern. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, capture, passive oder signal (zum Entfernen per AbortController). |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein FormDataEvent, dessen schreibgeschützte Eigenschaft formData auf das veränderbare FormData-Objekt zeigt.Beispiele
Zusätzliche Daten beim Absenden anhängen
// HTML: <form id="kontakt" action="/senden" method="post"><input name="email"><button>Senden</button></form>
const form = document.querySelector('#kontakt');
form.addEventListener('formdata', (event) => {
// Werte ergänzen, ohne versteckte Inputs anzulegen
event.formData.append('gesendetAm', new Date().toISOString());
event.formData.append('sprache', navigator.language);
});
// Das Ereignis wird auch durch new FormData(form) ausgelöst:
const daten = new FormData(form);
console.log([...daten.keys()]);
Inhalt eines contenteditable-Editors mitsenden (on-Property)
// HTML: <form id="artikel"><div id="editor" contenteditable>Hallo <b>Welt</b></div><button>Speichern</button></form>
const form = document.querySelector('#artikel');
const editor = document.querySelector('#editor');
form.onformdata = (event) => {
event.formData.set('inhalt', editor.innerHTML);
};
form.addEventListener('submit', async (event) => {
event.preventDefault();
const body = new FormData(form); // löst formdata aus
const res = await fetch('/api/artikel', { method: 'POST', body });
console.log('Status:', res.status);
});
Sensible Felder entfernen und Listener wieder abmelden
const form = document.querySelector('form');
const bereinigen = (event) => {
// Hilfsfeld nicht an den Server schicken
event.formData.delete('passwortWiederholung');
// Leerzeichen am Rand der E-Mail entfernen
const email = event.formData.get('email');
if (typeof email === 'string') event.formData.set('email', email.trim());
};
form.addEventListener('formdata', bereinigen);
// Später, z. B. beim Abbau der Komponente:
form.removeEventListener('formdata', bereinigen);
// Alternativ, falls per Property gesetzt: form.onformdata = null;
// Wichtig · Fallstricke
- Keine Rekursion: Rufst du innerhalb des Handlers erneut
new FormData(form)für dasselbe Formular auf, wirft der Browser eineInvalidStateError-DOMException, weil die Eintragsliste gerade aufgebaut wird. Arbeite deshalb immer mitevent.formData. - Nicht abbrechbar:
event.preventDefault()hat keine Wirkung. Um das Absenden zu stoppen, nutze dassubmit-Ereignis. - Synchron: Asynchrone Änderungen, etwa nach einem
await, kommen zu spät und werden nicht mehr übertragen. - Bei Formularen mit
method=\"get\"oderenctype=\"application/x-www-form-urlencoded\"werden angehängteBlob/File-Werte nur als Dateiname übertragen. Für Dateien brauchst dumultipart/form-data. - Das Ereignis steigt auf. Ein Listener auf
documenterfasst daher dieformdata-Ereignisse aller Formulare. Das eignet sich für globale Ergänzungen wie CSRF-Tokens, du solltest aberevent.targetprüfen. - Kompatibilität: Chrome/Edge 77+, Firefox 72+, Safari 15+. In älteren Browsern greifst du als Ersatz auf versteckte Inputs im
submit-Handler zurück. Die Unterstützung kannst du mit'onformdata' in HTMLFormElement.prototypeprüfen.