Wenn man schon seit Jahren mit HTML arbeitet, ist es doch sehr überraschend wenn man wieder etwas neues entdeckt (abseits von dem ganzen HTML5-Javascript-Kram). Bei mir gilt das für die Form-Attribute, mit denen man HTML-Formulare deutlich dynamischer gestalten kann. Diese ermöglichen, dass man ein Formular an verschiedene Adressen schicken kann, mit verschiedenen Methoden und sogar mit Elementen außerhalb der Form. Und das alles ohne Javascript.

Buttons modifizieren

Bei einem Button, egal ob <input type="submit"> oder <button>, kann man die Attribute der Form überschreiben, wenn der Button angeklickt wird. So kann man das selbe Formular bequem für verschiedene Aktionen verwenden, z.B. wenn man GET und POST korrekt trennen möchte.

Die Attribute am Button entsprechen denen, die man bei <form> direkt angibt, allerdings mit einem davorgesetzten form.

formaction Gibt die URL an, an die das Formular geschickt werden soll
formenctype Gibt das Encoding für die Form an, z.B. multipart/form-data
formmethod Gibt die Methode an (GET, POST, etc.)
formnovalidate Deaktiviert die Validierung beim Submit über die Schaltfläche
formtarget Gibt das Zielfenster an, z.B. _blank für ein neues Fenster

Besonders hervorzuheben ist noch formnovalidate um die Validierung des Formulars zu deaktivieren. Das ist hilfreich, wenn der Button eine Aktion ausführen soll, für die die Validierung der Inputs gar nicht notwendig ist, z.B. beim Löschen. Bei MDN Web Docs findet man eine ausführliche Erklärung der einzelnen Attribute.

Beispiele

Bearbeitungsformular

Ein Beispiel ist ein Bearbeitungsformular, in dem man mehrere Schaltflächen zum Speichern, Löschen und ggf. noch weitere Aktionen anbieten möchte. Denn so kann man der Löschen-Schaltfläche eine andere URL geben und auch noch die Validierung deaktivieren.

Beachten muss man dennoch, dass immer alle Inputs des Formulars mit Namen und Wert mitgeschickt werden. Die Schaltflächen, bis auf die, die man angeklickt hat, sind davon natürlich ausgeschlossen. So bekommt das Bearbeitungsformular auch beim Klick auf Löschen alle Bearbeitungselemente mitgeschickt. Solange der Server die anderen Parameter ignoriert, sollte das aber kein Problem sein.

Listen

Auch bei Listen, bei den jedes Element ein Häkchen besitzt, ist kann das hilfreich sein: Man kann z.B. eine Schaltfläche zum Download der gewählten Elemente mit GET-Abruf und -Parametern für eine bestimmte URL hinterlegen, und (im gleichen Formular) eine Schaltfläche zum Löschen der gewählten Elemente, die einen POST auf eine andere URL ausführt.

<form action="/files" method="get">
    <ul>
        <li>
            <input type="checkbox" name="file[]" value="file-1.pdf"> file-1.pdf
        </li>
        <li>
            <input type="checkbox" name="file[]" value="file-2.xml"> file-2.xml
        </li>
    </ul>
    <button name="type" value="zip" formaction="/files/pack">Download ZIP</button>
    <button name="action" value="delete" formmethod="post">Löschen</button>
</form>

Hier z.B. ein Formular, das einen GET-Request je nach Schaltfläche an verschiedene Suchmaschinen schickt. Das ganze funktioniert allerdings nur, weil alle den Suchbegriff im Parameter q erwarten.

In <form> wurde überhaupt keine action angegeben, dafür aber z.B. bei der Google-Schaltfläche:

<button formaction="https://www.google.com/search">Google</button>

Elemente außerhalb der Form

Üblicherweise gehören zu einem Formular alle Elemente, die sich innerhalb des <form>-Tags befinden. Mit dem Attribut form kann man aber auch Elemente zu einer Form hinzufügen, die außerhalb sind. Dazu muss im Attributwert die Id der Form angegeben werden, ähnlich wie bei <label for="myId">. Das funktioniert bei allen Formularelementen, nicht nur bei den Schaltflächen.

So kann man das Formular oben auch an dieser Stelle noch um DuckDuckGo erweitern:

Das ist sehr hilfreich, wenn man ein Modal (z.B. das von Bootstrap) zum Bestätigen einer Aktion anzeigen möchte. Das Modal befindet sich außerhalb der Form, hat nur den Button und gibt mit dem Form-Attribut das ursprüngliche Formular an. Der Button in der Form öffnet nur das Modal.

<form action="/action" method="post" id="mymainform">
    <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#mymodal">Aktion bestätigen</button>
</form>
<div class="modal" id="mymodal">
    ...
    <div class="modal-footer">
        <button class="btn btn-primary" form="mymainform">Aktion ausführen</button>
    </div>
    ...
</div>

Man kann das Modal auch noch um normale Eingabe- oder Auswahlfelder ergänzen. Berücksichtigen muss man allerdings, dass deren Werte im Gegensatz zur Schaltfläche natürlich beim Absenden mit jeder beliebigen Schaltfläche mitgeschickt werden – auch wenn das Modal gar nicht sichtbar ist. Wer also sowohl beim Löschen- als auch beim Speichern-Modal ein Kommentarfeld haben möchte, muss diesen deswegen unterschiedliche Namen geben und serverseitig je nach Aktion den passenden Parameter auswerten. Ansonsten kann man mit dieser Variante aber sowohl auf eine zusätzliche Form im Modal bzw. auf zusätzliches Javascript verzichten.