HTML-formulieren: de basisbouwstenen

Leer de basis van HTML-formulieren. Bouw toegankelijke formulieren met de juiste opbouw, invoertypes, validatie en verwerking van inzendingen.

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.

email

<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.

Veelgestelde vragen

Moet ik GET of POST gebruiken om mijn formulier te versturen?
Gebruik POST voor elk formulier dat gegevens wijzigt, gevoelige informatie verstuurt of bestanden uploadt. Gebruik GET alleen voor zoekformulieren waarbij de zoekopdracht zichtbaar mag zijn in de URL. GET is minder veilig en heeft een maximale URL-lengte. POST is voor de meeste formulieren de veilige keuze. Met de websitebouwer van WEMASY stel je dit direct in op je eigen website.
Is validatie in de browser genoeg, of moet ik ook op de server valideren?
Valideer altijd op de server. Validatie in de browser is er voor de gebruikerservaring. Iemand kan JavaScript uitzetten of de controles van de browser omzeilen. Op de server gebeurt de echte beveiliging. Doe beide.
Hoe verstuur ik een formulier met JavaScript in plaats van de standaardmethode?
Luister met addEventListener naar de gebeurtenis submit, roep event.preventDefault() aan en gebruik daarna _blocked_ of axios om de gegevens te versturen. Zo kun je gegevens valideren, omzetten of aanvullen voordat je ze verstuurt.
Wat is het verschil tussen formuliergegevens en JSON?
Formulieren sturen gegevens standaard als application/x-www-form-urlencoded (sleutel-waardeparen). JSON is een ander formaat. Als je een formulier met JavaScript afvangt en met _blocked_ JSON verstuurt, verander je het contenttype. De server moet weten welk formaat hij kan verwachten.
Waarom moet ik label-elementen gebruiken in plaats van gewoon tekst naast invoervelden te zetten?
Labels verbeteren de toegankelijkheid voor schermlezers en toetsenbordnavigatie. Ze maken op mobiel ook een groter klikvlak. Moet je een label visueel verbergen, doe dat dan met CSS, maar laat het in de HTML staan, zodat hulptechnologie het kan vinden.
Moet ik me zorgen maken over CSRF-bescherming bij formulieren?
Ja. Wijzigt je formulier gegevens (aanmaken, bijwerken of verwijderen), gebruik dan een CSRF-token om cross-site request forgery te voorkomen. Neem een verborgen invoerveld op met een unieke token die de server aanmaakt. Controleer de token als het formulier wordt verstuurd.

Zet het meteen
in je eigen website.

Start gratis met WEMASY en bouw je site in een paar minuten.