En fouinant sur le web, on peut découvrir plusieurs pratiques pour appeler des scripts en Javascript qui vérifient le contenu d’un formulaire. Mais elles sont, hélas, rarement correctes dans le sens où beaucoup d’entre elles réduisent l’accessibilité et l’ergonomie des formulaires, voire sont inefficaces. Cet article vous propose de passer en revue ce qu’il faut faire et ne pas faire en la matière.
Rappelons-nous d'abord de quoi est composé un formulaire :
input,
select et textarea ;<input type="submit" /> et
<input type="reset" /> ;form qui encadre le tout ;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.
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="#" 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>
Il faut se mettre en tête que :
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 !
En fait, il n'existe qu'une seule méthode valable pour vérifier le contenu d'un formulaire en Javascript avant son envoi.
Le/les bouton(s) pour envoyer le formulaire doivent être :
<input type="submit" value="Ok" /> ;<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.
"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é.
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 fonction valider()
ne sera pas appelée dans ce cas.document.all pour 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.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.
formsL'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ù n est le
numéro de formulaire, 0 étant le premier formulaire.document.forms['mon_formulaire'] où
mon_formulaire est la valeur de l'attribut
"id" de la balise form,
ou bien de l'attribut "name"
en (X)HTML transitionnal. Il faut savoir que si la balise form
a 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ù n est le numéro de l'élément dans la collection,
0 étant le premier élément.document.forms['mon_formulaire'].elements['mon_element']
où mon_element est 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.
thisLe 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>
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>
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 !
Une question, une remarque ? Écrivez à l'auteur.
Page valide XHTML 1 Strict,
CSS2 et
accessible AA.
Ce site s'affiche mieux dans un navigateur conforme aux standards,
voici pourquoi.
Site hébergé par l'APINC
et propulsé par SPIP.