# HTML/Basiscursus/Formulieren

Op een webpagina kan een bezoeker een formulier invullen met gevraagde gegevens. Een voorbeeld hiervan is een loginformulier. Hierop vult de gebruiker een gebruikersnaam en een wachtwoord in, waarna hij toegang krijgt tot bepaalde pagina's op de site. Dit is slechts een van de vele mogelijkheden van het gebruik van formulieren. Samengevat: formulieren worden gebruikt om informatie van de gebruiker te krijgen.

## De HTML-tag <form>

Er zijn meerdere mogelijkheden een formulier in HTML te maken. De belangrijkste is met behulp van de tags <form>...</form>. Alle andere elementen van een formulier zitten tussen deze tags. Er zijn drie attributen die voor het maken van een formulier van belang kunnen zijn, namelijk action, method en enctype. Aangezien enctype meestal niet wordt gebruikt, is deze in het voorbeeld hieronder weggelaten.
HTML-code: Basis van een formulier

### action

Dit attribuut is verplicht. De 'waarde' van het attribuut is de webpagina waarin een script staat dat de informatie van het formulier verwerkt, bijvoorbeeld een script dat de gebruiker inlogt. Bij het verzenden van een formulier wordt de informatie daarheen gestuurd. Als het attribuut leeg is (<form action="">), wordt het formulier naar de actieve pagina verzonden.

### method

Het attribuut method bepaalt hoe de informatie wordt verzonden. Er zijn twee mogelijkheden: get en post. Is het attribuut leeg of niet aanwezig, dan geldt de defaultwaarde get.
* get
** Met de methode get worden de gegevens van het formulier via de URL verzonden. Als je bijvoorbeeld je naam (pietje) moet invullen in het vakje je_naam en daarna het formulier verzendt, ga je naar de pagina script.php?je_naam=pietje. Je kan deze method goed gebruiken bij zoekopdrachten (kijk maar in de URL bij Google achter ?q=).
* post
** Hiermee worden de gegevens van het forumulier verzonden zonder dat ze in de URL staan.
Je mag helemaal zelf bepalen welke method je gebruikt. Bedenk alleen het volgende.
* Als een gebruiker inlogt via de method get, is zijn wachtwoord zichtbaar in de adresbalk, en erger, in de geschiedenis van de browser. Iemand anders die daarna op dezelfde computer door de geschiedenis bladert, kan zomaar inloggen.
* Als je een zoekformulier (bv. Google) via post verzendt, komt je zoekaanvraag niet goed in de geschiedenis. Daarbij is het voor andere sites moeilijker om jouw zoekfunctie te gebruiken.

### enctype (geavanceerd)

Dit attribuut bepaald het encoding type, de manier waarop de gegevens gecodeerd worden. Dit coderen wil NIET zeggen dat je gegevens veilig worden verzonden, maar alleen dat ze dusdanig gecodeerd worden, dat de browser en het script ze niet als bijvoorbeeld HTML tags gaat gebruiken. Als je dit niet invult (en meestal doe je dit niet) is de standaardwaarde van dit attribuut application/x-www-form-urlencoded. In de meeste gevallen is dit goed genoeg. Er zijn veel andere waarden voor enctype, en twee hiervan worden naast application/x-www-form-urlencoded wel eens gebruikt.
* text/plain
** Als je begint met HTML, zal je nog niet genoeg kennis hebben van server-sided scripttalen als PHP om je formuliergegevens te verwerken. Een makkelijk alternatief is dan het mailen van de gegevens naar een e-mailadres. Om de gegevens dan leesbaar te maken kan je deze enctype gebruiken. Je moet dan wel method="post" gebruiken.
HTML-code: Een formulier verzenden via e-mail
In de volgende tabel staat hoe de gegevens verstuurd worden in de tekst van het e-mailbericht. De enctype text/plain geeft een duidelijker overzicht.
| "application/x-www-form-urlencoded" | "text/plain" |
| je_naam=Pietje&je_leeftijd=ouder+dan+25 | je_naam=Pietje je_leeftijd=ouder dan 25 |
* multipart/form-data
** Deze enctype moet gebruikt worden om bestanden (bijvoorbeeld een foto) te versturen via een formulier. Kijk bij bestanden uploaden hoe je dat kan doen.

