LP
IMApp

Scripts
Clients

Leçon 08

Leçon 08 : Les formulaires

Contenu :

Cette leçon détaille la gestion des formulaires en JavaScript. Elle présente les principaux éléments de formulaire HTML, leur accès et modification depuis JavaScript. Cette leçon explique également les mécanismes de base mis en oeuvre dans la vérification de formulaire.

Objectifs :

Connaitre les éléments de formulaire et leur gestion via JavaScript. Connaitre et utiliser les mécanismes de base pour la vérification de formulaire côté client

Eléments de formulaire

Les formulaires HTML sont destinés à transmettre des données du client au serveur. C'est le mécanisme de base qui permet la communication du client vers le serveur. Un formulaire contient, entre autres, des éléments spécifiques à la communication appelés éléments de formulaire. Ces éléments peuvent être utilisés en dehors de tout formulaire pour assurer une interaction avec l'utilisateur. Vous connaissez déjà un élément de formulaire que vous avez utilisé dans la leçon précédente, l'élément INPUT. Nous allons passer en revue les autres.

L'élément SELECT

L'élément HTML SELECT présente un menu avec des options. Les options de ce menu sont représentées par des éléments OPTION. En JavaScript, un élément SELECT est vu comme un tableau contenant les éléments OPTION. Par exemple, si on dispose du code HTML suivant :

Choisissez un continent :
  <select id="continent">
    <option>Afrique</option>
    <option>Amérique</option>
    <option>Asie</option>
    <option>Europe</option>
    <option>Océanie</option>
  </select>
  <p>
    Cliquez <span onclick="liste()">ici</span> pour voir la liste des continents et
    <span onclick="choix()">ici</span> pour voir celui que vous avez choisi !
  </p>           
on accéder au contenu de l'élément SELECT avec la fonction suivante :
function liste() {
	var continentElt = document.querySelector( "#continent" );
	var continent = "Les continents sont :";
	for ( var i = 0; i < continentElt.length; i++ )
		continent += "\n" + continentElt[i].innerHTML;
	alert( continent );
}	
Remarquez que la variable continentElt qui contient la version JavaScript de l'élément SELECT d'identifiant continent peut être utilisée comme un tableau contenant les éléments OPTION. Pour connaitre l'option sélectionnée par l'utilisateur, on utilise l'attribut selectedIndex :
function choix() {
	var continentElt = document.querySelector( "#continent" );
	alert( continentElt[ continentElt.selectedIndex ].innerHTML );
}	
Ce modèle est très général et on peut bien entendu exploiter tous les attributs des éléments qu'on manipule. Par exemple, on peut s'interesser aux attributs des éléments OPTION de l'élément SELECT en question. Dans le code HTML suivant :
Choisissez une ville :
  <select id="ville">
    <option value="Afrique">Pretoria</option>
    <option value="Amérique">Washington</option>
    <option value="Asie">Hanoï</option>
    <option value="Europe">Berlin</option>
    <option value="Océanie">Canberra</option>
  </select>
  <p>
    Cliquez <span onclick="continent()">ici</span> pour connaitre son continent !
  </p>
on utilise l'attribut value des éléments OPTION, attribut qu'on peut exploiter en JavaScript :
function continent() {
	var villeElt = document.querySelector( "#ville" );
	var optionElt = villeElt[ villeElt.selectedIndex ];
	alert( optionElt.innerHTML + " est en " + optionElt.value );	
}

Il est possible de contrôler totalement un élément SELECT depuis JavaScript, par exemple en positionnant ou non l'attribut multiple qui autorise la sélection multiple.

Exercice 1

