# Bouw een Bankapp Deel 2: Maak een Login- en Registratieformulier
## Pre-Lecture Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/43)
Heb je ooit een online formulier ingevuld dat je e-mailformaat afwees? Of al je informatie verloren toen je op verzenden klikte? We hebben allemaal wel eens zulke frustrerende ervaringen gehad.
Formulieren vormen de brug tussen je gebruikers en de functionaliteit van je applicatie. Net zoals luchtverkeersleiders zorgvuldig protocollen gebruiken om vliegtuigen veilig naar hun bestemming te begeleiden, bieden goed ontworpen formulieren duidelijke feedback en voorkomen ze kostbare fouten. Slechte formulieren daarentegen kunnen gebruikers sneller wegjagen dan een miscommunicatie op een druk vliegveld.
In deze les transformeren we je statische bankapp naar een interactieve applicatie. Je leert formulieren bouwen die gebruikersinvoer valideren, communiceren met servers en nuttige feedback geven. Zie het als het bouwen van een bedieningsinterface waarmee gebruikers door de functies van je applicatie kunnen navigeren.
Aan het einde heb je een compleet login- en registratiesysteem met validatie dat gebruikers begeleidt naar succes in plaats van frustratie.
## Vereisten
Voordat we beginnen met het bouwen van formulieren, zorgen we ervoor dat alles correct is ingesteld. Deze les gaat verder waar we de vorige hebben achtergelaten, dus als je vooruit hebt gespoeld, wil je misschien teruggaan en eerst de basis in orde maken.
### Vereiste Setup
| Component | Status | Beschrijving |
|-----------|--------|-------------|
| [HTML Templates](../1-template-route/README.md) | ✅ Vereist | De basisstructuur van je bankapp |
| [Node.js](https://nodejs.org) | ✅ Vereist | JavaScript runtime voor de server |
| [Bank API Server](../api/README.md) | ✅ Vereist | Backend service voor gegevensopslag |
> 💡 **Ontwikkeltip**: Je zult twee aparte servers tegelijkertijd draaien – één voor je frontend bankapp en een andere voor de backend API. Deze setup weerspiegelt de echte wereld waarin frontend- en backendservices onafhankelijk van elkaar werken.
### Serverconfiguratie
**Je ontwikkelomgeving zal bestaan uit:**
- **Frontend server**: Bedient je bankapp (meestal poort `3000`)
- **Backend API server**: Behandelt gegevensopslag en -opvraging (poort `5000`)
- **Beide servers** kunnen tegelijkertijd draaien zonder conflicten
**Test je API-verbinding:**
```bash
curl http://localhost:5000/api
# Expected response: "Bank API v1.0.0"
```
**Als je de API-versie ziet, kun je verder gaan!**
---
## Begrip van HTML-formulieren en -besturingselementen
HTML-formulieren zijn hoe gebruikers communiceren met je webapplicatie. Zie ze als het telegraafsysteem dat in de 19e eeuw verre plaatsen met elkaar verbond – ze vormen het communicatieprotocol tussen gebruikersintentie en applicatierespons. Wanneer ze zorgvuldig zijn ontworpen, vangen ze fouten op, begeleiden ze invoerformaten en bieden ze nuttige suggesties.
Moderne formulieren zijn aanzienlijk geavanceerder dan eenvoudige tekstinvoervelden. HTML5 introduceerde gespecialiseerde invoertypes die automatisch e-mailvalidatie, nummerformattering en datumselectie afhandelen. Deze verbeteringen komen zowel de toegankelijkheid als de mobiele gebruikerservaring ten goede.
### Essentiële Formulierelementen
**Bouwstenen die elk formulier nodig heeft:**
```html
```
**Wat deze code doet:**
- **Creëert** een formuliercontainer met een unieke identificatie
- **Specificeert** de HTTP-methode voor gegevensverzending
- **Associeert** labels met invoervelden voor toegankelijkheid
- **Definieert** een verzendknop om het formulier te verwerken
### Moderne Invoertypes en Attributen
| Invoertype | Doel | Voorbeeldgebruik |
|------------|------|------------------|
| `text` | Algemene tekstinvoer | `` |
| `email` | E-mailvalidatie | `` |
| `password` | Verborgen tekstinvoer | `` |
| `number` | Numerieke invoer | `` |
| `tel` | Telefoonnummers | `` |
> 💡 **Voordeel van moderne HTML5**: Het gebruik van specifieke invoertypes biedt automatische validatie, geschikte mobiele toetsenborden en betere ondersteuning voor toegankelijkheid zonder extra JavaScript!
### Knoptypes en Gedrag
```html
```
**Wat elk knoptype doet:**
- **Verzendknoppen**: Activeren formulierverzending en sturen gegevens naar het opgegeven eindpunt
- **Resetknoppen**: Herstellen alle formuliervelden naar hun oorspronkelijke staat
- **Normale knoppen**: Hebben geen standaardgedrag en vereisen aangepaste JavaScript voor functionaliteit
> ⚠️ **Belangrijke Opmerking**: Het ``-element is zelfsluitend en heeft geen sluitingstag nodig. Moderne best practice is om `` zonder schuine streep te schrijven.
### Je Loginformulier Bouwen
Laten we nu een praktisch loginformulier maken dat moderne HTML-formulierpraktijken demonstreert. We beginnen met een basisstructuur en verbeteren deze geleidelijk met toegankelijkheidsfuncties en validatie.
```html
Bank App
Login
```
**Wat hier gebeurt:**
- **Structureert** het formulier met semantische HTML5-elementen
- **Groepeert** gerelateerde elementen met `div`-containers en betekenisvolle klassen
- **Associeert** labels met invoervelden via de attributen `for` en `id`
- **Voegt** moderne attributen toe zoals `autocomplete` en `placeholder` voor betere gebruikerservaring
- **Voegt** `novalidate` toe om validatie met JavaScript te verwerken in plaats van standaard browserinstellingen
### Het Belang van Goede Labels
**Waarom labels belangrijk zijn voor moderne webontwikkeling:**
```mermaid
graph TD
A[Label Element] --> B[Screen Reader Support]
A --> C[Click Target Expansion]
A --> D[Form Validation]
A --> E[SEO Benefits]
B --> F[Accessible to all users]
C --> G[Better mobile experience]
D --> H[Clear error messaging]
E --> I[Better search ranking]
```
**Wat goede labels bereiken:**
- **Maakt** het mogelijk voor schermlezers om formuliervelden duidelijk aan te kondigen
- **Vergroot** het klikbare gebied (door op het label te klikken wordt het invoerveld gefocust)
- **Verbetert** de mobiele bruikbaarheid met grotere aanraakdoelen
- **Ondersteunt** formuliervalidatie met betekenisvolle foutmeldingen
- **Verbetert** SEO door semantische betekenis aan formulierelementen te geven
> 🎯 **Toegankelijkheidsdoel**: Elk formulierinvoerveld moet een bijbehorend label hebben. Deze eenvoudige praktijk maakt je formulieren bruikbaar voor iedereen, inclusief gebruikers met een beperking, en verbetert de ervaring voor alle gebruikers.
### Het Registratieformulier Maken
Het registratieformulier vereist meer gedetailleerde informatie om een volledig gebruikersaccount te maken. Laten we het bouwen met moderne HTML5-functies en verbeterde toegankelijkheid.
```html
Register
```
**In het bovenstaande hebben we:**
- **Georganiseerd** elk veld in container-divs voor betere styling en lay-out
- **Toegevoegd** geschikte `autocomplete`-attributen voor browser-autovulondersteuning
- **Inbegrepen** nuttige placeholder-tekst om gebruikersinvoer te begeleiden
- **Ingesteld** verstandige standaardwaarden met het `value`-attribuut
- **Toegepast** validatieattributen zoals `required`, `maxlength` en `min`
- **Gebruikt** `type="number"` voor het veld saldo met ondersteuning voor decimalen
### Verkenning van Invoertypes en Gedrag
**Moderne invoertypes bieden verbeterde functionaliteit:**
| Functie | Voordeel | Voorbeeld |
|---------|----------|-----------|
| `type="number"` | Numeriek toetsenbord op mobiel | Makkelijker saldo invoeren |
| `step="0.01"` | Controle over decimale precisie | Staat centen toe in valuta |
| `autocomplete` | Browser-autovul | Snellere formulierinvulling |
| `placeholder` | Contextuele hints | Begeleidt gebruikersverwachtingen |
> 🎯 **Toegankelijkheidsuitdaging**: Probeer de formulieren alleen met je toetsenbord te navigeren! Gebruik `Tab` om tussen velden te bewegen, `Spatie` om vakjes aan te vinken en `Enter` om te verzenden. Deze ervaring helpt je begrijpen hoe gebruikers van schermlezers met je formulieren omgaan.
## Begrip van Formulierverzendmethoden
Wanneer iemand je formulier invult en op verzenden klikt, moet die gegevens ergens naartoe – meestal naar een server die ze kan opslaan. Er zijn een paar verschillende manieren waarop dit kan gebeuren, en weten welke je moet gebruiken kan je later veel hoofdpijn besparen.
Laten we eens kijken wat er precies gebeurt wanneer iemand op die verzendknop klikt.
### Standaard Formuliergedrag
Laten we eerst observeren wat er gebeurt bij een basisformulierverzending:
**Test je huidige formulieren:**
1. Klik op de *Registreren*-knop in je formulier
2. Observeer de veranderingen in de adresbalk van je browser
3. Merk op hoe de pagina opnieuw laadt en gegevens in de URL verschijnen

### Vergelijking van HTTP-methoden
```mermaid
graph TD
A[Form Submission] --> B{HTTP Method}
B -->|GET| C[Data in URL]
B -->|POST| D[Data in Request Body]
C --> E[Visible in address bar]
C --> F[Limited data size]
C --> G[Bookmarkable]
D --> H[Hidden from URL]
D --> I[Large data capacity]
D --> J[More secure]
```
**Begrip van de verschillen:**
| Methode | Gebruikssituatie | Locatie gegevens | Beveiligingsniveau | Groottebeperking |
|---------|------------------|------------------|--------------------|------------------|
| `GET` | Zoekopdrachten, filters | URL-parameters | Laag (zichtbaar) | ~2000 tekens |
| `POST` | Gebruikersaccounts, gevoelige gegevens | Verzoekbody | Hoger (verborgen) | Geen praktische limiet |
**Begrip van de fundamentele verschillen:**
- **GET**: Voegt formuliergegevens toe aan de URL als queryparameters (geschikt voor zoekopdrachten)
- **POST**: Bevat gegevens in de verzoekbody (essentieel voor gevoelige informatie)
- **GET-beperkingen**: Groottebeperkingen, zichtbare gegevens, blijvende browsergeschiedenis
- **POST-voordelen**: Grote gegevenscapaciteit, privacybescherming, ondersteuning voor bestanduploads
> 💡 **Best Practice**: Gebruik `GET` voor zoekformulieren en filters (gegevensopvraging), gebruik `POST` voor gebruikersregistratie, login en gegevenscreatie.
### Configureren van Formulierverzending
Laten we je registratieformulier configureren om correct te communiceren met de backend API via de POST-methode:
```html
```
**Begrip van de verbeterde validatie:**
- **Combineert** verplichte veldindicatoren met behulpzame beschrijvingen
- **Bevat** `pattern`-attributen voor formaatvalidatie
- **Biedt** `title`-attributen voor toegankelijkheid en tooltips
- **Voegt** hulptekst toe om gebruikersinvoer te begeleiden
- **Gebruikt** semantische HTML-structuur voor betere toegankelijkheid
### Geavanceerde validatieregels
**Wat elke validatieregel bereikt:**
| Veld | Validatieregels | Voordeel voor gebruiker |
|------|-----------------|-------------------------|
| Gebruikersnaam | `required`, `minlength="3"`, `maxlength="20"`, `pattern="[a-zA-Z0-9_]+"` | Zorgt voor geldige, unieke identificatoren |
| Valuta | `required`, `maxlength="3"`, `pattern="[A-Z$€£¥₹]+"` | Accepteert gangbare valutatekens |
| Saldo | `min="0"`, `step="0.01"`, `type="number"` | Voorkomt negatieve saldi |
| Beschrijving | `maxlength="100"` | Redelijke lengtebeperkingen |
### Testen van validatiegedrag
**Probeer deze validatiescenario's:**
1. **Dien** het formulier in met lege verplichte velden
2. **Voer** een gebruikersnaam in die korter is dan 3 tekens
3. **Probeer** speciale tekens in het gebruikersnaamveld
4. **Voer** een negatief saldo in

**Wat je zult zien:**
- **Browser toont** native validatiemeldingen
- **Stijlwijzigingen** op basis van `:valid` en `:invalid` statussen
- **Formulierinzending** wordt voorkomen totdat alle validaties slagen
- **Focus verplaatst automatisch** naar het eerste ongeldige veld
### Client-side versus server-side validatie
```mermaid
graph LR
A[Client-Side Validation] --> B[Instant Feedback]
A --> C[Better UX]
A --> D[Reduced Server Load]
E[Server-Side Validation] --> F[Security]
E --> G[Data Integrity]
E --> H[Business Rules]
A -.-> I[Both Required]
E -.-> I
```
**Waarom je beide lagen nodig hebt:**
- **Client-side validatie**: Biedt directe feedback en verbetert de gebruikerservaring
- **Server-side validatie**: Zorgt voor beveiliging en behandelt complexe bedrijfsregels
- **Gecombineerde aanpak**: Creëert robuuste, gebruiksvriendelijke en veilige applicaties
- **Progressieve verbetering**: Werkt zelfs als JavaScript is uitgeschakeld
> 🛡️ **Beveiligingsherinnering**: Vertrouw nooit alleen op client-side validatie! Kwaadwillende gebruikers kunnen client-side controles omzeilen, dus server-side validatie is essentieel voor beveiliging en gegevensintegriteit.
---
---
## GitHub Copilot Agent Challenge 🚀
Gebruik de Agent-modus om de volgende uitdaging te voltooien:
**Beschrijving:** Verbeter het registratieformulier met uitgebreide client-side validatie en gebruikersfeedback. Deze uitdaging helpt je om formuliervalidatie, foutafhandeling en het verbeteren van de gebruikerservaring met interactieve feedback te oefenen.
**Opdracht:** Maak een compleet formuliervalidatiesysteem voor het registratieformulier dat het volgende bevat: 1) Real-time validatiefeedback voor elk veld terwijl de gebruiker typt, 2) Aangepaste validatiemeldingen die onder elk invoerveld verschijnen, 3) Een wachtwoordbevestigingsveld met overeenkomende validatie, 4) Visuele indicatoren (zoals groene vinkjes voor geldige velden en rode waarschuwingen voor ongeldige velden), 5) Een verzendknop die alleen wordt ingeschakeld wanneer alle validaties slagen. Gebruik HTML5-validatieattributen, CSS voor het stylen van de validatiestatussen en JavaScript voor het interactieve gedrag.
Lees meer over [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) hier.
## 🚀 Uitdaging
Toon een foutmelding in de HTML als de gebruiker al bestaat.
Hier is een voorbeeld van hoe de uiteindelijke inlogpagina eruit kan zien na wat styling:

## Quiz na de les
[Quiz na de les](https://ff-quizzes.netlify.app/web/quiz/44)
## Review & Zelfstudie
Ontwikkelaars zijn erg creatief geworden in hun inspanningen om formulieren te bouwen, vooral wat betreft validatiestrategieën. Leer over verschillende formulierstromen door te kijken op [CodePen](https://codepen.com); kun je enkele interessante en inspirerende formulieren vinden?
## Opdracht
[Style je bankapp](assignment.md)
---
**Disclaimer**:
Dit document is vertaald met behulp van de AI-vertalingsservice [Co-op Translator](https://github.com/Azure/co-op-translator). Hoewel we streven naar nauwkeurigheid, dient u zich ervan bewust te zijn dat geautomatiseerde vertalingen fouten of onnauwkeurigheden kunnen bevatten. Het originele document in de oorspronkelijke taal moet worden beschouwd als de gezaghebbende bron. Voor kritieke informatie wordt professionele menselijke vertaling aanbevolen. Wij zijn niet aansprakelijk voor eventuele misverstanden of verkeerde interpretaties die voortvloeien uit het gebruik van deze vertaling.