Skip to content

5. Beheer van de gebruikersinterface

5.1. Introduction

In de client-serverrelatie op het web stuurt de client informatie naar de server in de vorm van een reeks parameters [param1=val1&param2=val2&...]. In onze voorgaande voorbeelden hebben we deze reeks meestal handmatig samengesteld door URL's op te roepen in de vorm van [http://localhost/appli? param1=val1&param2=val2&...]. In de praktijk is de informatie die de client naar de server verzendt afkomstig van formulieren die de gebruiker heeft ingevuld. In dit hoofdstuk gaan we in op de opbouw daarvan. We introduceren ook de tool WebMatrix waarmee we de gebruikersinterfaces kunnen ontwerpen. De installatie van deze tool wordt beschreven in de bijlagen.

5.2. De taal HTML

5.2.1. Een voorbeeld

Laten we eens kijken naar het volgende voorbeeld, gemaakt met [Web Matrix], dat het volgende toont:

  • een tabel
  • een afbeelding
  • een link

Image

Laten we [WebMatrix] uitvoeren en vervolgens de optie [File/New File] kiezen:

Image

We kiezen ervoor om een pagina HTML aan te maken. De bovenstaande gegevens zullen een bestand [d:\data\devel\aspnet\chap4\exemple1\exemple1.htm] aanmaken. [WebMatrix] biedt twee mogelijkheden om dit bestand te bewerken: de modus [Design] en de modus [HTML]:

Image

In de modus [Design] kun je gebruikmaken van het componentenpalet HTML dat door [WebMatrix] wordt aangeboden:

Image

Om een element uit dit palet in te voegen, hoeft u er alleen maar op te dubbelklikken en het vervolgens in het venster [Design] te plaatsen. Met de modus [HTML] kunt u het document HTML samenstellen met behulp van een teksteditor. Hiervoor moet u de syntaxis van de taal HTML kennen. Op het tabblad [HTML] is een documentskelet gegenereerd:

Image

Het venster [HTML] is erg handig voor wie de taal HTML niet kent. Hij stelt in het venster [Design] zijn document op en controleert de gegenereerde HTML-code in het venster [HTML]. Zo krijgt hij geleidelijk aan de HTML onder de knie en kan hij vrij snel uitsluitend met de teksteditor werken, zonder de hulp van de modus [Design]. We gaan nu laten zien hoe we het document HTML kunnen opbouwen dat aan het begin van deze paragraaf is getoond. We werken in het venster [Design]. Allereerst voeren we direct de eerste tekstregel in:

Image

  • we voegen de component [Horizontal Rule] toe aan het componentenpalet:

Image

  • we voegen de component [Table] toe:

Image

  • we plaatsen de cursor in de derde rij van de tabel om deze te verwijderen met de optie [HTML/Edit Table/Delete Table Row]. Vervolgens voeren we de gewenste tekst in elke cel in:

Image

  • we plaatsen de cursor in een van de cellen van de tabel en bekijken de eigenschappen ervan. Het eigenschappenvenster wordt rechtsonder in de werkomgeving weergegeven:

Image

  • De cel wordt weergegeven door de tag HTML <TD>. We zien dus de eigenschappen van de tag <TD>. We richten onze aandacht op de tabel, die een object is dat de cel omvat. We klikken op de vervolgkeuzelijst (click to see parent HTML elements) hierboven om het object <TABLE> te selecteren:

Image

  • Het object <TABLE> heeft een eigenschap [border] die de breedte van de rand rond de cellen van de tabel bepaalt. Hier kiezen we voor border=1.

Image

  • we bewerken nu de attributen van het object <TD> van cel (1,2) om align=Center en width=200 (pixels) in te stellen. De tekst wordt in de cel gecentreerd (align=center) en de cel wordt 200 pixels breed. Om de wijziging te zien, moet u soms eerst het tabblad [HTML] selecteren en vervolgens teruggaan naar het tabblad [Design]:

Image

  • nu plaatsen we de tekst die voor de afbeelding staat:

Image

  • en vervolgens de afbeelding door te dubbelklikken op de component [image] in het palet:

Image

  • We selecteren de afbeelding om de eigenschappen ervan te bewerken:

Image

  • in het attribuut [src] voeren we de bestandsnaam in waarin de afbeelding is opgeslagen, in dit geval [univ01.gif]:

Image

  • we plaatsen de tekst die voor de link staat:

Image

  • we maken van de tekst [ici] een link naar de URL [http://istia.univ-angers.fr]. Hiervoor selecteren we de tekst en kiezen we vervolgens de optie [HTML/Insert Hyperlink]:

Image

  • we krijgen het volgende resultaat:

Image

  • we zijn er bijna. Laten we eens kijken naar de gegenereerde code HTML in het tabblad [HTML]:
<html>
<head>
</head>
<body>
    <p>
        Le langage HTML - 1 
    </p>
    <hr />
    <table border="1">
        <tbody>
            <tr>
                <td>
                    cellule(1,1)</td>
                <td align="middle" width="200">
                    cellule(1,2)</td>
                <td>
                    cellule(1,3)</td>
            </tr>
            <tr>
                <td>
                    cellule(2,1)</td>
                <td>
                    cellule(2,2)</td>
                <td>
                    cellule(2,3)</td>
            </tr>
        </tbody>
    </table>
    <p>
        Une image <img src="univ01.gif" /> 
    </p>
    <p>
        Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a>
    </p>
</body>
</html>

Er moeten nog enkele details worden geregeld. Allereerst willen we ons document een titel geven. In de modus [WebMatrix] is dit niet mogelijk. In het tabblad [HTML] vervangen we de reeks <head>..</head> door de volgende reeks:

<head>
    <title>HTML1</title>
</head>

Daarnaast willen we de tekst [Le langage HTML - 1] in grotere letters weergeven. Met de reeks <Hi>tekst</Hi> kan de tekstgrootte worden ingesteld, waarbij i varieert van 1 tot 6, van groot naar klein. Hier kiezen we voor H2. De reeks

    <p>
        Le langage HTML - 1 
    </p>

wordt:

<h2>Le langage HTML - 1</h2>

Het venster [Design] geeft onze wijzigingen weer:

Image

Nu hoeven we alleen nog maar te testen met behulp van de optie [View/Start] of [F5]. [WebMatrix] vraagt om enkele gegevens om de webserver [Cassini] te starten:

Image

We kunnen de voorgestelde standaardwaarden accepteren. De server [Cassini] wordt gestart en onze pagina wordt in een browser weergegeven:

Image

Uit nieuwsgierigheid kunnen we controleren met welke parameters [Cassini] is gestart:

Image

We hebben de basisprincipes van het bouwen van een HTML-pagina met [WebMatrix] besproken. De lezer wordt uitgenodigd om andere HTML-pagina’s te bouwen en telkens de gegenereerde HTML-code te controleren. Gaandeweg zal hij in staat zijn om een pagina te bouwen zonder de hulp van de modus [Design]. Een HTML-document heeft de volgende algemene vorm:

<html>
    <head>
        <title>Un titre</title>
        ...
    </head>
    <body attributs>
        ...
    </body>
</html>

Het gehele document wordt omgeven door de tags <html>...</html>. Het bestaat uit twee delen:

<head>...</head>: dit is het niet-weergegeven gedeelte van het document. Het geeft informatie aan de browser die het document gaat weergeven. Hierin staat vaak de tag <title>...</title>, die de tekst vastlegt die in de titelbalk van de browser wordt weergegeven. Er kunnen ook andere tags in staan, met name tags die de trefwoorden van het document definiëren; trefwoorden die vervolgens door zoekmachines worden gebruikt. In dit gedeelte kunnen ook scripts voorkomen, meestal geschreven in JavaScript of VBScript, die door de browser worden uitgevoerd.

<body attributen>...</body>: dit is het gedeelte dat door de browser wordt weergegeven. De tags HTML in dit gedeelte geven aan de browser aan hoe het document er visueel „uit moet zien”. Elke browser interpreteert deze tags op zijn eigen manier. Twee browsers kunnen hetzelfde webdocument dus op verschillende manieren weergeven. Dit is doorgaans een van de hoofdbrekers voor webontwerpers.

De code HTML van het vorige document was als volgt:

<html>
<head>
    <title>HTML1</title>
</head>
<body>
    <h2>Le langage HTML - 1 
    </h2>
    <hr />
    <table border="1">
        <tbody>
            <tr>
                <td>
                    cellule(1,1)</td>
                <td align="middle" width="200">
                    cellule(1,2)</td>
                <td>
                    cellule(1,3)</td>
            </tr>
            <tr>
                <td>
                    cellule(2,1)</td>
                <td>
                    cellule(2,2)</td>
                <td>
                    cellule(2,3)</td>
            </tr>
        </tbody>
    </table>
    <p>
        Une image <img src="univ01.gif" /> 
    </p>
    <p>
        Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a> 
    </p>
</body>
</html>
Element
tags en voorbeelden HTML
titre du document
<title>HTML1</title>
HTML1 verschijnt in de titelbalk van de browser die het document weergeeft
barre horizontale
<hr>: geeft een horizontale streep weer
tableau
<table-attributen>....</table>: om de tabel te definiëren
<tr attributen>...</tr>: om een rij te definiëren
<td attributen>...</td>: om een cel te definiëren
voorbeelden:
<table border="1">...</table>: het attribuut border bepaalt de dikte van de rand van de tabel
<td align="center" width="200">cel(1,2)</td>: definieert een cel waarvan de inhoud cellule(1,2) zal zijn. Deze inhoud wordt horizontaal gecentreerd (align="center"). De cel heeft een breedte van 200 pixels (width="200")
image
<img src="univ01.gif" />: definieert een afbeelding waarvan het bronbestand univ01.gif op de webserver staat (src="univ01.gif"). Deze link staat in een webdocument dat is gegenereerd met de URL http://localhost/exemple1.htm. De browser zal dus de pagina http://localhost/univ01.gif opvragen om de hier genoemde afbeelding op te halen.
lien
<a href="http://istia.univ-angers.fr">hier</a>: zorgt ervoor dat de tekst ici als link naar de URL URL http://istia.univ-angers.fr fungeert.

Uit dit eenvoudige voorbeeld blijkt dat de browser, om het volledige document op te bouwen, twee verzoeken naar de server moet sturen:

http://localhost/exemple1.htm om de broncode HTML van het document op te halen

http://localhost/univ01.gif om de afbeelding univ01.gif op te halen

5.2.2. Een formulier opbouwen

Een formulier HTML is bedoeld om de gebruiker een pagina te tonen waarop hij gegevens kan invoeren, vergelijkbaar met de invoerformulieren die men in Windows tegenkomt. Het invoerformulier wordt in de vorm van een document HTML naar de browser verzonden. De browser toont het formulier aan de gebruiker, die het invult en valideert met een knop die deze functie heeft. De browser stuurt vervolgens de ingevoerde waarden naar de server voor verwerking. We zullen zien dat niet het volledige formulier naar de server wordt teruggestuurd, maar alleen de ingevoerde waarden. Het volgende voorbeeld toont een webformulier dat eveneens met WebMatrix is gemaakt:

Image

De door [WebMatrix] gegenereerde code HTML is als volgt:


<html>
    <head>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
    </head>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr />
        <form name="formulaire" method="post">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <input type="radio" value="oui" name="rdMarie" />Oui 
                            <input type="radio" checked value="non" name="rdMarie" />Non
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Cases à cocher
                    </td>
                    <td>
                        <p align="center">
                            <input type="checkbox" value="un" name="C1" />1
                            <input type="checkbox" checked value="deux" name="C2" />2
                            <input type="checkbox" value="trois" name="C3" />3
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Champ de saisie</td>
                    <td>
                        <p align="center">
                            <input type="text" maxlength="30" value="qqs mots" name="txtSaisie" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Mot de passe</td>
                    <td>
                        <p align="center">
                            <input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Boîte de saisie</td>
                    <td>
                        <p align="center">
                        </p>
                        <textarea name="areaSaisie">ligne1
ligne2</textarea>
                    </td>
                </tr>
                <tr>
                    <td>
                        ComboBox</td>
                    <td>
                        <p align="center">
                        </p>
                        <select name="cmbValeurs">
                            <option value="1">choix1</option>
                            <option value="2" selected>choix2</option>
                            <option value="3">choix3</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix simple</td>
                    <td>
                        <p align="center">
                        </p>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix multiple</td>
                    <td>
                        <p align="center">
                        </p>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton simple</td>
                    <td>
                        <p align="center">
                            <input onclick="effacer()" type="button" value="Effacer" name="btnEffacer" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton submit</td>
                    <td>
                        <p align="center">
                            <input type="submit" value="Envoyer" name="btnEnvoyer" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton reset</td>
                    <td>
                        <p align="center">
                            <input type="reset" value="Rétablir" name="btnRetablir" runat="server" />
                        </p>
                    </td>
                </tr>
            </table>
            <input type="hidden" name="secret" value="uneValeur" />
        </form>
    </body>
</html>

De koppeling tussen visuele controle <--> tag HTML is als volgt:

Controle
tag HTML
formulaire
<form name="formulier" method="post">
champ de saisie
<input type="text" maxlength="30" value="een paar woorden" name="txtSaisie" />
champ de saisie cachée
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
champ de saisie multilignes
<textarea name="areaSaisie">regel1
regel2</textarea>
boutons radio
<input type="radio" value="ja" name="rdMarie" />Ja
<input type="radio" checked value="nee" name="rdMarie" />Nee
cases à cocher
<input type="checkbox" value="één" name="C1" />1
<input type="checkbox" checked value="twee" name="C2" />2
<input type="checkbox" value="drie" name="C3" />3
Combo
<select name="cmbValeurs">
<option value="1">keuze1</option>
<option value="2" selected>keuze 2</option>
<option value="3">keuze3</option>
</select>
liste à sélection unique
<select size="3" name="lstSimple">
<option value="1" selected>lijst1</option>
<option value="2">lijst2</option>
<option value="3">lijst3</option>
<option value="4">lijst4</option>
<option value="5">lijst5</option>
</select>
liste à sélection multiple
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>
champ caché
<input type="hidden" name="secret" value="uneValeur" />
bouton de type submit
<input type="submit" value="Verzenden" name="btnEnvoyer" />
bouton de type reset
<input type="reset" value="Resetten" name="btnRetablir" runat="server" />
bouton de type button
<input onclick="effacer()" type="button" value="Wissen" name="btnEffacer" />

Laten we deze verschillende besturingselementen eens bekijken.

5.2.2.1. Het formulier

formulaire
<form name="formulier" method="post">
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
name="frmexemple": naam van het formulier
method="..." : methode die door de browser wordt gebruikt om de in het formulier verzamelde waarden naar de webserver te verzenden
action="..." : URL waarnaar de in het formulier verzamelde waarden worden verzonden.
Een webformulier wordt omgeven door de <form>...</form>-tags. Het formulier kan een naam hebben (name="xx"). Dit geldt voor alle besturingselementen die in een formulier voorkomen. Deze naam is nuttig als het webdocument scripts bevat die naar elementen van het formulier moeten verwijzen. Het doel van een formulier is om informatie te verzamelen die de gebruiker via het toetsenbord of de muis invoert, en deze naar een URL van de webserver te verzenden. Welke? Die waarnaar wordt verwezen in het attribuut action="URL". Als dit attribuut ontbreekt, wordt de informatie verzonden naar de URL van het document waarin het formulier zich bevindt. Hoe zorgt een webclient ervoor dat informatie (die in het formulier staat) naar een webserver wordt verzonden? Dat hebben we in detail besproken. Er kunnen twee verschillende methoden worden gebruikt, namelijk POST en GET. Het attribuut method="méthode", met als methode GET of POST, van de tag <form> geeft aan de browser aan welke methode moet worden gebruikt om de in het formulier verzamelde informatie te verzenden naar de URL die is opgegeven door het attribuut action="URL". Wanneer het attribuut method niet is opgegeven, wordt standaard de methode GET gebruikt.

5.2.2.2. Invoerveld

Image

champ de saisie
<input type="text" maxlength="30" value="een paar woorden" name="txtSaisie" />
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
balise HTML
<input type="..." name="..." size=".." value="..">
De input-tag bestaat voor verschillende besturingselementen. Het is het attribuut type waarmee deze verschillende besturingselementen van elkaar kunnen worden onderscheiden.
attributs
type="text": geeft aan dat het een invoerveld is
type="password": de tekens in het invoerveld worden vervangen door *-tekens. Dit is het enige verschil met het normale invoerveld. Dit type besturingselement is geschikt voor het invoeren van wachtwoorden.
size="12": aantal zichtbare tekens in het veld – dit belet niet dat er meer tekens worden ingevoerd
maxlength="30": stelt het maximale aantal tekens vast op 30 – de browser zorgt ervoor dat aan dit attribuut wordt voldaan
name="txtSaisie": naam van het invoerveld
value="enkele woorden": tekst die in het invoerveld wordt weergegeven.

5.2.2.3. Invoerveld met meerdere regels

Image

champ de saisie multilignes
<textarea name="areaSaisie">regel1
regel2</textarea>
balise HTML
<textarea ...>tekst</textarea>
toont een invoerveld voor meerdere regels met aanvankelijk tekst erin
attributs
rows="2": aantal regels
cols="'20": aantal kolommen
name="areaSaisie": naam van het besturingselement

5.2.2.4. Keuzerondjes

Image

boutons radio
<input type="radio" value="ja" name="rdMarie" />Ja
<input type="radio" checked value="nee" name="rdMarie" />Nee
balise HTML
<input type="radio" attribuut2="waarde2" ..../>tekst
toont een keuzerondje met tekst ernaast.
attributs
name="rdMarie": naam van het besturingselement. Keuzerondjes met dezelfde naam vormen een groep die elkaar uitsluiten: er kan slechts één worden aangevinkt.
value="waarde": de waarde die aan de keuzeknop wordt toegewezen. Deze waarde mag niet worden verward met de tekst die naast de keuzeknop wordt weergegeven. Die tekst is uitsluitend bedoeld voor weergave.
checked: als dit trefwoord aanwezig is, is het keuzerondje aangevinkt, anders niet.

5.2.2.5. Selectievakjes

cases à cocher
<input type="checkbox" value="één" name="C1" />1
<input type="checkbox" checked value="twee" name="C2" />2
<input type="checkbox" value="drie" name="C3" />3

Image

balise HTML
<input type="checkbox" attribuut2="waarde2" ..../>tekst
toont een selectievakje met tekst ernaast.
attributs
name="C1": naam van het besturingselement. Selectievakjes kunnen al dan niet dezelfde naam hebben. Selectievakjes met dezelfde naam vormen een groep van aan elkaar gekoppelde selectievakjes.
value="waarde": waarde die aan het selectievakje wordt toegewezen. Deze waarde mag niet worden verward met de tekst die naast het selectievakje wordt weergegeven. Deze tekst is uitsluitend bedoeld voor weergave.
checked: als dit trefwoord aanwezig is, is het keuzerondje aangevinkt, anders niet.

5.2.2.6. Keuzelijst (combo)

Combo
<select name="cmbValeurs">
<option value="1">keuze1</option>
<option value="2" selected>keuze2</option>
<option value="3">keuze 3</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected="selected"] [value="valeur"]>tekst</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option> staan
attributs
name="cmbValeurs": naam van het besturingselement.
size="1": aantal zichtbare lijstitems. size="1" maakt van de lijst het equivalent van een combobox. Dit is de standaardwaarde als het attribuut [size] ontbreekt.
selected="selected": als dit trefwoord bij een lijstitem aanwezig is, wordt dit item in de lijst als geselecteerd weergegeven. In ons voorbeeld hierboven wordt het lijstitem choix2 weergegeven als het geselecteerde item in de keuzelijst wanneer deze voor het eerst wordt weergegeven.
value="waarde": stelt de waarde in die naar de server moet worden verzonden als het item wordt geselecteerd. Als dit attribuut ontbreekt, wordt de tekst die aan het keuzemenu is gekoppeld naar de server verzonden.