Ecrivez le code JavaScript nécessaire au document HTML exo1.html pour permettre à l'utilisateur de tester ses connaissances en sélectionnant la bonne réponse dans une liste de réponses possibles. Le résultat s'affiche dans un élément initialement caché lorsque l'utilisateur clique sur le bouton correspondant à la question qu'il souhaite tester. Dès qu'on sélectionne une option dans une des listes déroulantes, la zone de résultats disparaît. Dans cet exercice, on exploite la possibilité d'utiliser des attributs propriétaires avec l'attribut booléen data-ok : on décide que la présence de cet attribut dans un élément OPTION indique que cette option est la bonne réponse. Pour tester l'existence d'un attribut sur un élément, vous utiliserez la méthode hasAttribute.

Fichier(s)

exo1.html

Les boutons radio

Les éléments HTML INPUT de type radio permettent de constituer des groupes de boutons dont un seul peut être activé à la fois. Les boutons radios d'un même groupe sont repérés par la valeur de l'attribut name qui doit avoir la même valeur pour tous les boutons du groupe. L'accès à un groupe de boutons radios s'effectue à l'aide de la méthode querySelectorAll. Cette méthode ressemble à la méthode querySelector mais contrairement à cette dernière, elle retourne plusieurs éléments (par exemple tous les boutons d'un même groupe). Cette méthode retourne donc les éléments sélectionnés dans une liste. Les éléments apparaissent dans la liste dans l'ordre dans lequel il apparaissent dans le document HTML. Sur un élément HTML INPUT de type radio on dispose de l'attribut booléen checked qui indique si cet élément est cliqué. Dans le code HTML suivant :

Choisissez un pays :
  <ul style="list-style-type: none">
    <li>1<input type="radio" name="pays" value="Pretoria" /> Afrique du sud</li>
    <li>2<input type="radio" name="pays" value="Washington" /> Etats-Unis</li>
    <li>3<input type="radio" name="pays" value="Hanoï" /> Vietnam</li>
    <li>4<input type="radio" name="pays" value="Berlin" /> Allemagne</li>
    <li>5<input type="radio" name="pays" value="Canberra" /> Australie</li>
  </ul>
  <p>
    Cliquez <span onclick="choix2()">ici</span> pour voir
    le numéro de celui que vous avez choisi !                    
  </p>
on utilise également l'attribut value pour stocker la capitale du pays sélectionné. Remarquez que le pays lui-même apparait comme du texte sans lien avec l'élément INPUT qui est sensé le sélectionner. Le code JavaScript de la fonction choix2 :
function choix2() {
	var paysTab = document.querySelectorAll( 'input[name="pays"]' );
	var indice = 0;
	for ( var i = 0; i < paysTab.length; i++ )
		if ( paysTab[ i ].checked )
			indice = i;
	alert( "Vous avez choisi le pays n. " + ( indice + 1 ) +
	       "\ndont la capitale est " + paysTab[ indice ].value );
}	

Exercice 2

Reprenez l'exercice précédent avec le fichier exo2.html, cette fois en utilisant des boutons radio à la place des listes déroulantes. On utilise ici encore un attribut propriétaire (l'attribut data-ok) pour marquer l'élément INPUT qui correspond à la bonne réponse. Notez l'utilisation de l'attribut checked qui permet d'activer un bouton par défaut.

Fichier(s)

exo2.html

Les cases à cocher

Les éléments HTML INPUT de type checkbox permettent de constituer des groupes de boutons à la manière des boutons radio mais dans ce cas il est possible de cocher plusieurs boutons dans le même groupe. Les attributs disponibles sur les cases à cocher sont les mêmes que sur les boutons radio. Quand on veut pouvoir communiquer au serveur l'ensemble des valeurs cochées dans un groupe de case à cocher, on utilise pour valeur de l'attribut name des chaînes de caractères terminant par [], comme par exemple entree[] dans l'exercice 5 (voir plus bas). Dans ce cas, il faut bien utiliser ce nom (avec la paire de crochets à la fin) pour récupérer l'ensemble des boutons en JavaScript (par exemple, document.querySelectorAll( 'intput[name="entree[]"' )).

Autres éléments de formulaire

