Bien valider ses formulaires avec Javascript

  • Profil : Débutant, Expert
  • Technologie : DOM
  • Thème : Accessibilité, Pages dynamiques
  • Auteur : Laurent Jouanneau
  • Mise à jour : 14/05/2008

En bref

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.


Petit rappel sur les formulaires

Rappelons-nous d'abord de quoi est composé un formulaire :

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="#" 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 :

  1. 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 ;
  2. 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 :

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

  1. 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.
  2. 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 fonction valider() ne sera pas appelée dans ce cas.
  3. On évitera d'utiliser les méthodes propriétaires à Internet Explorer comme 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.

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é

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 :

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 !


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.