JavaScript : les formulaires

Dans les exemples des chapitres précédents l'utilisateur communiquait avec le programme grâce à des fonctions de JavaScript : prompt(), confirm(), alert(). Ce n'est pas très ergonomique ...

Si JavaScript est un excellent langage de programmation pour le Web il faut regretter que la gestion des entrées et sorties soit minimaliste ...

Heureusement dans HTML nous avons un outil formidable : le formulaire.
Il faut donc préférable de confier les entrées-sorties à un formulaire HTML, le traitement des données se faisant via un script.
Nous aurons donc dans la page web du CSS, du HTML et du JavaScript.

Premier exemple

Thème: l'utilisateur saisit un nom et un prénom et le script retourne la concaténation des deux.

Le code CSS et HTML

... <style> label, input, button {display : inline-block ; width : 45% ; height : 40px ; margin : 10px ; vertical-align : top ; } label {text-align : right ; } ... <form name ="f"> <label>votre nom : </label> <input type = 'text' name ="nom"> <label>votre prénom : </label> <input type = 'text' name ="prenom"> <label></label><button type = 'button' name ="bouton">Concaténez ! </button> <label>Nom et prénom : </label> <input type ='text' readonly name ="nom_prenom"> </form> ...

Commentaire du CSS

Dans un formulaire on utilise surtout les balises input, label, button. Ces balises sont par défaut de type inline alors que la balise form est de type block. Or nous voulons avoir la légende (balise label) du champ puis le champ de saisie (balise input) alignés. Il faut donc que ces balises deviennent de type inline-block c'est à dire des boites qui comme toutes les boites peuvent être dimensionnées mais qui se positionnent côté à côté tant qu'il y a de la place.

Ici chaque légende ou champ a une largeur interne de 45% de la largeur de la boite parente (FORM). Donc il y aura deux contrôles par ligne (la balise LABEL et la balise INPUT).

Commentaire du HTML

Les attributs action et method de la balise form sont ici inutiles puisque ce formulaire n'a pas pour objet d'envoyer les données saisies dans une autre page en vue d'un traitement PHP (avec éventuellement un stockage dans une base de données).

Astuce : notez une balise LABEL vide afin que le bouton de commande se positionne au dessous des champs de saisie.

Depuis HTML5 les boutons de commande peuvent être créés avec la balise double BUTTON.
Attention : le bouton doit être impérativement de type "button" car il est associé à une fonction JS. Si vous ne précisez pas le type d'un bouton il est par défaut de type "submit". Et alors dès que vous cliquez sur le bouton le contenu du formulaire est effacé ... donc vous ne voyez pas le résultat.
Notez pour le troisième input l'attribut readonly. Il est donc impossible de saisir dans ce champ, il est en lecture seule.

Dans le formulaire chaque INPUT et le bouton de commande sont nommés grâce à l'attribut name.
Ces noms seront utilisés dans le script.

Le script

Il est d'une simplicité déroutante !

	f.bouton.onclick = function () 
			{f.nom_prenom.value = f.nom.value +" "+ f.prenom.value}

Pour référencer dans le script un élément de formulaire j'ai utilisé une vieille technique, mais toujours valide, reposant sur la syntaxe : nomFormulaire.nomChamp.

Je rajoute ".value" quand je manipule le contenu d'un champ ou ".onclick" pour appeler une fonction sur clic.
Testez ce code !

Deuxième exemple

Nous saisissons un nombre (entier ou décimal) dans un champ puis le carré ce nombre s'affiche dans un deuxième champ du formulaire.

Le code CSS & HTML

La feuille de style interne est strictement identique à celle de l'exemple précédant. Donc je vous communique uniquement le code de la partie BODY

<form name ="f"> <label>Saisir un nombre :</label><input type = 'number' name ="nombre" > <label></label><button type = 'button' name ="bouton">Calculez le carré de ce nombre !</button> <label>Carré du nombre :</label><input type = 'text' readonly name ="carre"> </form>

Le premier INPUT est de type "number" donc on ne peut saisir dans ce champ que des valeurs numériques (impossible de saisir des lettres). Autre avantage ce champ accepte comme séparateur décimal la virgule ...
Tous les navigateurs récents ont implémenté le INPUT type number.

Le script