5.2.2.7. Lijst met één selectie

liste à sélection unique
<select size="3" name="lstSimple">
<option value="1" selected>lijst1</option>
<option value="2">lijst2</option>
<option value="3">lijst3</option>
<option value="4">lijst4</option>
<option value="5">lijst5</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected] [value="valeur"]>...</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option> staan
attributs
dezelfde als voor de vervolgkeuzelijst die slechts één item weergeeft. Dit besturingselement verschilt alleen van de vorige vervolgkeuzelijst door het attribuut size>1.

5.2.2.8. Lijst met meerdere selecties

liste à sélection multiple
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>

Image

balise HTML
<select size=".." name=".." multiple>
<option [selected] ] [value="valeur"]>...</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option>
attributs
multiple: maakt het mogelijk meerdere elementen in de lijst te selecteren. In het bovenstaande voorbeeld zijn de elementen liste1 en liste3 beide geselecteerd.

5.2.2.9. Knop van het type button

bouton de type button
<input onclick="effacer()" type="button" value="Wissen" name="btnEffacer" />

Image

balise HTML
<input type="button" value="..." name="..." onclick="effacer()" ....>
attributs
type="button": definieert een knop. Er zijn nog twee andere soorten knoppen: de typen submit en reset.
value="Wissen": de tekst die op de knop wordt weergegeven
onclick="functie()": hiermee kunt u een functie definiëren die moet worden uitgevoerd wanneer de gebruiker op de knop klikt. Deze functie maakt deel uit van de scripts die in het weergegeven webdocument zijn gedefinieerd. De bovenstaande syntaxis is een javascript-syntaxis. Als de scripts in VBScript zijn geschreven, moet u onclick="functie" schrijven zonder de haakjes. De syntaxis blijft hetzelfde als er parameters aan de functie moeten worden doorgegeven: onclick="functie(val1, val2,...)"
In ons voorbeeld roept een klik op de knop Effacer de volgende JavaScript-functie effacer aan:

        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
De functie effacer geeft een melding weer:

5.2.2.10. Submit-knop

bouton de type submit
<input type="submit" value="Verzenden" name="btnEnvoyer" />

Image

balise HTML
<input type="submit" value="Verzenden" name="btnEnvoyer">
attributs
type="submit": definieert de knop als een knop om de gegevens van het formulier naar de webserver te verzenden. Wanneer de gebruiker op deze knop klikt, verzendt de browser de gegevens van het formulier naar de URL die is gedefinieerd in het action-attribuut van de <form>-tag, volgens de methode die is gedefinieerd door het method-attribuut van diezelfde tag.
value="Verzenden": de tekst die op de knop wordt weergegeven

5.2.2.11. Resetknop

bouton de type reset
<input type="reset" value="Resetten" name="btnRetablir" runat="server" />

Image

balise HTML
<input type="reset" value="Terugzetten" name=" btnRetablir ">
attributs
type="reset": definieert de knop als een knop om het formulier te resetten. Wanneer de gebruiker op deze knop klikt, zet de browser het formulier terug in de staat waarin het werd ontvangen.
value="Resetten" : de tekst die op de knop wordt weergegeven

5.2.2.12. Verborgen veld

champ caché
<input type="hidden" name="secret" value="uneValeur" />
balise HTML
<input type="hidden" name="..." value="...">
attributs
type="hidden": geeft aan dat het een verborgen veld is. Een verborgen veld maakt deel uit van het formulier, maar wordt niet aan de gebruiker getoond. Als de gebruiker echter aan zijn browser zou vragen om de broncode weer te geven, zou hij de tag <input type="hidden" value="..."> zien en dus ook de waarde van het verborgen veld.
value="eenWaarde": waarde van het verborgen veld.
Wat is het nut van het verborgen veld? Hiermee kan de webserver informatie bijhouden tijdens de verzoeken van een klant. Laten we eens kijken naar een online winkelapplicatie. De klant koopt een eerste artikel art1 in een hoeveelheid q1 op een eerste pagina van een catalogus en gaat vervolgens naar een nieuwe pagina van de catalogus. Om te onthouden dat de klant q1 artikelen art1 heeft gekocht, kan de server deze twee gegevens in een verborgen veld van het webformulier op de nieuwe pagina plaatsen. Op deze nieuwe pagina koopt de klant de artikelen q2 en art2. Wanneer de gegevens van dit tweede formulier naar de server worden verzonden (submit), ontvangt de server niet alleen de informatie (q2,art2), maar ook (q1,art1), die eveneens deel uitmaakt van het formulier als een verborgen veld dat niet door de gebruiker kan worden gewijzigd. De webserver zal vervolgens de gegevens (q1,art1) en (q2,art2) in een nieuw verborgen veld plaatsen en een nieuwe cataloguspagina verzenden. En zo verder.

5.3. Verzending van formulierwaarden naar een webserver door een browser

Uit het vorige hoofdstuk weten we al hoe een client informatie naar de server verstuurt. Dit gebeurt via:

  • een verzoek met de URL HTTP GET?param1=va1&param2=val2&....
  • een verzoek HTT POST url gevolgd door een document met de parameterreeks param1=va1&param2=val2&....

De browser zal een van deze twee methoden gebruiken, afhankelijk van of het attribuut [method] van de tag [form] de waarde GET of POST heeft. Dat gaan we nu laten zien. De pagina die we eerder hebben bekeken, is een statische pagina. Om toegang te krijgen tot de HTTP-headers die worden verzonden door de browser die dit document opvraagt, zetten we deze om in een dynamische pagina voor een .NET-webserver (IIS of Cassini). De eerdere statische code wordt in een bestand [formulaire_get.aspx] geplaatst en de inhoud ervan is als volgt:


<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
    <head>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
    </head>
    <body>
.....
    </body>
</html>

De bovenstaande presentatiepagina hoort bij de controller [formulaire_get.aspx.vb]:


Public Class formulaire_get
    Inherits System.Web.UI.Page

    Private Sub Page_Init(ByVal Sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init
        ' de huidige aanvraag wordt opgeslagen in request.txt in de paginamap
        Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
        Me.Request.SaveAs(requestFileName, True)
    End Sub
End Class

Bij elke oproep van het document [formulaire_get.aspx] wordt de aanvraag van de klant door de procedure Page_Init opgeslagen in een bestand [request.txt]. We zijn deze werkwijze al eerder tegengekomen, dus zullen we niet verder ingaan op de controller.

5.3.1. Methode GET

Laten we een eerste test uitvoeren, waarbij in de code HTML van het document de tag FORM als volgt is gedefinieerd:


        <form name="formulaire" method="get">

We plaatsen de bestanden [formulaire_get.aspx] en [formulaire_get.aspx.vb] in een map <application-path> en starten de Cassini-server met de parameters (<application-path>,/form2). We roepen de URL http://localhost/form2/formulaire_get.aspx op:

Image

De browser heeft zojuist een verzoek verzonden en we weten dat dit is opgeslagen in het bestand [request.txt]. Laten we de inhoud ervan eens bekijken:

GET /form2/formulaire_get.aspx HTTP/1.1
Cache-Control: max-age=0
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

De browser heeft een verzoek HTTP GET gebruikt om de URL [http://localhost/form2/formulaire_get.aspx] op te vragen. Dit is altijd het geval wanneer de URL door de gebruiker wordt opgegeven. We vullen het formulier als volgt in:

Image

We gebruiken de bovenstaande knop [Envoyer]. De code HTML is als volgt:

<form method="get">
    ...
    <input type="submit" value="Envoyer">
    ...
</form>

Bij het klikken op een knop van het type [Submit], stuurt de browser de formulierparameters (tag <form>) naar de URL die is opgegeven in het attribuut [action] van de tag <form action="URL">, indien deze bestaat. Als dit attribuut niet bestaat, worden de formulierparameters verzonden naar de URL die het formulier heeft geleverd. Dat is hier het geval. De knop [Envoyer] zou dus moeten leiden tot een verzoek van de browser aan de URL [http://localhost/form2/formulaire_get.aspx], waarbij de formulierparameters worden doorgegeven. Aangezien de pagina [formulaire_get.aspx] het ontvangen verzoek onthoudt, zouden we moeten weten hoe de client deze parameters heeft doorgegeven. Laten we het eens proberen. We klikken op de knop [Envoyer]. We ontvangen het volgende antwoord van de browser:

Image

Dit is de oorspronkelijke pagina, maar we zien dat de waarde URL in het veld [Adresse] van de browser is gewijzigd. Deze is nu als volgt:

http://localhost/form2/formulaire_get.aspx?rdMarie=ja&C1=één&C2=twee&txtSaisie=programmering+asp.net&txtMdp=unMotDePasse&areaSaisie=de+basisprincipes+van+de%0D%0Awebprogrammering%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Verzenden&secret=uneValeur

We zien dat de keuzes die in het formulier zijn gemaakt, terug te vinden zijn in de URL. Laten we eens kijken naar de inhoud van het bestand [request.txt], waarin het verzoek van de klant is opgeslagen:

GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_get.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

We zien een verzoek HTTP dat sterk lijkt op het verzoek dat de browser aanvankelijk had gedaan toen hij het document opvroeg zonder parameters door te geven. Er zijn twee verschillen:

GET URL HTTP/1.1
De formulierparameters zijn achter de URL van het document toegevoegd in de vorm ?param1=val1&param2=val2&...
Referer
De klant geeft met deze header HTTP de URL aan van het document dat hij aan het bekijken was toen hij de aanvraag indiende

Laten we eens nader bekijken hoe de parameters zijn doorgegeven in de opdracht GET URL?param1=waarde1&param2=waarde2&... HTTP/1.1, waarbij de parami de namen zijn van de besturingselementen van het webformulier en de valeuri de waarden die eraan zijn gekoppeld. Hieronder presenteren we een tabel met drie kolommen:

  • kolom 1: bevat de definitie van een besturingselement HTML uit het voorbeeld
  • kolom 2: toont hoe dit besturingselement in een browser wordt weergegeven
  • kolom 3: toont de waarde die door de browser naar de server wordt verzonden voor het besturingselement uit kolom 1, in de vorm zoals deze voorkomt in de verzoek-URL GET uit het voorbeeld
besturingselement HTML
weergave vóór validatie
teruggestuurde waarde(n)
<input type="radio" value="ja" name="rdMarie" />Ja
<input type="radio" checked
value="nee" name="rdMarie" />Nee
rdMarie=ja
- de waarde van het attribuut value van de knop
die door de gebruiker is aangevinkt.
<input type="checkbox"
value="een" name="C1" />1
<input type="checkbox"
checked value="twee" name="C2" />2
<input type="checkbox"
value="drie" name="C3" />3
C1=één
C2=twee
- waarden van de attributen value van de selectievakjes
die door de gebruiker zijn aangevinkt
<input type="text" maxlength="30" value="qqs
woorden" name="txtSaisie" />
txtInvoer=programmering+asp.net
- tekst die door de gebruiker in het
. Spaties zijn vervangen
door het teken +
<input type="password"
maxlength="12" size="12"
value="eenWachtwoord"
name="txtMdp" />
txtMdp=ditisgeheim
- tekst die door de gebruiker in het
. De daadwerkelijk ingevoerde tekst was
"ditisgeheim". Het laatste teken is
verloren gegaan omdat het attribuut
maxlength="12" het aantal
tekens tot 12.
<textarea name="areaSaisie">
regel1
regel2</textarea>
invoergebied=de+basisprincipes+van+
de%0D%0A
webprogrammering+
- tekst die door de gebruiker in het
. %OD%OA is het teken voor
regeleinde. De spaties zijn
vervangen door het teken +
<select name="cmbValeurs">
<option value="1">keuze1
</option>
<option value="2" selected>keuze2
</option>
<option value="3">keuze 3
</option>
</select>
cmbWaarden=3
- door de gebruiker gekozen waarde in de
lijst met één selectie
<select size="3"
name="lstSimple">
<option value="1"
selected>lijst1</option>
<option value="2">lijst2
</option>
<option value="3">lijst3
</option>
<option value="4">lijst4
</option>
<option value="5">lijst5
</option>
</select>
lstSimple=3
- door de gebruiker gekozen waarde in de
lijst met één selectie
<select multiple size="3"
name="lstMultiple">
<option value="1" selected>multiple1
</option>
<option value="2">multiple2
</option>
<option value="3" selected>multiple3
</option>
<option value="4">multiple4
</option>
<option value="5">multiple5
</option>
</select>
lstMultiple=2
lstMultiple=4
- door de gebruiker geselecteerde waarden in de
lijst met meerdere selectiemogelijkheden
<input type="submit"
value="Verzenden"
name="btnVerzenden" />
btnEnvoyer=Verzenden
- naam en attribuut value van de knop die
is gebruikt om de gegevens van het formulier
naar de server
<input type="hidden"
name="secret"
value="eenWaarde" />
 
secret=eenWaarde
- attribuut value van het verborgen veld

Je kunt je afvragen wat de server heeft gedaan met de parameters die we hem hebben doorgegeven. Eigenlijk niets. Bij ontvangst van het commando

GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1

De webserver heeft de parameters doorgegeven aan URL naar het document [http://localhost/form2/formulaire_get.aspx], c.a.d, naar het document dat we aanvankelijk hadden opgesteld. We hebben geen code geschreven om de parameters die de client ons stuurt op te halen en te verwerken. Het is dus alsof het verzoek van de client simpelweg luidt:

GET http://localhost/form2/formulaire_get.aspx

Om deze reden hebben we, als reactie op onze knop [Envoyer], dezelfde pagina ontvangen als die we aanvankelijk kregen bij het opvragen van de URL en [http://localhost/form2/formulaire_get.aspx] zonder parameters.

5.3.2. Methode POST

Het document HTML is nu zo geconfigureerd dat de browser de methode POST gebruikt om de formulierwaarden naar de webserver te verzenden. Hiervoor kopiëren we het bestand [formulaire_get.aspx] naar [formulaire_post.aspx] en wijzigen we alleen de tag <form> in [formulaire_post.aspx]:


<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
    <head>
        ...
    </head>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr />
        <form name="formulaire" method="post">
            <table border="1">

Het is niet nodig om de controller [formulaire_get.aspx.vb] te vervangen, dus laten we deze in de huidige staat. We vragen het nieuwe document aan via de URL [http://localhost/form2/formulaire_post.aspx], vullen het formulier in zoals bij de methode GET en verzenden de parameters naar de server met de knop [Envoyer]. We ontvangen de volgende responspagina van de server:

Image

We krijgen dus hetzelfde resultaat als bij de methoden GET en c.a.d: de startpagina. Er is één verschil op te merken: in het veld [Adresse] van de browser verschijnen de doorgegeven parameters niet. Laten we nu eens kijken naar het verzoek dat door de client is verzonden en dat is opgeslagen in het bestand [request.txt]:

POST /form2/formulaire_post.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Content-Length: 222
Content-Type: application/x-www-form-urlencoded
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0,1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_post.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=3&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur

Er verschijnen nieuwe gegevens in de query HTTP van de klant:

POST URL HTTP/1.1
de query GET is vervangen door een query POST. De parameters staan niet meer in de eerste regel van de query. We zien dat ze nu na een lege regel achter de query HTTP staan. Hun codering is identiek aan die in de query GET.
Content-Length
aantal „verzonden” tekens, c.a.d. Het aantal tekens dat de webserver moet lezen na ontvangst van de headers HTTP om het document op te halen dat de client naar hem verstuurt. Het document in kwestie is hier de lijst met waarden van het formulier.
Content-type
geeft het type document aan dat de client na de headers HTTP zal verzenden. Het type [application/x-www-form-urlencoded] geeft aan dat het een document is dat formulierwaarden bevat.

Er zijn twee methoden om gegevens naar een webserver te verzenden: GET en POST. Is de ene methode beter dan de andere? We hebben gezien dat als de waarden van een formulier door de browser werden verzonden met de methode GET, de browser in het veld Adresse de gevraagde URL weergeeft in de vorm URL?param1=val1&param2=val2&.... Dit kan als een voordeel of als een nadeel worden gezien:

  • een voordeel als men de gebruiker de mogelijkheid wil bieden om deze geconfigureerde URL in zijn favoriete links op te nemen
  • een nadeel als men niet wil dat de gebruiker toegang heeft tot bepaalde informatie in het formulier, zoals bijvoorbeeld verborgen velden

Vanaf nu zullen we in onze formulieren vrijwel uitsluitend de methode POST gebruiken.

5.4. Server-side verwerking van formulierwaarden

5.4.1. Overzicht van het voorbeeld

Nu we het verband hebben gelegd tussen de tag HTML <form method="GET/POST" ...> en de manier waarop de browser de formulierwaarden verstuurt, weten we hoe we deze aan de serverzijde kunnen ophalen. Het antwoord vonden we in het vorige hoofdstuk:

  • als de methode van de tag <form> GET is, worden de waarden van de parameters opgehaald uit de verzameling [Request.QueryString]
  • als de methode van de tag <form> POST is, worden de waarden van de „gepostte” parameters opgehaald uit de verzameling [Request.Form]. Hier moet een verduidelijking worden gegeven. De tag <form> kan met behulp van het attribuut [action] de doel-URL van de GET of de POST specificeren. Deze URL kan heel goed worden geconfigureerd, of er nu sprake is van een GET of een POST, in de vorm action="url?param1=val1&param2=val2&..". Deze parameters worden vervolgens toegevoegd aan de parameters die tussen de tags <form> en </form> staan en die via een GET of een POST naar de server worden verzonden. Omdat ze deel uitmaken van de doel-URL, worden ze opgehaald in de verzameling [Request.QueryString], ongeacht of het om een GET of een POST gaat.

We schrijven nu een applicatie MVC met twee weergaven:

  • de eerste weergave is het voorgaande formulier. We noemen deze [vue_formulaire].
  • De tweede weergave is een informatiepagina met een overzicht van de waarden die op de eerste pagina zijn ingevoerd. Via een link kan men terugkeren naar het formulier. We noemen deze weergave [vue_confirmation].

De weergave [vue_formulaire] wordt naar de gebruiker gestuurd, die deze invult en valideert. Vlak voor de validatie zou deze er als volgt uit kunnen zien:

Image

De gebruiker gebruikt de knop [Envoyer] om zijn invoer te valideren. Hij ontvangt vervolgens de volgende weergave [vue_validation]:

Image

5.4.2. De controller van de applicatie

In het vorige hoofdstuk hebben we gezien dat we de rol van controller voor een applicatie MVC kunnen toewijzen aan het bestand [global.asax], waar alle verzoeken van de clients doorheen lopen. We hebben al een op deze manier opgebouwde applicatie MVC gepresenteerd en volgen hier het toen gepresenteerde ontwikkelingsmodel. Het bestand [global.asax] ziet er als volgt uit:

<%@ Application src="Global.asax.vb" Inherits="Global" %>

Het bestaat uit één enkele regel die verwijst naar de controller in het bestand [global.asax.vb]:


Imports System
Imports System.Web
Imports System.Web.SessionState

Public Class Global
    Inherits System.Web.HttpApplication

    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' de uit te voeren actie wordt opgehaald
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' de actie wordt uitgevoerd
        Select Case action
            Case "init"
                Server.Transfer("formulaire.aspx", False)
            Case "validation"
                Server.Transfer("validation.aspx", True)
            Case Else
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub
End Class

Het principe van de controller is als volgt:

  • de controller verwacht in de doel-URL een reeks parameters die de parameter [action] bevat. Als deze ontbreekt, wordt er gehandeld alsof [action=init] in de reeks parameters stond.
  • Er worden slechts twee acties herkend:
    • init: het vooraf ingevulde formulier wordt aan de klant geleverd
    • validation: de klant krijgt de pagina te zien waarop zijn invoer wordt bevestigd
  • Als de actie niet een van de voorgaande is, wordt er gehandeld alsof [action=init] was opgegeven. Er zou ook een foutpagina kunnen worden weergegeven.

5.4.3. Verwerking van de actie init

Wanneer de controller de actie „init“ verwerkt, moet hij een vooraf ingevuld formulier genereren. Het is de taak van de pagina [formulaire.aspx] om dit te doen. De code ervan is als volgt:


<HTML>
    <HEAD>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        function raz(liste){
            liste.selectedIndex=-1
        }
        </script>
    </HEAD>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr>
        <form name="formulaire" method="post" action="?action=validation">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <input type="radio" value="oui" name="rdMarie">Oui <input type="radio" checked value="non" name="rdMarie">Non
                        </p>
                    </td>
                </tr>
....
                    <td>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
....
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>
...

            </table>
            <input type="hidden" name="secret" value="uneValeur">
        </form>
    </body>
</HTML>

We zien hier de code HTML uit het eerder besproken formulier terug, op enkele verschillen na. De code van de tag <form> is gewijzigd:


        <form name="formulaire" method="post" action="?action=validation">
  • post: de waarden die door de gebruiker zijn ingevoerd en vervolgens naar de server worden verzonden wanneer de knop van het type [submit] wordt gebruikt, zullen worden verzonden via de methode HTTP POST
  • actie: de syntaxis action="url" wordt gebruikt om de URL aan te geven waarnaar de formulierwaarden moeten worden verzonden. Deze URL kan een reeks parameters bevatten in de vorm param1=val1&param2=val2&... Dat is hier het geval: we geven de parameter [action=validation] door om de controller aan te geven welke actie hij moet ondernemen. Merk op dat deze reeks parameters niet wordt voorafgegaan door een webadres. De browser zal de formulierparameters dan verzenden naar het adres dat dit formulier heeft aangeleverd. In ons hierboven gepresenteerde voorbeeld is dit adres [http://localhost/mvcform1]. De browser zal dus een verzoek [POST /mvcform1?action=validation] sturen naar de machine [localhost].

Er zijn knoppen toegevoegd waarmee de gebruiker de selectie van de elementen in de lijsten [lstSimple] en [lstMultiple] kan opheffen:

Image

Dit resulteert in de volgende code HTML:


                    <td>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
....
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>

Als je op een knop [Raz] klikt, wordt elk element uit de lijst waarmee deze is gekoppeld, gedeselecteerd. Laten we de lijst [lstMultiple] als voorbeeld nemen. Een klik op de bijbehorende knop [Raz] zorgt ervoor dat de JavaScript-functie [raz(lstMultiple)] wordt uitgevoerd. Ter herinnering: de JavaScript-code van een HTML-document dat door een browser wordt weergegeven, wordt door diezelfde browser uitgevoerd en niet door de server. JavaScript is een zeer veelzijdige taal waarmee pagina’s een dynamisch karakter kunnen krijgen zonder tussenkomst van de server. De functie [raz] is als volgt:

        function raz(liste){
            liste.selectedIndex=-1
        }

Deze functie ontvangt een parameter die een JavaScript-object is dat een lijst HTML vertegenwoordigt. Dit object heeft eigenschappen en methoden. Een van deze eigenschappen is [selectedIndex], waarvan de waarde het nummer is van de eerste geselecteerde optie in de lijst HTML. Als er geen is geselecteerd, is de waarde van deze eigenschap -1. Omgekeerd komt het toekennen van een waarde aan deze eigenschap neer op het selecteren van een nieuw element in de lijst HTML, en het toekennen van de waarde -1 komt neer op het niet selecteren van enig element. Dat is wat hier gebeurt.

Tot slot valt op dat de presentatiecode [formulaire.aspx] niet vergezeld gaat van een controller [formulaire.aspx.vb]. Er is namelijk geen enkel dynamisch onderdeel dat door de server wordt gegenereerd in het document HTML, dus is er geen behoefte aan een controller.

5.4.4. Verwerking van de validatieactie

Wanneer de controller de actie „validatie“ verwerkt, moet deze een pagina genereren met een overzicht van de door de gebruiker ingevoerde waarden. Het is de taak van de pagina [validation.aspx] om dit te doen. Visueel ziet de pagina er als volgt uit:

Image

De code HTML is als volgt:


<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
    <HEAD>
        <title>validation</title>
    </HEAD>
    <body>
        <P>Valeurs saisies</P>
        <HR width="100%" SIZE="1">
        <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
            <TR>
                <TD width="84">rdMarie</TD>
                <TD><% =rdMarie%></TD>
            </TR>
            <TR>
                <TD width="84">C1</TD>
                <TD><%=C1%></TD>
            </TR>
            <TR>
                <TD width="84">C2</TD>
                <TD><%=C2%></TD>
            </TR>
            <TR>
                <TD width="84">C3</TD>
                <TD><%=C3%></TD>
            </TR>
            <TR>
                <TD width="84">txtSaisie</TD>
                <TD><%=txtSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">txtMdp</TD>
                <TD><%=txtMdp%></TD>
            </TR>
            <TR>
                <TD width="84">areaSaisie</TD>
                <TD><%=areaSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">cmbValeurs</TD>
                <TD><%=cmbValeurs%></TD>
            </TR>
            <TR>
                <TD width="84">lstSimple</TD>
                <TD><%=lstSimple%></TD>
            </TR>
            <TR>
                <TD width="84">lstMultiple</TD>
                <TD><%=lstMultiple%></TD>
            </TR>
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
    </body>
</HTML>

De dynamische delen <%=variabele%> van het document worden berekend door de bijbehorende controller [validation.aspx.vb]:


Imports System.Text.RegularExpressions

Public Class validation
    Inherits System.Web.UI.Page

    Protected rdMarie As String
    Protected C1 As String
    Protected C2 As String
    Protected C3 As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeurs As String
    Protected lstSimple As String
    Protected lstMultiple As String
    Protected secret As String
    Protected delimiteur As New Regex("\r\n")

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'de verzonden parameters worden opgehaald
        rdMarie = getValue("rdMarie")
        C1 = getValue("C1")
        C2 = getValue("C2")
        C3 = getValue("C3")
        txtSaisie = getValue("txtSaisie")
        txtMdp = getValue("txtMdp")
        areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
        cmbValeurs = getValue("cmbValeurs")
        lstSimple = getValue("lstSimple")
        lstMultiple = getValue("lstMultiple")
        secret = getValue("secret")
    End Sub

    Private Function getValue(ByVal champ As String) As String
        ' haalt de waarde op van het veld [champ] uit de verzonden aanvraag
        ' iets?
        If Request.Form(champ) Is Nothing Then Return ""
        ' de waarde(n) van het veld worden opgehaald
        Dim valeurs() As String = Request.Form.GetValues(champ)
        Dim valeur As String = ""
        Dim i As Integer
        For i = 0 To valeurs.Length - 1
            valeur += "[" + valeurs(i) + "]"
        Next
        Return valeur
    End Function

End Class

De berekening van de weer te geven waarden vindt plaats in de procedure [Form_Load]. De waarde van een "gepost" veld wordt verkregen via de functie getValue(C), waarbij C de naam van het veld is. De belangrijkste punten van deze functie zijn de volgende:

  • als C niet in de geposte parameterreeks voorkomt, wordt de lege tekenreeks als waarde voor C geretourneerd
  • anders wordt de array met waarden van veld C opgehaald via [Request.Form.GetValues(C)]. Deze worden samengevoegd tot een tekenreeks in de vorm [val1][val2]...[valn], waarbij [vali] de waarde nr. i van het veld C is

Het veld [areaSaisie] wordt op een bijzondere manier verwerkt. De waarde ervan wordt door de browser verzonden in de vorm areaSaisie=regel1\r\nregel2\r\n... waarbij \r het codetekens ASCII 13 (carriage return) is en \n het codetekens ASCII 10 (regelsprong). De functie getValue(areaSaisie) is dus de tekenreeks "regel1\r\nregel2\r\n...". Deze tekenreeks wordt door de methode [Regex.Split] in regels opgesplitst. We krijgen dan een array van tekenreeksen {regel1,regel2,...}. Deze array wordt door de methode [String.Join] omgezet in de tekenreeks "regel1,regel2,...". Het is deze laatste tekenreeks die wordt weergegeven als waarde van het veld [areaSaisie]. Het doel was hier om te laten zien hoe men de verschillende regels van een veld HTML van het type [TextArea] kon verkrijgen.

5.4.5. Tests

We plaatsen alle bestanden (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) in een map <application-path>. We starten de Cassini-server met de parameters (<application-path>,/mvcform1). We maken in de map <application-path> een leeg bestand [default.aspx] aan en roepen vervolgens de URL [http://localhost/mvcform1] op. Aangezien [/mvcform1] het virtuele pad naar een map is en niet naar een document, zal de webserver het document [default.aspx] weergeven als dit aanwezig is. Daarom hebben we dit document aangemaakt. Voordat het wordt weergegeven, wordt het script [global.asax] uitgevoerd, waardoor uiteindelijk de pagina [formulaire.aspx] wordt weergegeven. Daarom mag het bestand [default.aspx] leeg zijn.

Stel dat het gevalideerde formulier er als volgt uitziet:

Image

Als je de knop [Envoyer] gebruikt, wordt de volgende pagina weergegeven:

Image

Laten we allereerst de URL van het antwoord bekijken: [http://localhost/mvcform1/?action=validation]. Dit is de URL van het attribuut [action] van de tag <form> van het formulier [formulaire.aspx]:


        <form name="formulaire" method="post" action="?action=validation">

Laten we de waarden die voor de verschillende velden van het formulier zijn verkregen een voor een bekijken:

veld
waarde
HTML
opmerkingen
rdMarie
ja
<input type="radio" value="ja"
name="rdMarie">Ja
<input type="radio" checked
value="nee" name="rdMarie">Nee
de verkregen waarde is het attribuut [value] van de aangevinkte knop
C1
een
<input type="checkbox"
value="een" name="C1">1
idem
C2
twee
<input type="checkbox"
checked value="twee" name="C2">2
idem
C3
 
<input type="checkbox"
value="drie" name="C3">3
deze knop is niet door de gebruiker aangevinkt. De waarde ervan is dus niet door de browser verzonden. In de code was de voorwaarde [Request.Form("C3") is Nothing] dus waar.
txtSaisie
Programmeren
asp.net
<input type="text"
... name="txtSaisie">
de verkregen waarde is de tekst die op het moment van het verzenden in het invoerveld staat
txtMdp
mdp
<input type="password"
...name="txtMdp">
idem
areaSaisie
de basisprincipes van
webprogrammering
<textarea name="areaSaisie">
...</textarea>
idem
cmbValeurs
3
<select name="cmbValeurs">
...
<option value="3">keuze3</option>
</select>
de verkregen waarde is het attribuut [value] van de geselecteerde optie
lstSimple
3
<select size="3" name="lstSimple">
....
<option value="3">lijst3</option>
...
</select>
idem
lstMultiple
2 4
<select multiple size="3" name="lstMultiple">
...
<option value="2">multiple2
</option>
...
<option value="4">multiple4
</option>
...
</select>
de verkregen waarden zijn die van de attributen [value] van de geselecteerde opties
geheim
uneValeur
<input type="hidden"
name="secret" value="eenWaarde">
de verkregen waarde is het attribuut [value] van het verborgen veld

Laten we nu eens kijken naar de lijsten. Stel dat de status van het formulier op het moment van validatie als volgt is:

Image

  • de optie [choix1] is geselecteerd in de comboBox
  • er is geen optie geselecteerd in de twee andere lijsten. We hebben de knoppen [Raz] gebruikt om dit te bereiken.

Dit is de pagina die na het valideren wordt weergegeven:

Image

Wanneer er geen waarde in een lijst is geselecteerd, verstuurt de browser geen parameter daarvoor. In de code van [validation.aspx.vb] zijn de uitdrukkingen [Request.Form("lstSimple")] en [Request.Form("lstMultiple")] dus gelijk aan de constante [Nothing], vandaar het hierboven weergegeven resultaat.

5.5. De status van een pagina behouden

5.5.1. De status van een pagina behouden met een sessie

We kopiëren de volledige vorige applicatie naar een nieuwe map. We voegen een link toe aan de pagina [validation.aspx] waarmee de gebruiker terug kan keren naar het formulier:

Image

De wijziging die op de pagina [validation.aspx] moet worden aangebracht, is het toevoegen van de link:


.....
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
        <P>
            <a href="?action=formulaire">Retour au formulaire</a>
        </P>
    </body>
</HTML>

Het attribuut [href] van de link heeft als waarde een URL met als enige parameter [action=formulaire], waardoor de server weet dat hij het formulier moet weergeven zoals het was op het moment dat het werd gevalideerd. Er is dus een verschil met de actie [init], die een vooraf gedefinieerd formulier weergeeft. De URL met parameter [?action=formulaire] heeft in feite geen URL. Deze zal dus dezelfde zijn als die waarmee de validatiepagina werd weergegeven. Zoals we ons uit de vorige studie herinneren, is dit de URL van de applicatiemap. Het verzoek zal dus via de controller verlopen. Deze moet nu de actie [formulaire] verwerken. De code van [global.asax.vb] wordt als volgt aangepast:


    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' de uit te voeren actie wordt opgehaald
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' de actie wordt uitgevoerd
        Select Case action
            Case "init"
                Server.Transfer("formulaire.aspx", False)
            Case "validation"
                Server.Transfer("validation.aspx", True)
            Case "formulaire"
                Server.Transfer("formulaire.aspx", True)
            Case Else
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub

Als de actie "formulier" is, sturen we de aanvraag gewoon door naar de pagina [formulaire.aspx]. We weten dat deze pagina een vooraf gedefinieerd formulier weergeeft waarin geen variabele onderdelen voorkomen. Deze pagina kan het formulier dus niet weergeven met de waarden die het had toen het werd gevalideerd. We willen dit punt hier benadrukken. Als alle bestanden van de applicatie in <application-path> zijn geplaatst, starten we Cassini met de parameters (<application-path>,/mvcform2) en vragen we vervolgens de URL [http://localhost/mvcform2] op. We krijgen de volgende pagina te zien (gedeeltelijke weergave):

Image

We vullen het formulier als volgt in en verzenden het vervolgens:

Image

We krijgen de volgende bevestigingspagina te zien:

Image

We gebruiken de link [Retour au formulaire] die op de bovenstaande pagina staat (maar niet wordt weergegeven). We krijgen het volgende antwoord van de server:

Image

We stellen vast dat:

  • de opgevraagde URL inderdaad de parameter action=formulier bevat, zoals gewenst
  • het weergegeven formulier de ingevoerde waarden kwijt is.

We weten waarom we de ingevoerde waarden niet terugvinden. Als we de code van het document [formulaire.aspx] bekijken, zien we dat alles statisch is en dat het daardoor telkens dezelfde pagina moet weergeven. Het is duidelijk dat we deze code dynamisch moeten maken. De code moet de door de gebruiker gevalideerde waarden weergeven. Maar waar moeten we deze opslaan?

Laten we de ijzeren wet van het stateloze protocol HTTP nog eens in herinnering brengen:

  • de URL [http://localhost/mvcform2] wordt opgevraagd – er wordt een antwoord ontvangen. Er is een verbinding TCP-IP geopend tussen de client en de server aan het begin van de aanvraag en beëindigd aan het einde van het antwoord.
  • De gebruiker voert gegevens in en bevestigt deze. De URL [http://localhost/mvcform2/?action=validation] wordt opgevraagd – er wordt een antwoord ontvangen. Er is een nieuwe verbinding TCP-IP geopend en vervolgens gesloten tussen de twee partijen.
  • De gebruiker gebruikt de link [Retour au formulaire]. De URL [http://localhost/mvcform2/?action=formulaire] wordt opgevraagd – er wordt een antwoord ontvangen. Er is opnieuw een verbinding TCP-IP geopend en vervolgens gesloten tussen de twee partners.

De vraag-antwoordcycli staan los van elkaar omdat elk daarvan een nieuwe verbinding TCP-IP gebruikt. Wanneer een client-servertoepassing één enkele verbinding TCP-IP gebruikt voor een reeks uitwisselingen, kan de server een client identificeren via zijn verbinding. Hij kan dus informatie opslaan die hij aan een specifieke verbinding koppelt en zo de uitwisselingen bijhouden. Wanneer de uitwisselingen via verschillende verbindingen plaatsvinden, kan de server een client niet aan een verbinding koppelen. Er is een andere manier nodig. In het vorige hoofdstuk hebben we er een geïntroduceerd: het sessiemechanisme. Hiermee kunnen de vraag-antwoordcycli informatie opslaan in een [Session]-object dat toegankelijk is voor alle opeenvolgende cycli.

Nu we een applicatie MVC met sessie hebben, kunnen we het bestand [global.asax] niet meer als controller gebruiken, zoals in het vorige hoofdstuk is getoond. De rol van applicatiecontroller moet worden vervuld door een speciale pagina die hiervoor is bestemd. In dit geval is dat de pagina [main.aspx]. We gaan als volgt te werk:

  • wanneer de gebruiker zijn gegevens valideert (actie=validatie), slaat de controller [main.aspx.vb] deze op in de huidige sessie voordat de validatiepagina wordt weergegeven.
  • wanneer het formulier met de ingevoerde waarden moet worden weergegeven (actie=formulier), haalt de controller [main.aspx.vb] deze uit de sessie en plaatst ze in de context voordat het formulier wordt weergegeven.

5.5.2. De nieuwe applicatiecontroller

De applicatiecontroller bestaat uit de twee bestanden [main.aspx, main.aspx.vb]:

[main.aspx]

<%@ Page src="main.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="main" %>

[main.aspx.vb]


Imports System.Collections.Specialized
Imports Microsoft.VisualBasic

Public Class main
    Inherits System.Web.UI.Page

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' de uit te voeren actie wordt opgehaald
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' de actie wordt uitgevoerd
        Select Case action
            Case "init"
                ' het vooraf ingevulde formulier wordt weergegeven
                Context.Items("formulaire") = initForm()
                Server.Transfer("formulaire.aspx", True)
            Case "validation"
                ' de bevestigingspagina wordt weergegeven nadat de verzonden waarden in de sessie zijn opgeslagen
                Session.Item("formulaire") = Request.Form
                Server.Transfer("validation.aspx", True)
            Case "formulaire"
                ' het formulier wordt weergegeven met waarden uit de sessie
                Context.Items("formulaire") = Session.Item("formulaire")
                Server.Transfer("formulaire.aspx", True)
            Case Else
                ' het vooraf ingevulde formulier wordt weergegeven
                Context.Items("formulaire") = initForm()
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub

    Private Function initForm() As NameValueCollection
        ' het formulier wordt geïnitialiseerd
        Dim form As New NameValueCollection
        form.Set("rdMarie", "non")
        form.Set("C2", "deux")
        form.Set("txtSaisie", "qqs mots")
        form.Set("txtMdp", "ceciestsecret")
        form.Set("areasaisie", "ligne1" + ControlChars.CrLf + "ligne2" + ControlChars.CrLf)
        form.Set("cmbValeurs", "2")
        form.Set("lstSimple", "1")
        form.Set("lstMultiple", "1")
        form.Add("lstMultiple", "3")
        Return form
    End Function
End Class

De structuur van de eerder besproken applicatiecontroller komt in essentie overeen, met de volgende verschillen:

  • de controller voert zijn taken uit in de procedure [Form_Load]
  • in het geval van de actie [validation] worden de formulierwaarden uit [Request.Form] opgeslagen in de sessie die gekoppeld is aan de sleutel "formulier". Vervolgens wordt de uitvoering overgedragen aan de pagina [validation.aspx], die deze waarden weergeeft.
  • Voor de overige acties wordt de uitvoering in alle gevallen doorgestuurd naar de pagina [formulaire.aspx]. Deze pagina verwacht in haar context een sleutel „formulier” die gekoppeld zal zijn aan een object van het type [Request.form] of c.a.d, of van het type [NameValueCollection]. Dit object moet de verzameling waarden van de formuliervelden bevatten.
  • Indien de actie [init] is of een niet-herkende actie, wordt de verzameling waarden willekeurig samengesteld door de functie [initForm].
  • Als de actie [formulaire] is, is deze verzameling de verzameling [Request.Form] die door de actie [validation] in de sessie was geplaatst

5.5.3. Het nieuwe formulier

Omdat de applicatie niet langer dezelfde inhoud in het formulier weergeeft, moet dit dynamisch worden gegenereerd. De nieuwe pagina [formulaire.aspx] ziet er als volgt uit:


<%@ Page src="formulaire.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire" %>
<HTML>
    <HEAD>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        function raz(liste){
            liste.selectedIndex=-1
        }
        </script>
    </HEAD>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr>
        <form name="formulaire" method="post" action="main.aspx?action=validation">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <INPUT type="radio" value="oui" name="rdMarie" <%=rdouichecked%>>Oui
                         <INPUT type="radio" value="non" name="rdMarie" <%=rdnonchecked%>>Non
                        </p>
                    </td>
                </tr>
                <TR>
                    <TD>Cases à cocher
                    </TD>
                    <TD>
                        <P align="center">
                            <INPUT type="checkbox" value="un" name="C1" <%=c1checked%>>1
                             <INPUT type="checkbox" value="deux" name="C2" <%=c2checked%>>2
                            <INPUT type="checkbox" value="trois" name="C3" <%=c3checked%>>3
                        </P>
                    </TD>
                </TR>
                <TR>
                    <TD>Champ de saisie</TD>
                    <TD>
                        <P align="center">
                            <INPUT type="text" maxLength="30" value="<%=txtSaisie%>" name="txtSaisie">
                        </P>
                    </TD>
                </TR>
                <tr>
                    <td>
                        Mot de passe</td>
                    <td>
                        <p align="center">
                            <input type="password" maxlength="12" size="12" value="<%=txtMdp%>" name="txtMdp">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Boîte de saisie</td>
                    <td>
                        <textarea name="areaSaisie"><%=areaSaisie%></textarea>
                    </td>
                </tr>
                <tr>
                    <td>
                        ComboBox</td>
                    <td>
                        <select name="cmbValeurs">
                            <%=cmbValeursOptions%>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix simple</td>
                    <td>
                        <select size="3" name="lstSimple">
                            <%=lstSimpleOptions%>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix multiple</td>
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <%=lstMultipleOptions%>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton simple</td>
                    <td>
                        <p align="center">
                            <input onclick="effacer()" type="button" value="Effacer" name="btnEffacer">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton submit</td>
                    <td>
                        <p align="center">
                            <input type="submit" value="Envoyer" name="btnEnvoyer">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton reset</td>
                    <td>
                        <p align="center">
                            <input type="reset" value="Rétablir" name="btnRetablir" runat="server">
                        </p>
                    </td>
                </tr>
            </table>
            <input type="hidden" name="secret" value="uneValeur">
        </form>
    </body>
</HTML>

Laten we de dynamische variabelen bespreken die in de code HTML voorkomen:

variabele
rol
rdouichecked
heeft de waarde "checked" als de keuzeknop [oui] moet worden aangevinkt, anders de waarde ""
rdnonchecked
hetzelfde geldt voor de keuzeknop [non]
c1checked
hetzelfde geldt voor het selectievakje [C1]
c2checked
idem voor het selectievakje [C2]
c3checked
hetzelfde geldt voor het selectievakje [C3]
txtSaisie
de tekst die in het veld [txtSaisie] moet worden geplaatst
txtMdp
de tekst die in het veld [txtMdp] moet worden geplaatst
areaSaisie
de tekst die in het veld [areaSaisie] moet worden geplaatst
cmbValeursOptions
de tekst HTML van de opties in de keuzelijst [cmbValeurs]
lstSimpleOptions
de tekst HTML van de opties in de keuzelijst [lstSimple]
lstMultipleOptions
de tekst HTML van de opties in de keuzelijst [lstMultiple]
  

De waarden van deze variabelen worden berekend door de controller van de pagina [formulaire.aspx.vb]:


Imports Microsoft.VisualBasic
Imports System.Collections.Specialized

Public Class formulaire
    Inherits System.Web.UI.Page

    ' vaste velden van het formulier
    Private libellésCmbValeurs() As String = {"choix1", "choix2", "choix3"}
    Private valeursCmbValeurs() As String = {"1", "2", "3"}
    Private libellésLstSimple() As String = {"liste1", "liste2", "liste3"}
    Private valeursLstSimple() As String = {"1", "2", "3"}
    Private libellésLstMultiple() As String = {"multiple1", "multiple2", "multiple3", "multiple4", "multiple5"}
    Private valeursLstMultiple() As String = {"1", "2", "3", "4", "5"}

    ' dynamische velden van het formulier
    Protected rdouichecked As String
    Protected rdnonchecked As String
    Protected c1checked As String
    Protected c2checked As String
    Protected c3checked As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeursOptions As String
    Protected lstSimpleOptions As String
    Protected lstMultipleOptions As String

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' de vorige aanvraag wordt uit de sessie opgehaald
        Dim form As NameValueCollection
        If Not Context.Items("formulaire") Is Nothing Then
            form = Context.Items("formulaire")
        Else
            form = New NameValueCollection
        End If
        ' de weer te geven pagina wordt voorbereid
        ' keuzerondjes
        rdouichecked = ""
        rdnonchecked = "checked"
        If isEqual(form("rdMarie"), "oui") Then
            rdouichecked = "checked"
            rdnonchecked = ""
        End If
        ' selectievakjes
        c1checked = ""
        If isEqual(form("C1"), "un") Then c1checked = "checked"
        c2checked = ""
        If isEqual(form("C2"), "deux") Then c2checked = "checked"
        c3checked = ""
        If isEqual(form("C3"), "trois") Then c3checked = "checked"
        ' invoervelden
        txtSaisie = ""
        If Not form("txtSaisie") Is Nothing Then txtSaisie = form("txtSaisie").ToString
        txtMdp = ""
        If Not form("txtMdp") Is Nothing Then txtMdp = form("txtMdp").ToString
        areaSaisie = ""
        If Not form("areaSaisie") Is Nothing Then areaSaisie = form("areaSaisie").ToString
        ' lijsten
        Dim sélections() As String = {}
        If Not form("cmbValeurs") Is Nothing Then sélections = form.GetValues("cmbValeurs")
        cmbValeursOptions = getOptions(valeursCmbValeurs, libellésCmbValeurs, sélections)
        sélections = New String() {}
        If Not form("lstSimple") Is Nothing Then sélections = form.GetValues("lstSimple")
        lstSimpleOptions = getOptions(valeursLstSimple, libellésLstSimple, sélections)
        sélections = New String() {}
        If Not form("lstMultiple") Is Nothing Then sélections = form.GetValues("lstMultiple")
        lstMultipleOptions = getOptions(valeursLstMultiple, libellésLstMultiple, sélections)
    End Sub

    Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
        ' geeft de code HTML weer van de opties van een <select>-tag
        ' waarden: tabel met de waarden van de opties van de tag
        ' labels: tabel met de labels van de opties van de tag
        ' selecties: te selecteren opties
        Dim iValeur As Integer
        Dim iSelection As Integer
        Dim selected As String
        Dim toString As String = ""
        ' de lijst met optiewaarden wordt doorlopen
        For iValeur = 0 To valeurs.Length - 1
            ' wordt gecontroleerd of de huidige waarde moet worden geselecteerd
            selected = "" : iSelection = 0
            Do While iSelection < sélections.Length And selected = ""
                If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
                iSelection += 1
            Loop
            ' de code HTML van de optie wordt opgenomen
            toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
            + libelles(iValeur) + "</option>" + ControlChars.CrLf
        Next
        ' het resultaat wordt weergegeven
        Return toString
    End Function

    Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
        ' geeft ‘waar’ terug als het veld gelijk is aan de waarde
        If champ Is Nothing OrElse champ.ToString <> valeur Then
            Return false
        Else
            Return true
        End If
    end function
End Class

Wanneer de pagina [formulaire.aspx] wordt uitgevoerd, vindt deze in zijn context een 'formulier'-sleutel die gekoppeld is aan de verzameling waarden van de velden die moeten worden weergegeven.


         ' de vorige query uit de sessie ophalen
        Dim form As NameValueCollection
        If Not Context.Items("formulaire") Is Nothing Then
            form = Context.Items("formulaire")
        Else
            form = New NameValueCollection
        End If

Men kan zich afvragen waarom wordt gecontroleerd of [Context.Items("formulaire")] bestaat. De controller wijst immers in alle gevallen een waarde toe aan dit object. Niets belet de client echter om de pagina [formulaire.aspx] rechtstreeks op te vragen, zonder via de controller te gaan. Als dat het geval zou zijn, zou de bovenstaande code met een lege verzameling waarden werken, maar er zou geen "crash" optreden.

De code doorloopt de verzameling waarden die hij heeft ontvangen om alle dynamische variabelen te berekenen voor de bijbehorende pagina HTML. Hoewel de code lang is, is hij niet bijzonder ingewikkeld en laten we het aan de lezer over om zich erin te verdiepen, om deze uitleg niet te zwaar te maken. We zullen echter wel stilstaan bij de manier waarop de code HTML wordt gegenereerd uit de drie lijsten van het type [select]. Deze code wordt gegenereerd door de volgende functie:

    Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
         ' geeft de code HTML van de opties van een <select>-tag weer
         ' waarden: array met de waarden van de opties van de tag
         ' labels: array met de labels van de opties van de tag
         ' selecties: te selecteren opties
        Dim iValeur As Integer
        Dim iSelection As Integer
        Dim selected As String
        Dim toString As String = ""
         ' de lijst met optiewaarden wordt doorlopen
        For iValeur = 0 To valeurs.Length - 1
             ' wordt gecontroleerd of de huidige waarde moet worden geselecteerd
            selected = "" : iSelection = 0
            Do While iSelection < sélections.Length And selected = ""
                If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
                iSelection += 1
            Loop
             ' de code HTML van de optie wordt opgenomen
            toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
            + libelles(iValeur) + "</option>" + ControlChars.CrLf
        Next
         ' het resultaat wordt weergegeven
        Return toString
    End Function

Ter herinnering: de opties van een <select>-tag komen overeen met de volgende code HTML:

<option [selected] value="...">texte</option>

Voor elke optie moet er dus drie gegevens worden gegenereerd:

  • de waarde van de optie in het attribuut [value]
  • de tekst van de optie tussen de tags <option> en </option>
  • het trefwoord [selected] als de optie in de lijst moet worden geselecteerd

Om deze drie gegevens voor elke optie te genereren, ontvangt de functie [getOptions] drie waarden:

  1. de tabel met de waarden van de opties in [valeurs]
  2. de tabel met de teksten van de opties in [libelles]
  3. de tabel met de te selecteren waarden in [sélections]

5.5.4. De validatiepagina

De validatiepagina blijft ongewijzigd:

[validation.aspx]


<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
    <HEAD>
        <title>validation</title>
    </HEAD>
    <body>
        <P>Valeurs saisies</P>
        <HR width="100%" SIZE="1">
        <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
            <TR>
                <TD width="84">rdMarie</TD>
                <TD><% =rdMarie%></TD>
            </TR>
            <TR>
                <TD width="84">C1</TD>
                <TD><%=C1%></TD>
            </TR>
            <TR>
                <TD width="84">C2</TD>
                <TD><%=C2%></TD>
            </TR>
            <TR>
                <TD width="84">C3</TD>
                <TD><%=C3%></TD>
            </TR>
            <TR>
                <TD width="84">txtSaisie</TD>
                <TD><%=txtSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">txtMdp</TD>
                <TD><%=txtMdp%></TD>
            </TR>
            <TR>
                <TD width="84">areaSaisie</TD>
                <TD><%=areaSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">cmbValeurs</TD>
                <TD><%=cmbValeurs%></TD>
            </TR>
            <TR>
                <TD width="84">lstSimple</TD>
                <TD><%=lstSimple%></TD>
            </TR>
            <TR>
                <TD width="84">lstMultiple</TD>
                <TD><%=lstMultiple%></TD>
            </TR>
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
        <P>
            <a href="main.aspx?action=formulaire">Retour au formulaire</a>
        </P>
    </body>
</HTML>

[validation.aspx.vb]


Imports Microsoft.VisualBasic
Imports System.Text.RegularExpressions

Public Class validation
    Inherits System.Web.UI.Page

    Protected rdMarie As String
    Protected C1 As String
    Protected C2 As String
    Protected C3 As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeurs As String
    Protected lstSimple As String
    Protected lstMultiple As String
    Protected secret As String
    Protected delimiteur As New Regex("\r\n")

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'de verzonden parameters worden opgehaald
        rdMarie = getValue("rdMarie")
        C1 = getValue("C1")
        C2 = getValue("C2")
        C3 = getValue("C3")
        txtSaisie = getValue("txtSaisie")
        txtMdp = getValue("txtMdp")
        areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
        cmbValeurs = getValue("cmbValeurs")
        lstSimple = getValue("lstSimple")
        lstMultiple = getValue("lstMultiple")
        secret = getValue("secret")
        ' we slaan ze op in de sessie
        'Session("formulier") = Request.Form
    End Sub

    Private Function getValue(ByVal champ As String) As String
        ' haalt de waarde op van het veld [champ] uit de verzonden verzoek
        ' wat dan?
        If Request.Form(champ) Is Nothing Then Return ""
        ' hiermee worden de waarden van het veld opgehaald
        Dim valeurs() As String = Request.Form.GetValues(champ)
        Dim valeur As String = ""
        Dim i As Integer
        For i = 0 To valeurs.Length - 1
            valeur += "[" + valeurs(i) + "]"
        Next
        Return valeur
    End Function
End Class

5.5.5. De tests

De bestanden [main.aspx, main.aspx.vb,formulaire.aspx,formulaire.aspx.vb, validation.aspx, validation.aspx.vb] worden in <application-path> geplaatst en Casini wordt gestart met de parameters (<application-path>,/mvcform3). Vervolgens roepen we de URL [http://localhost/mvcform3/main.aspx] op. We krijgen het vooraf geïnitialiseerde formulier te zien:

Image

We vullen het formulier als volgt in:

Image

We gebruiken de bovenstaande knop [Envoyer]. We krijgen het volgende antwoord van de server:

Image

We gebruiken de bovenstaande link [Retour au formulaire] om terug te keren naar het formulier. We krijgen het volgende nieuwe antwoord:

Image

We zien inderdaad het formulier terug zoals we het hebben verzonden.

5.5.6. Conclusie

Het voorgaande voorbeeld heeft aangetoond dat het mogelijk is om de status van een pagina te behouden tijdens de verzoek-antwoordcycli tussen de client en de server. Dit is echter geen eenvoudige opgave. In een later hoofdstuk zullen we zien dat het met ASP.NET mogelijk is om de server zelf de status van een pagina te laten herstellen.