Petit rappel sur les formulaires
Rappelons-nous d'abord de quoi est composé un formulaire :
- de champs de saisie, matérialisés par des balises
input,selectettextarea; - de boutons pour valider ou annuler / effacer le formulaire,
respectivement
<input type="submit" />et<input type="reset" />; - une balise
formqui encadre le tout ; - et éventuellement ce fameux script en Javascript qui va vérifier le contenu avant son envoi vers le serveur Web.
Cet ensemble peut être complété par des balises label,
fieldset, legend, etc.
pour améliorer l'accessibilité et la structure d'un formulaire. Je vous renvoie à l'article
Utilisation des formulaires pour
en savoir plus à ce sujet. Nous ne nous occuperons ici que de l'aspect Javascript.
Voila ce que cela pourrait donner :
<form action="url_page_suivante" method="get" name="formSaisie"> <p> <label for="prenom">Saisissez votre prénom :</label> <input type="text" name="prenom" id="prenom" /> <input type="submit" value="Ok" /> </p> </form>
Nous sommes dans l'hypothèse où notre page est conforme au
XHTML 1.0 Transitionnal,
et non Strict, pour faciliter la compréhension des exemples qui suivront. En effet, en
XHTML Strict ou HTML
4.01 Strict, l'attribut "name" de la balise form
est obsolète. De ce fait, il est impossible avec ces DTD
d'utiliser le code document.nom_du_formulaire, très souvent utilisé,
pour accéder aux champs de saisie (comme par exemple
document.nom_du_formulaire.mon_champs.value). Nous verrons
à la fin de cet article comment contourner cette restriction et écrire du code
respectant un peu mieux les spécifications du DOM,
utilisable avec toutes les versions de HTML et sur tous les navigateurs.
Les erreurs les plus courantes
En général, les formulaires ressemblent à notre exemple, il n'y a pas trop de soucis. Là où ça se gâte, c'est au moment d'inclure le petit bout de code Javascript qui va vérifier que l'internaute a bien saisi un prénom (en se référant à notre exemple), avant d'envoyer le formulaire.
Beaucoup de développeurs, instinctivement, implémentent (à tort) cette vérification au niveau du clic sur le bouton « Ok ». C'est ainsi que l'on trouve ce genre de fonction (à ne pas faire).
<script type="text/javascript">
//<![CDATA[
function valider() {
// si la valeur du champ prenom est non vide
if(document.formSaisie.prenom.value != "") {
// alors on envoie le formulaire
document.formSaisie.submit();
}
else {
// sinon on affiche un message
alert("Saisissez le prénom");
}
}
//]]>
</script>
Puis sur le bouton « Ok », on trouve en général
l'appel de la fonction valider() sur l'événement
"onclick", déclenché lorsque
l'on clique sur le bouton, ce qui ressemble à ceci (Cas A) :
<input type="submit" value="Ok" onclick="valider()" />
On trouve parfois aussi, non pas un bouton « submit » mais un bouton tout court, ou une image, ou un lien, ce qui est encore moins bien (Cas B):
<input type="button" value="Ok" onclick="valider()" /> <img src="ok.png" onclick="valider()" alt="ok" /> <a href="/articles/validation_formulaire#" onclick="valider()">Ok</a>
Souvent même, la fonction valider() est
appelée directement dans l'attribut "href"
d'un lien (Cas C):
<a href="javascript:valider()">Ok</a> <a href="javascript:valider()"><img src="ok.png" alt="ok" /></a>
Pourquoi ce sont des erreurs ?
Il faut se mettre en tête que :
- l'utilisateur peut vouloir préférer appuyer sur la touche Entrée de son clavier plutôt que de cliquer sur le bouton « Ok ». Il peut s'agir des inconditionnels du clavier, mais il peut s'agir aussi de personnes qui sont obligées de passer par le clavier. Il y a ainsi ceux qui utilisent un navigateur texte. Il y a aussi les handicapés moteurs pour qui la manipulation de la souris peut être difficile. Il y a aussi les gens qui doivent manipuler à longueur de temps des formulaires, comme c'est le cas dans les applications intranet. Car éviter de passer du clavier à la souris et de la souris au clavier permet d'être plus productif et est moins fatiguant. Tous les ergonomes vous le diront ;
- le Javascript n'est pas forcément disponible dans le navigateur de l'internaute (ou tout simplement désactivé). La plupart des statistiques rapportent que c'est le cas pour 5 à 7% des internautes.
Ces constats nous amènent donc à nous rendre compte que les exemples vus précédemment sont inadaptés.
Dans le cas A, si l'utilisateur appuie sur la touche
Entrée en étant dans l'un des champs de
saisie, ou s'il met le focus sur le bouton avec la touche Tab
puis en appuyant sur Entrée, le formulaire
sera envoyé, sans même que la fonction valider() soit
exécutée (Ce n'est cependant pas le cas de tout les navigateurs). En effet,
elle n'est ici appelée que sur l'événement "onclick".
Dans le cas B, étant donné qu'il ne s'agit ni de bouton « submit », ni de bouton « image », la touche Entrée est inactive, et ne provoque pas l'envoi du formulaire. On est obligé de cliquer sur le bouton, l'image ou le lien. Cela peut être donc embêtant pour certaines personnes comme on l'a vu.
Pire, dans les cas B et C, si le support du Javascript est désactivé ou n'est pas présent dans le navigateur, le formulaire ne pourra jamais être envoyé ! Idem si on n'a pas de souris (navigateur texte) dans le cas B !
La bonne façon de vérifier un formulaire
En fait, il n'existe qu'une seule méthode valable pour vérifier le contenu d'un formulaire en Javascript avant son envoi.
Utilisation des bons boutons
Le/les bouton(s) pour envoyer le formulaire doivent être :
- soit de type « submit » :
<input type="submit" value="Ok" />; - soit de type image, si on veut un bouton « submit »
sous forme d'image :
<input type="image" src="ok.png" alt="ok" />.
Rappelez-vous qu'il est possible d'utiliser des feuilles de styles pour changer l'apparence des boutons : couleurs, bordures, image de fond, etc. Il faut noter cependant que certains navigateurs ne permettent pas d'utiliser tous les styles sur les boutons.
L'événement "onsubmit"
Cet événement, spécifique à la balise form, est
déclenché lorsque le formulaire est sur le point d'être envoyé, suite à
l'appui sur la touche Entrée, ou d'un clic sur un
bouton « submit », ou toute autre action indiquant au navigateur
d'envoyer le formulaire.
Donc l'éxecution d'un script devant vérifier le contenu du formulaire
(ou faisant éventuellement d'autres traitements liés à l'envoi)
doit toujours se faire sur l'événement "onsubmit" !
Comme sur tous les événements ("onclick"...),
le script appelé doit renvoyer un booléen, true ou
false. S'il ne renvoie rien, l'événement reçoit
true par défaut. Ce booléen indique si l'événement
doit se propager, c'est-à-dire si l'événement par défaut doit s'exécuter.
Ainsi, si vous renvoyez true sur l'événement
"onsubmit", le formulaire sera envoyé.
Si vous renvoyez false, il ne le sera pas et le navigateur ne changera
pas de page. Par exemple, en mettant onsubmit="return false",
le formulaire ne pourra jamais être envoyé !
Nous devons donc appeler notre fonction valider() sur
le "onsubmit", et celle-ci devra renvoyer
un booléen pour indiquer si le formulaire doit être envoyé ou non :
<script type="text/javascript">
//<![CDATA[
function valider(){
// si la valeur du champ prenom est non vide
if(document.formSaisie.prenom.value != "") {
// les données sont ok, on peut envoyer le formulaire
return true;
}
else {
// sinon on affiche un message
alert("Saisissez le prénom");
// et on indique de ne pas envoyer le formulaire
return false;
}
}
//]]>
</script>
Et la balise form devient :
<form action="url_page_suivante" onsubmit="return valider()" method="get" name="formSaisie"> <p> <label for="prenom">Saisissez votre prénom :</label> <input type="text" name="prenom" id="prenom" /> <input type="submit" value="Ok" /> </p> </form>
Notez l'emploi du mot-clé return sur l'appel de valider().
Ainsi, que l'on appuie sur la touche Entrée ou
que l'on clique sur le bouton « submit », la fonction
valider() sera toujours appelée. Et si le Javascript n'est
pas activé, cela n'empêche pas le contenu du formulaire d'être envoyé.
Quelques précisions
- Le test du contenu d'un formulaire en Javascript doit être seulement considéré comme un plus pour le confort de l'utilisation de la page, afin d'éviter un envoi et un rechargement du formulaire si son contenu est invalide. Il ne remplace en aucun cas une vérification faite côté serveur, qui doit être systématique (que ce soit en PHP, ASP, Java, etc.), afin de palier le cas où le Javascript n'est pas activé, donc au cas où le formulaire n'est pas vérifié côté navigateur.
- S'il y a du code Javascript qui envoie le formulaire en appelant
la methode
submit()de l'objet formulaire comme ceci :document.formSaisie.submit();, l'événement"onsubmit"n'est pas déclenché, mais le formulaire est tout de même envoyé. Donc la fonctionvalider()ne sera pas appelée dans ce cas. - On évitera d'utiliser les méthodes propriétaires à Internet Explorer comme
document.allpour récupérer l'objet formulaire ou les objets correspondants aux champs de saisie, afin de garder une interopérabilité maximum. On préferera utiliser les fonctions du DOM comme nous allons le voir dans la section suivante.
La vérification de formulaire en Strict
Le problème des DTD Strict (HTML 4.01 Strict,
XHTML 1.0 Strict ou XHTML 1.1),
c'est que l'attribut "name" de la balise
form est obsolète. Du coup, il est impossible de
récupérer l'objet formulaire par l'instruction suivante comme on a très souvent l'habitude
de faire : document.formSaisie. Cette instruction est en fait
un raccourci de ce qu'il faudrait faire.
Utilisation du DOM avec la collection forms
L'objet document possède une propriété forms,
qui est une collection contenant les objets formulaires présents dans la page.
On peut alors l'utiliser de deux manières pour récupérer l'objet formulaire désiré
document.forms[n]oùnest le numéro de formulaire, 0 étant le premier formulaire.- ou
document.forms['mon_formulaire']oùmon_formulaireest la valeur de l'attribut"id"de la baliseform, ou bien de l'attribut"name"en (X)HTML transitionnal. Il faut savoir que si la baliseforma les 2 attributs, c'est la valeur de l'attribut"id"qu'il faudra utiliser pour récupérer votre objet formulaire.
Ensuite, un objet formulaire contient une propriété elements
qui est une collection contenant les éléments de saisie du formulaire. On récupère
donc un élément du formulaire d'une de ces façons :
-
document.forms['mon_formulaire'].elements[n]oùnest le numéro de l'élément dans la collection, 0 étant le premier élément. - ou
document.forms['mon_formulaire'].elements['mon_element']oùmon_elementest la valeur de l'attribut"id"ou"name"de l'élément. Même remarque que pour les formulaires si il y a les 2 attributs, il faudra utiliser la valeur de l'attribut"id"pour récupérer l'élément.
Notre fonction valider() devient donc
function valider(){
frm=document.forms['frmSaisie'];
if(frm.elements['prenom'].value != "") {
return true;
}
else {
alert("Saisissez le prénom");
return false;
}
}
Ou encore
function valider(){
elt=document.forms['frmSaisie'].elements['prenom'];
if(elt.value != "") {
return true;
}
else {
alert("Saisissez le prénom");
return false;
}
}
C'est une méthode qui fonctionne sur tous les navigateurs. Tout comme la solution suivante.
Utilisation de this
Le mot clé this désigne toujours l'objet
courant. Si on l'utilise lors de l'appel de la fonction
valider() dans le "onsubmit",
on peut transmettre l'objet formulaire à la fonction valider() :
<script type="text/javascript">
//<![CDATA[
function valider(frm){
if(frm.elements['prenom'].value != "") {
return true;
}
else {
alert("Saisissez le prénom");
return false;
}
}
//]]>
</script>
<form onsubmit="return valider(this)" id="frmSaisie" ...>
...
</form>
À noter une petite astuce au passage : si vous avez
besoin de faire des manipulations du formulaire Javascript sur
des événements des champs de saisie ou de boutons, sachez que
les objets Javascript correspondants à ces éléments
HTML ont une propriété form
représentant l'objet formulaire. Voici un exemple d'utilisation :
<script type="text/javascript">
//<![CDATA[
function afficher(frm){
alert("Vous avez tapé : " + frm.elements['prenom'].value)
}
//]]>
</script>
<form>
<p>
<label for="prenom">Saisissez votre prénom :</label>
<input type="text" name="prenom" id="prenom" />
<input type="button" value="Afficher" onclick="afficher(this.form)" />
<input type="submit" value="Ok" />
</p>
</form>
Les commentaires dans la balise script
En théorie, le code situé entre les balises script,
doit être encadré par <![CDATA[ et ]]>.
C'est la manière en XHTML d'indiquer que le contenu représente des données.
En HTML, il faut utiliser les délimiteurs de commentaires HTML, à savoir
<!-- et -->, pour éviter que le code
javascript ne s'affiche dans les anciens navigateurs.
Pour que le contenu de la balise script en XHTML soit interpreté correctement, quel que soit le navigateur (pas trop vieux, de l'époque de IE6 par exemple), y compris donc ceux qui ne connaissent pas XHTML, il faut alors utiliser l'astuce suivante :
<script type="text/javascript"> //<![CDATA[ ... //]]> </script>
La façon la plus simple et celle qui garantie une parfaite compatibilité entre les navigateurs, est de mettre le script dans un fichier séparé :
<script type="text/javascript" src="nom_de_mon_fichier.js"></script>
Conclusion
Si la validation en JavaScript est pratique pour l'utilisateur, il convient de la
développer correctement de façon à rester compatible avec tous les types de navigateurs
et d'usages. Pour cela, le recours au bouton submit s'impose !