Encore une fois il est très succinct puisque le contrôle de saisie est effectué via le formulaire.

	f.bouton.onclick =function()
		{	
			var vnombre = f.nombre.value;
			f.carre.value = vnombre * vnombre;
		}

Le script ne présente aucune difficulté.
Essayez ce code !

Contrôle de saisie

Je vais maintenant évoquer l'emploi de JavaScript dans le cadre d'un formulaire de soumission c'est à dire un formulaire qui permet d'adresser des données en vue d'un traitement PHP, traitement qui modifie le plus souvent la base de données.
On reconnait un formulaire de soumission facilement ; les attributs action & method de la balise FORM sont alors obligatoires.

Dans ce type de formulaire avant toute tentative de soumission des données il faut procéder à un contrôle de saisie par le navigateur ou côté client.

Vous êtes en droit de penser que grâce à toutes ces nouveautés apportées par HTML5 & CSS3 on peut parfaitement effectuer un contrôle de saisie côté client sans avoir à recourir à JavaScript.
En effet pour vérifier si un champ n'est pas vide ou si la saisie correspond à un certain gabarit vous n'avez plus besoin de JavaScript ; il suffit d'utiliser les nouveaux attributs required et pattern de la balise INPUT.
Mais si vous devez comparer la saisie dans deux champs différents alors HTML, même version 5, ne vous est d'aucun secours puisque la notion de test n'existe pas dans ce langage. Mais heureusement il y a JavaScript !

Première thématique : inscription à un site

Pour vous inscrire sur un site de rencontres coquin (lol) vous devez saisir en guise d'identifiant votre adresse mail et la confirmer puis choisir un mot de passe et le confirmer.
Le mot de passe doit contenir entre 6 et 8 caractères alphanumériques c'est à dire des lettres non accentuées et des chiffres. Les autres caractères sont bannis.

Première solution : sans JavaScript

... <style> label, input, button {display : inline-block ; width : 44% ; height : 30px ; margin :10px 1% 10px 1% } input:invalid {color : red; } input:valid {color : lime ; } button:hover {color : red ; box-shadow : 5px 5px 5px grey ; } ... <form action = "inscription_trait.htm" method ='post'> <p>Vous devez saisir votre adresse mail en guise d'identifiant et choisir un mot de passe. <br>Le mot de passe est composé de lettres non accentuées et de chiffres ; entre 6 et 8 caractères</p> <label>Tapez votre adresse mail : </label> <input type = "email" required placeholder = "n'oubliez pas @" name ='mail1'> <label>Confirmez votre adresse mail : </label> <input type = "email" required name ='mail2'> <label>Saisissez mot de passe :</label> <input type = "password" required pattern ='[A-z0-9]{6,8}' maxlength ='8' placeholder = 'entre 6 et 8 lettres ou chiffres' name ='passe1'> <label>Confirmer le mot de passe : </label> <input type = "password" required pattern = '[A-z0-9]{6,8}' maxlength ='8' name ='passe2'> <label></label><button type = 'submit'> inscription</button> </form> ...

les données sont envoyées avec la méthode POST. En cas de succès de la soumission accès à la page "inscription_trait.htm" ;
Page qui réserve quelques surprises ...

Quatre "input" dont deux de type "email" et deux de type "password"
Les attributs name dans chaque input sont utiles que dans le cadre du traitement PHP (traitement qui ne sera pas évoqué).

Notez les pattern associés aux champs pour la saisie et confirmation du mot de passe.

D'après ce "pattern" seuls sont autorisés les lettres (majuscules et minuscules) non accentuées ainsi que les chiffres. Donc les lettres accentuées, les caractères de ponctuation, etc sont interdits.

On ne ne peut saisir plus de 8 caractères (maxlength ="8").

Test 1

Faites le test !

Bravo! vous accéder à la page "inscription_trait". Donc vous avez pu soumissionner avec succès.

Test 2

Faites le test !

Vous accéder quand même à la page "inscription_trait" alors que les deux adresses mail sont différentes et les deux mots de passe sont également différents ...
Vous découvrez à cette occasion les limites du HTML !

Solution avec un script (solution provisoire)

Grâce à JavaScript il sera possible de comparer la saisie 1 à la saisie2 et de comparer la saisie 3 à la saisie 4

Le code HTML

En effet il n'y a qu'un petit changement dans le code HTML.

<button type = 'button' onclick = 'fenvoi()'> inscription</button>

