Als je een formulier bouwt, gebruik je frameworks of formulierbouwers. Maar onder de motorkap gebruiken ze allemaal HTML-formulieren. Als je snapt hoe HTML-formulieren werken, snap je al het andere ook. Je bent niet afhankelijk van een tool of framework. Je kent de basis.
In dit artikel lees je over het HTML-formulierelement, invoertypes, labels, validatie en hoe formulieren echt worden verstuurd. Geen frameworks. Geen bibliotheken. Alleen HTML en de principes waar al het andere op is gebouwd.
Het HTML-formulierelement
Een formulier is een HTML-element dat formuliervelden omvat en hun gegevens ergens naartoe stuurt. De basisopbouw is:
<form action="/submit" method="POST">
<input type="text" name="email">
<button type="submit">Send</button>
</form>
Drie attributen zijn belangrijk. Het attribuut action vertelt het formulier waarheen het gegevens stuurt. "/submit" betekent: verstuur naar het eindpunt /submit op je server. Is action leeg, dan wordt het formulier naar de huidige pagina verstuurd. Het attribuut method vertelt het formulier hoe de gegevens onderweg zijn. POST stuurt gegevens in de body van het verzoek (veilig, niet zichtbaar in de URL). GET plakt gegevens aan de URL (onveilig voor gevoelige gegevens, handig voor zoekopdrachten). Het attribuut enctype heb je alleen nodig voor bestandsuploads. Stel enctype="multipart/form-data" in als je formulier een bestandsveld heeft.
Alles tussen de formuliertags hoort bij de inzending. Klikt de gebruiker op een verzendknop, dan verzamelt de browser alle velden met een naam en stuurt ze met de opgegeven methode naar de action-URL.
Invoertypes en wat ze doen
text
<input type="text" name="first_name">
Een tekstveld van één regel. De browser toont een gewoon tekstvak. Geen validatie. Elk teken is toegestaan.
<input type="email" name="email">
Een veld voor e-mailadressen. Op een computer ziet het eruit als een tekstveld. Op mobiel toont de browser een e-mailtoetsenbord. Bij het versturen controleert de browser of de waarde op een e-mailadres lijkt (met een @). Alleen basisvalidatie.
password
<input type="password" name="password">
Tekst die tijdens het typen wordt verborgen achter puntjes of sterretjes. De waarde wordt nog steeds als gewone tekst verstuurd, dus gebruik bij formulieren met wachtwoordvelden altijd HTTPS.
number
<input type="number" name="age">
Op een computer een tekstveld dat alleen cijfers accepteert. Op mobiel toont de browser een numeriek toetsenbord. De browser voorkomt invoer die geen getal is.
date
<input type="date" name="birth_date">
Een datumkiezer. In ondersteunde browsers en op ondersteunde apparaten opent een klik op het veld een kalender. De waarde heeft de notatie JJJJ-MM-DD.
checkbox
<input type="checkbox" name="agree" value="yes">
Een vakje dat je aan en uit zet. Is het aangevinkt, dan wordt de waarde van het veld bij het versturen meegestuurd. Is het niet aangevinkt, dan wordt het veld helemaal niet verstuurd.
radio
<input type="radio" name="plan" value="starter"> Starter
<input type="radio" name="plan" value="pro"> Pro
Meerdere keuzerondjes met dezelfde naam vormen een groep. Er kan er maar één tegelijk gekozen zijn. De waarde van het gekozen rondje wordt bij het versturen meegestuurd.
select (keuzelijst)
<select name="country">
<option value="us">United States</option>
<option value="ca">Canada</option>
</select>
Een keuzemenu. De waarde van de gekozen optie wordt bij het versturen meegestuurd.
textarea
<textarea name="message"></textarea>
Een tekstveld van meerdere regels. Gebruikers kunnen hele alinea's typen. De waarde bevat regeleinden.
file
<input type="file" name="resume">
Een knop die de bestandskiezer van het apparaat opent. Het gekozen bestand wordt naar de server gestuurd. Vereist enctype="multipart/form-data" op het formulierelement.
hidden
<input type="hidden" name="user_id" value="12345">
Een veld dat niet wordt getoond, maar wel wordt meegestuurd. Handig voor trackinggegevens die moeten worden meegestuurd, maar die de gebruiker niet mag wijzigen.
Labels en toegankelijkheid
Koppel invoervelden altijd aan labels.
<label for="email">Email address</label>
<input type="email" id="email" name="email">
Het attribuut for van het label moet overeenkomen met de id van het invoerveld. Als je dit goed doet:
Schermlezers lezen het label en het veld samen voor, een klik op het label zet de cursor in het invoerveld en mobiele gebruikers krijgen een groter aanraakvlak.
Sla labels nooit over. Wil je een label visueel verbergen, doe dat dan met CSS, maar laat het in de HTML staan. Dit heet een "visueel verborgen" label.
Verwante velden groeperen
Gebruik voor verwante velden fieldset en legend.
<fieldset>
<legend>Shipping address</legend>
<input type="text" name="street">
<input type="text" name="city">
</fieldset>
Het legend-element kondigt de groep aan voor schermlezers. Fieldsets helpen keuzerondjes en selectievakjes visueel en semantisch te ordenen.
Formulieren versturen en HTTP-methodes
Klikt de gebruiker op de verzendknop, dan verzamelt de browser alle velden met een naam, codeert de gegevens (standaard application/x-www-form-urlencoded), stuurt een HTTP-verzoek naar de action-URL met de methode (POST of GET) en wacht op een antwoord.
De server ontvangt het verzoek en kan de gegevens verwerken. De gegevens komen binnen als sleutel-waardeparen. Is de formuliermethode POST en de action "/submit", dan ziet het verzoek er zo uit. POST /submit HTTP/1.1 met Content-Type ingesteld op application/x-www-form-urlencoded, daarna staan de gegevens als email=user@example.com&name=John.
De server leest deze gegevens uit en antwoordt. Is het antwoord een pagina, dan laadt de browser die. Is het antwoord een doorverwijzing, dan gaat de browser naar de nieuwe URL.
Validatie in de browser
HTML heeft ingebouwde validatie-attributen. De browser controleert die voordat het formulier wordt verstuurd.
required
<input type="text" name="email" required>
Het veld moet een waarde hebben. Blijft het leeg, dan wordt het formulier niet verstuurd en toont de browser een foutmelding.
minlength en maxlength
<input type="password" name="password" minlength="8" maxlength="128">
De waarde moet tussen het opgegeven minimale en maximale aantal tekens liggen.
min en max
<input type="number" name="age" min="18" max="120">
Bij getalvelden moet de waarde binnen het bereik liggen.
pattern
<input type="text" name="zip_code" pattern="[0-9]{5}">
Een reguliere expressie waar de waarde aan moet voldoen. Een postcode van vijf cijfers komt overeen met [0-9]{5}.
Validatie in de browser is een gemak voor gebruikers. Ze voorkomt dat ze ongeldige gegevens versturen en daarna een foutmelding van de server zien. Maar vertrouw voor beveiliging nooit alleen op validatie in de browser. Valideer altijd ook op de server.
Het verschil tussen type="submit" en type="button"
<button type="submit">Send</button>
<button type="button">Save</button>
Een knop met type="submit" verstuurt het formulier bij een klik. Een knop met type="button" doet standaard niets. Gebruik type="button" als je JavaScript-gebeurtenissen wilt koppelen.
Veel ontwikkelaars gebruiken <button> zonder type. Dan geldt standaard type="submit", en dat is meestal wat je wilt. Maar wees expliciet, om verrassingen te voorkomen.
Waarom je HTML-formulieren moet begrijpen
Gebruik je React, Vue of Angular, dan bouw je voort op HTML-formulieren. Frameworks verbergen de details, maar de onderliggende principes blijven dezelfde. Een formulier verstuurt nog steeds naar een eindpunt. Validatie moet nog steeds gebeuren. De server moet de gegevens nog steeds verwerken.
Gaat er iets mis bij het verwerken van je formulier, dan helpt kennis van HTML bij het zoeken naar de oorzaak. Je weet waar de gegevens vandaan komen, hoe ze worden gecodeerd en wat de server hoort te ontvangen. Dit is de basis.
De meeste moderne webapps gebruiken geen traditionele formulierverwerking meer. Ze gebruiken JavaScript om het formulier af te vangen, te valideren en de gegevens te versturen met _blocked_ of axios. Maar als je eerst de HTML-manier kent, begrijp je die patronen veel beter.
Hoe de formulierenbouwer van WEMASY deze principes gebruikt
Onder de motorkap maakt de formulierenbouwer van WEMASY toegankelijke HTML-formulieren met dezelfde elementen. Labels zijn gekoppeld aan invoervelden. Validatie gebeurt zowel in de browser als op de server. Formuliergegevens worden veilig verstuurd. Als je een WEMASY-formulier exporteert of aanpast, werk je met HTML-formulieren die op deze basis zijn gebouwd.
Bekijk de prijzenpagina van WEMASY voor details over formulierfuncties en aanpassingsmogelijkheden.