Il existe un autre élément de formulaire, l'élément TEXTAREA, qui permet à l'utilisateur de saisir un texte éventuellement sur plusieurs lignes. Du point de vue de JavaScript, cet élément est semblable à un élément INPUT de type texte et possède les mêmes attributs.

Il existe également d'autres éléments INPUT, les éléments de type hidden et les éléments de type password. Du point de vue de JavaScript, ces éléments sont identiques à des éléments INPUT de type texte.

Les exemples précédents sont disponibles dans les fichiers exemple-1.html et exemple-1.js

Vérification de formulaire

Une utilisation très classique de JavaScript est la vérification de formulaire côté client. L'idée est la suivante : après que l'utilisateur ait renseigné les différents éléments du formulaire et avant l'envoi des données au serveur, il est possible et souvent utile d'effectuer des vérifications. Par exemple, on peut vérifier la validité lexicale de certains éléments INPUT de type texte, ou bien vérifier qu'au moins un bouton radio d'un ensemble donné est coché. Parfois, cette vérification peut consister à valider la cohérence des différents choix effectués dans le formulaire (du type, si tel bouton est coché, alors tel élément INPUT doit être renseigné). Etudions le formulaire suivant :

<form action="exemple-2.php" method="post" onsubmit="return verifier()">
  <p>
    <label>Nom</label><input id="nom" name="nom" type="text" />
  </p>
  <p>
    <label>Prénom</label><input id="prenom" name="prenom" type="text" />
  </p>
  <p>
    <label>email</label><input id="email" name="email" type="text" />
  </p>
  <p>
    <input type="reset" value="Annuler" />
    <input type="submit" value="Envoyer" />
  </p>
</form>
Remarquez l'évènement onsubmit dans l'élément FORM. Cet évènement est déclenché lors du clic sur l'élément INPUT de type submit au bas du formulaire. A cet évènement est lié l'expression JavaScript return verifier(). Cette expression indique que la fonction verifier retourne une valeur, qui est en quelque sortes retournée au formulaire. Cette valeur doit être une valeur booléenne (true ou false). Si cette valeur est true, les données du formulaire sont bien transmises au serveur, sinon l'effet du submit est annulé et aucune information n'est transmise au serveur. La fonction verifier vérifie les données du formulaire, et dans le cas où elles sont incorrectes, annule leur envoi au serveur simplement en retournant la valeur false. Voilà une version sommaire de cette fonction :
function verifier() {
	var nomElt = document.querySelector( "#nom" );
	var nom = nomElt.value.trim();
	if ( nom.length == 0 ) {
		nomElt.value = "";
		nomElt.focus();
		alert( "Nom invalide" );
		return false;
	}
	var prenomElt = document.querySelector( "#prenom" );
	var prenom = prenomElt.value.trim();
	if ( prenom.length == 0 ) {
		prenomElt.value = "";
		prenomElt.focus();
		alert( "Prénom invalide" );
		return false;
	}	
	var emailElt = document.querySelector( "#email" );
	var email = emailElt.value.trim();
	if ( email.length == 0 || emailInvalide( email ) ) {
		emailElt.value = email;
		emailElt.focus();
		alert( "Email invalide" );
		return false;
	}
	return true;
}
Pour les éléments INPUT de type texte contenant les nom et prénom de l'utilisateur, la fonction se borne à vérifier que ces valeurs sont bien renseignées. Pour l'élément contenant l'adresse email, la fonction effectue des tests plus poussés à l'aide la fonction auxiliaire emailInvalide :
function emailInvalide( email ) {
	var i = email.indexOf( "@" );
	if ( i < 1 )
		return true;
	if ( i != email.lastIndexOf( "@" ) )
		return true;
	var droite = email.split( "@" )[1];
	i = droite.lastIndexOf( "." );
	if ( i == -1 )
		return true;
	droite = droite.substring(i);
	if ( droite.length < 3 )
		return true;
	return false;
}
Aux lignes 2-4, la fonction vérifie qu'il y a au moins une fois le caractère @ dans l'adresse email. Aux lignes 5-6, la fonction vérifie qu'il n'y qu'un unique caractère '@'. La ligne 7 permet de récupérer la partie située à droite du caractère '@'. Les lignes 8-10 vérifient qu'il y a au moins une fois le caractère '.' (point) dans cette partie. La ligne 11 permet de récupérer le suffixe de l'adresse email qui commence par le (dernier) caractère '.' (point). Les lignes 12-13 vérifient que ce suffixe est bien de longueur au moins 3 (le point suivi d'au moins deux caractères).