## Elementen in binnen <form>...</form>

Binnen de <form>...</form> tags staan de velden die een gebruiker kan invullen en die daarna naar script.php worden verstuurd. Alle gegeven code moet binnen het <form>...</form> element staan om verzonden te worden met het verzenden van het formulier. Het is echter niet verplicht om de elementen in een formulier te zetten. Het is bijvoorbeeld ook mogelijk elementen zonder formulier te verzenden met JavaScript (AJAX). Er zijn verschillende soorten velden met elk hun eigen attributen. Hieronder wordt voor elk van deze velden een uitleg gegeven. Omdat er een aantal attributen zijn die voor (bijna) alle velden gebruikt worden, zullen deze eerst worden uitgelegd.

### Standaardattributen

* name="": Alle velden die je in script.php wilt uitlezen, moeten een naam hebben. Dit doe je met dit attribuut. Een naam moet uniek zijn (behalve bij radiobuttons) binnen het formulier. Als je een naam meerdere keren gebruikt, wordt alleen de laatste keer door script.php gebruikt. Je mag de naam zelf kiezen, maar het wordt aangeraden om geen spaties en vreemde tekens te gebruiken, maar alleen letters, cijfers, dashes (-) en underscores (_). Uitzondering: name="namen_in_jouw_familie": Aan het eind van de naam kunnen twee blokhaken () geplaatst worden. Hierdoor kan je meerdere velden met dezelfde naam versturen, bijvoorbeeld om iemand alle voornamen in zijn familie te laten invoeren.
* value="": Hiermee geef je een veld een waarde. Voor tekstvelden is dit een standaardwaarde die de gebruiker kan wijzigen. Voor de andere velden is dit de waarde die naar script.php wordt gestuurd en niet de waarde die de gebruiker ziet.
** Bij checkboxen, radiobuttons en keuzelijsten is het geven van een value niet genoeg om deze waarde standaard (bij het laden van de pagina) geselecteerd te hebben. Hiervoor voeg je de volgende attributen toe.
*** checked="checked": Voor checkboxen en radiobuttons voeg je dit attribuut toe aan de tag. Als er aan meerdere radiobuttons met dezelfde naam dit attribuut wordt toegevoegd, wordt alleen het laatste als standaard geselecteerd.
*** selected="selected": Voor keuzelijsten gebruik je dit attribuut. Dit werkt op dezelfde manier als bij radiobuttons.
* disabled="disabled": Met dit attribuut kan het veld niet meer bewerkt worden. Ook kan de tekst niet meer worden geselecteerd, en in de meeste browsers wordt het veld grijs weergegeven.
* readonly="readonly": Dit werk hetzelfde als disabled alleen kan de tekst nog geselecteerd worden.

### Knoppen

Knoppen gebruik je om de gebruiker iets te laten doen, bijvoorbeeld het versturen of resetten van het formulier. Voor knoppen kan je de <input /> of de <button></button>-tag gebruiken. Er bestaan drie soorten knoppen:
* type="submit"
** Hiermee wordt het formulier opgestuurd naar de pagina die is opgegeven met het action attribuut.
* type="reset"
** Hiermee wordt het formulier gereset, waardoor alle velden de beginwaarde krijgen die ze bij het laden van de pagina hadden.
* type="button"
** Een knop zonder standaardactie. Je kan deze een eigen actie geven. In |de cursus over JavaScript staat welke acties je allemaal kan toekennen.
Je kan knoppen op twee manieren maken. In de onderstaande code staat van elk type een voorbeeld.
HTML-code: Knoppen

### Tekstveld

Het eenvoudigste veld is een tekstveld. Hierin kan de gebruiker een enkele regel tekst invoeren. Hiervoor gebruik het de <input /> tag. Om aan te geven wat voor input het is, gebruik je het attribuut type="text". Omdat text de standaardwaarde van type is, kan je dit hele attribuut eventueel weglaten. Met het attribuut maxlength="5" wordt het maximale aantal tekens die ingevoerd kunnen worden, op vijf ingesteld.
HTML-code: Een standaardtekstveld

### Tekstarea