Le bouton de type "submit" est remplacé par un bouton de type "button" pour pouvoir appeler une fonction JavaScript. En effet un bouton de type "submit" ne permet pas d'appeler une fonction JS.

Le script

function fenvoi() { // création des variables objets var mail1 = document.querySelector('input') ; var mail2 = document.querySelectorAll('input')[1] ; var passe1 = document.querySelectorAll('input')[2] ; var passe2 = document.querySelectorAll('input')[3] ; var formulaire = document.querySelector('form'); // test if(mail1.value == mail2.value && passe1.value == passe2.value) { alert ('ok') ; formulaire.submit() ; } else alert('erreur de saisie') ; } // fin fonction

J'utilise les nouvelles méthodes de l'objet document pour référencer les champs de saisie.
Il suffit de savoir compter jusqu'à 4 puisqu'il y a quatre INPUT sachant que querySelector("input") référence le premier INPUT.
j'aurais pu écrire : document.querySelectorAll('input')[0] ; (emploi de "querySelectorAll" avec l'indice 0).

Test : si les deux adresses mail sont identiques et les deux mots de passe saisie sont identique alors soumission du formulaire (emploi de la méthode submit de JavaScript appliquée au formulaire).

Tests

Faites la batterie de tests !

Conclusion

En effet les contrôles de saisie HTML5 (attributs type et pattern) ne fonctionnent plus ici car le bouton de commande est de type button. !
Retenez bien. Pour que les contrôles de saisie HTML (créés grâce aux attributs pattern, type) fonctionnent il faut impérativement que le bouton d'envoi soit de type submit.

Solution définitive

Comment bénéficier simultanément des contrôles de saisie HTML et de ceux programmés dans le script ???
Il y a une astuce de codage que je vais évoquer maintenant.

Le code du formulaire (extraits)

<form name ="formulaire" action = "inscription_trait.htm" method ='post' onsubmit="return fenvoi()" > ... <label></label><button type ="submit"> inscription</button> </form>

J'ai donné un nom au formulaire : name ="formulaire".

Le bouton de commande est redevenu de type submit.

Donc on bénéficie à la fois des contrôles de saisie HTML et JS. C'est pas beau la vie !!!

Le script

function fenvoi()
{
	// variables
		var compteur = 0 ;
		var mail1 = formulaire.mail1.value;
		var mail2 = formulaire.mail2.value;
		var passe1 = formulaire.passe1.value;
		var passe2 = formulaire.passe2.value;
	// test
	if(mail1 == mail2) compteur++;
	if(passe1 == passe2) compteur++;
	if (compteur < 2) {alert("champs mal renseignés");return false; }
	if (compteur==2) {alert("saisies correctes"); return true;}
} // fin fonction 

J'ai utilisé une autre méthode pour référencer dans le script les champs du formulaire et qui repose sur la syntaxe : nomFormulaire.nomChamp. Il s'agit d'une technique aussi ancienne que le JavaScript mais qui est toujours valide.

La variable compteur est incrémentée à chaque fois qu'un test est vérifié.

Si compteur < 2 la fonction retourne FALSE et donc pas de soumission.
Si compteur ==2 (tous les tests vérifiés) la fonction retourne TRUE et donc soumission des donnés.

Tests

Premier essai :
Saisir : toto - toto- aaaa - aaaa
Les mails et mots de passe sont égaux entre eux mais ne correspondent pas aux "pattern" donc soumission bloquée.

Deuxième essai :
Saisir : toto@free.fr - toto@free.fr - abcedef -abcdef
Les mails et mots de passe sont identiques et le mail est correct (existence du caractère "@" dans la chaine).

Une adresse mail correcte c'est non seulement le caractère "@" mais aussi un point après ce caractère.
Donc dans le cadre d'un script "professionnel" il faudrait utiliser un pattern basé sur une expression régulière ... Faites les tests

Remarque importante

Un contrôle des saisies côté client (navigateur) ne dispense d'une vérification côté serveur (en PHP au niveau de la page cible).
En effet le JavaScript peut être désactivé par le navigateur.
Un utilisateur chevronné du Web peut accéder au code du formulaire et supprimer pour sa session les contrôles de saisie HTML.
En d'autres termes tous les contrôles côté client peuvent être rendus inopérants !
Retour menu