Les exemples précédents sont disponibles dans les fichiers exemple-2.html et exemple-2.js

Exercice 3

Pour cet exercice, vous devez travailler dans le serveur web (et non pas en mode file). On désire développer un formulaire interactif dont l'apparition de certains éléments dépend de la valeur d'autres éléments. Au chargement du code HTML contenu dans le fichier exo3.html, seuls sont visibles les deux éléments correspondant aux nom et prénom, et les boutons radio pour préciser le sexe de l'utilisateur. Après avoir renseigné les nom et prénom, si celui-ci clique sur H(omme), le formulaire est complet et ses informations peuvent être envoyées au serveur. S'il clique sur F(emme), un nouvel ensemble de boutons radio apparaît pour déterminer si l'utilisatrice est mariée ou non. Si ce n'est pas le cas, le formulaire est complet et ses informations peuvent être envoyées au serveur, sinon, un nouvel élément apparait pour saisir le nom de jeune fille de l'utilisatrice. Avant l'envoi des données, la fonction verifier vérifie que tous les éléments INPUT de type texte sont bien renseignés. Après avoir étudié les différents évènements présents dans le code HTML, écrivez les fonctions JavaScript correspondantes.

Fichier(s)

exo3.html , exo3.php.txt

Exercice 4

Le fichier exo4.html contient du code HTML qui présente un menu de restaurant destiné à enregistrer une commande. Dans cette version, le formulaire n'est pas actif et on ne peut pas envoyer les données au serveur. Remarquez la structure des éléments INPUT de type checkbox : ils sont regroupés en types de plat (entrées, plats principaux, desserts et boissons). Le rôle de leurs attributs est le suivant :
  • name : il sert à regrouper les boites à cocher par type de plat
  • data-name : c'est un attribut propriétaire qui contient le nom du plat
  • data-price ; c'est un attribut propriétaire qui contient le prix du plat
Ecrivez le code JavaScript nécessaire pour permettre à l'utilisateur de sélectionner des plats dans le menu et d'afficher, après un clic sur le bouton Commander, une alerte contenant le récapitulatif de la commande (la liste des plats sélectionnés avec leur prix et le montant total de la commande).

Fichier(s)

exo4.html

Exercice 5

Pour cet exercice, vous devez travailler dans le serveur web (et non pas en mode file). Le fichier exo5.html contient du code HTML qui présente une nouvelle version du menu de l'exercice précédent. Maintenant, le formulaire est actif et on peut envoyer les données au serveur. Les éléments INPUT de type checkbox ont maintenant un attribut supplémentaire, l'attribut value. La valeur de cet attribut est utilisé côté serveur pour déterminer les plats commandés. Vous pouvez regarder le script PHP exo5.php pour vous en convaincre. Ecrivez le code JavaScript nécessaire pour permettre à l'utilisateur de sélectionner des plats dans le menu, d'afficher, après un clic sur le bouton Commander, une fenêtre de confirmation contenant le récapitulatif de la commande (la liste des plats sélectionnés avec leur prix et le montant total de la commande) : si l'utilisateur confirme, les données sont envoyées au serveur, sinon cet envoi est annulé.

Fichier(s)

exo5.html , exo5.php.txt