Als een gebruiker grotere stukken tekst moet typen, gebruik je een <textarea>. Een tekstvak wordt ook op Wikipedia gebruikt, bijvoorbeeld om een artikel te bewerken (klik bovenaan de pagina op bewerken voor een voorbeeld). Een textarea heeft twee verplichte attributen, namelijk cols en rows. Hiermee bepaal je de breedte en de hoogte. In het onderstaande voorbeeld is de breedte 40 tekens (in een [:w:Monospace|monospace]] lettertype, waarbij elk teken even breed is) en de hoogte 4 regels.
HTML-code: Tekstarea

#### Geen controle

Het nadeel van tekstvelden en textarea's is dat een gebruiker helemaal vrij is om in te vullen wat hij zelf wil. Dit is ten eerste gevaarlijk; de gebruiker kan tekst invoeren die script.php ontregeld, of bijvoorbeeld een database kapot maken. Om dit te voorkomen moeten er in script.php allerlei controles worden uitgevoerd. Ten tweede weet een gebruiker niet altijd wat hij mag invullen. Als de gebruiker bijvoorbeeld een taal moet selecteren. Met een tekstveld kan hij dan Japans invullen, terwijl de site alleen in het Nederlands, Engels en Vlaams beschikbaar is.
Deze twee voorbeelden geven twee van de drie groepen gebruikers weer:
* Slimme gebruikers: gebruikers die precies weten wat er ingevuld mag worden en deze kennis niet misbruiken (als je zelf een site maakt, val je hier zelf onder). Als je alleen deze gebruikers zou hebben, kan je alleen tekstvelden en textarea's gebruiken.
* Domme gebruikers: Deze weten niet precies wat er allemaal ingevuld mag worden en weten ook niet hoe je een site kan hacken. Als je een van de onderstaande velden maakt, kunnen zij hetzelfde als de Slimme gebruikers.
* Hackers: Deze weten niet precies wat er ingevuld mag worden, maar zullen proberen hierachter te komen om dit te misbruiken. Op deze groep moet je vooral letten als je de pagina script.php gaat schrijven en dit zal dus niet verder in deze cursus behandeld worden.

### Radiobuttons en Checkboxen

Deze twee soorten worden gemaakt met de <input /> tag. Radiobuttons krijg je met type="radio", checkboxen met type="checkbox". Het verschil tussen deze twee is dat meerdere checkboxen binnen een groep kunnen worden aangevinkt, en een checkbox ook weer kan worden uitgevinkt. Van radiobuttons met dezelfde naam (de uitzondering op de regel dat name uniek moet zijn) kan er maar een worden aangevinkt. Als er eenmaal een radiobutton binnen de groep is aangevinkt, kan deze niet meer worden uitgevinkt, tenzij de gebruiker op een andere radiobutton binnen de groep klikt. Aan radiobuttons en checkboxen moet een value worden meegegeven, omdat de tekst die de gebruiker ziet, buiten het element valt.
HTML-code: Radiobuttons en Checkboxen

#### Weergave

Er zijn drie elementen waarmee je deze velden goed overzichtelijk kan weergeven. Dit kan met de tag <fieldset>...</fieldset>, de tag <label>...</label> en de tag <legend>...</legend>. Met fieldset zet je een kader om de velden heen. Met label maak je de hele tekst binnen het label aanklikbaar, i.p.v. het rondje/vierkantje van de radiobutton of checkbox. En met legend kan je de groep een naam geven.
HTML-code: Opmaak van radiobuttons
Je kan deze tags ook bij andere velden gebruiken, maar bij de bovenstaande twee velden is het het nuttigst.

### Keuzelijsten

Als je iemand zijn geboortejaar wil laten invullen, kan je dat doen met radiobuttons. Het nadeel hiervan is dat de oudste mensen die nu nog leven, geboren zijn voor 1900, en je dus ruim 100 radiobuttons moet maken. Dit wordt erg onoverzichtelijk en het neemt veel ruimte in. In plaats van radiobuttons kan je hiervoor keuzelijsten gebruiken. Ook voor grote groepen van checkboxen kan je keuzelijsten gebruiken. Voor keuzelijsten heb je drie tags nodig. Ten eerste de lijst zelf. Deze maak je met <select>...</select>. Voor elke keuze gebruik je de tag <option>...</option>. Met de introductie van HTML 4.0 is er ook een mogelijkheid om de keuzes te sorteren met de tag <optgroup>...</optgroup>, maar dit wordt nog weinig gebruikt. Als je deze tag wel gebruikt, kan je met het labelattribuut (<optgroup label="naam van groep">) de naam van de groep weergeven. Aan het select-element moet de naam van het veld worden toegevoegd. De andere tags hoeven geen naam te hebben. De waarde (value) die naar script.php wordt verzonden moet aan het option element worden gegeven. Als je geen andere attributen aan het select element toevoegt, krijg je een gewone uitvouwbare keuzelijst. Door het attribuut size te gebruiken (<select size="5") worden er meerdere opties tegelijk weergegeven. Met het attribuut multiple (<select multiple="multiple" >) mogen er meerdere waarden worden geselecteerd. Dit kan door de Ctrl toets ingedrukt te houden terwijl je de keuzes aanklikt. Hiermee kan je het vergelijken met checkboxen i.p.v. radiobuttons. Let erop dat het lastig is voor de gebruiker, als er meerdere waarden geselecteerd mogen worden als de size klein is. Als je multiple gebruikt, is het aan te raden om minstens size="4" te gebruiken of geen size op te geven.
HTML-code: Keuzelijsten

### Andere tekstvelden

Naast het standaardtekstveld, zoals hierboven beschreven, zijn er nog twee andere tekstvelden.

#### Wachtwoorden

Dit veld wordt gemaakt met de <input /> tag met type="password". Er is geen verschil met het standaardtekstveld, behalve dat sterretjes (*) of rondjes worden getoond i.p.v. de getypte tekens, zodat het wachtwoord niet door anderen kan worden gelezen.
HTML-code: Wachtwoorden

#### Bestanden uploaden

Dit veld wordt gemaakt met de <input /> tag met type="file". Hiermee maak je een tekstveld (verplicht readonly) met een knop met 'bladeren...' ernaast (in sommige browsers zoals Google Chrome wordt het anders weergegeven maar de HTML code is hetzelfde). Voor het uploaden van bestanden moet de encoding (enctype) worden ingesteld op multipart/form-data en method op post.
HTML-code: Bestanden uploaden

### Verborgen velden

Dit veld wordt gemaakt met de <input /> tag met type="hidden". De gebruiker kan een verborgen veld niet zien en niet wijzigen, maar het wordt wel samen met de gegevens van het formulier opgestuurd. Dit kan bijvoorbeeld gebruikt worden om de ID van de gebruiker in een database mee te sturen (het formulier wordt dan opgebouwd door een PHP-script, bv. formulier_aanmaken.php. Een bijzonder verborgen veld is <input type="hidden" name="MAX_FILE_SIZE" /> (de hoofdletters zijn verplicht). Als er bestanden worden geüpload, wordt het uploaden afgebroken als het bestand groter is dan de opgegeven grootte. Dit kan handig zijn, omdat de gebruiker niet hoeft te wachten tot het bestand helemaal is geupload als script.php het bestand toch weigert als het te groot is.
HTML-code: Verborgen velden

## Verzenden

Er zijn drie manieren om het formulier te verzenden. Hoe je het verstuurt, bepaal je met het action attribuut.
* Met een server-sided script, bijvoorbeeld: script.php. Deze bestaat nog niet en je het zelf moeten aanmaken. Voor meer informatie hierover, kijk bij Wikibook PHP.
* Met een javascript functie. Voor meer informatie hierover, kijk bij Wikibook JavaScript.
** Een combinatie van de bovenstaande. Hierbij wordt eerst de functie uitgevoerd. Als deze een fout ontdekt, kan deze het versturen afbreken of de gebruiker vragen of hij echt door wil gaan. Daarna wordt het script verstuurd naar script.php.
* Versturen met de e-mail cliënt, op de computer waarop de pagina geladen is. Bijvoorbeeld: "mailto:emailadres@server.com".
In het onderstaande code staat een voorbeeld van deze manieren.
HTML-code: Drie manieren om een formulier te versturen

## Een voorbeeld van een formulier

Nu de meeste code voor een formulier behandeld is, komt hier nog een geheel voorbeeld: een formulier dat je kan invullen om aan te geven op welk tijdschrijft je je wilt abonneren.
HTML-code: Standaard, Wachtwoord, Upload, Verborgen velden