Ecriture et traitement de formulaires (côté HTML) - 1/2

Sommaire

  1. Partie 1 : Ecriture et Traitement de formulaires (côté HTML)
    1. Qu'est-ce qu'un formulaire ?
    2. Le formulaire : écriture syntaxique et sémantique
    3. Le formulaire : sécurité HTML
  2. Partie 2 : Ecriture et Traitement de formulaires (côté PHP)
    1. Méthodes de traitement des formulaires : GET et POST
    2. Sécurisation des données

Dernière m.à.j. : 2018-06-17

1. Qu'est-ce qu'un formulaire ?

Un formulaire n'est jamais qu'une suite de lignes HTML permettant au visiteur d'interagir avec le site : c'est une partie de site dans laquelle le visiteur n'est pas un simple élément passif à consulter ce que lui affiche le navigateur, mais qui permet au visiteur de soumettre une forme de demande. Le formulaire sert à entrer des données par le visiteur. Les données peuvent être de plusieurs natures, depuis une simple case à cocher lors d'un choix au fichier à télécharger en passant bien évidemment par l'entrée de texte.

Le formulaire est donc un objet qui se décompose en trois étapes :

  1. L'affichage sur le navigateur du client ;
  2. La saisie des valeurs par le visiteur, qui se termine par la soumission du formulaire ;
  3. Le traitement du formulaire (qui fera l'objet de la seconde partie de ce tutorial).

2. Le formulaire : écriture syntaxique et sémantique

Le formulaire présente une suite de balises qui permettent l'interaction du visiteur avec le site web visité. Selon le DocType choisi (HTML ou XHTML, Transitional ou Strict dans chacun des cas), certaines balises doivent respecter un style d'écriture propre.

Un formulaire affiche principalement les balises html suivantes :

  • <form></form> : délimite le début et la fin du formulaire
  • <fieldset></fieldset> : délimite un champ de données de même nature au sein d'un formulaire
  • <legend></legend> : la légende (libellé) d'un fieldset
  • <input> : une entrée d'objet (texte, case à cocher, fichier) ou un déclenchement d'action (button, submit)
  • <textarea></textarea> : zone de texte pouvant contenir plusieurs lignes
  • <label></label> : libellé (étiquette) d'un item de formulaire.
  • <select></select> : un menu déroulant

Les balises sont soummises à un doctype : les <input> n'ayant pas de fermeture se verront fermés par /> s'il s'agit d'un doctype XHTML. De même, leurs attributs auront leur valeur entourée de guillemets.

Dans un doctype Strict, les <input> ne peuvent pas hériter directement de la balise <form> : il faut un conteneur de type bloc (<p>, <fieldset>, <div>... ) entre elles.

2.1. Généralités sur les formulaires

Les formulaires se caractérisent par leur action, leur méthode et leur encodage. Respectivement désignées par action="...", method="..." et enctype="...", ces trois notions permettent de définir le type d'envoi de données et la façon de le faire.

Prenons ces attributs à tour de rôle.

  • action="..." : c'est la destination du formulaire : page (ou script) appelé lorsqu'on soumet le formulaire. C'est cette page qui recevra toutes les données du formulaire. Si vide : le formulaire sera envoyé à la page (courante) qui l'a affiché.
  • method="..." : method="post" ou method="get". La méthode "post" signifie que les valeur transmises seront cachées. Utiliser method="get" signifie que le contenu passera dans l'URL de la page : ?champ=valeur&champ2=valeur2 ... Beaucoup moins esthétique, surtout lorsqu'il y a des champs texte, des boutons, etc.
  • enctype : c'est l'encodage du formulaire. Si sous-entendu, il s'agit de "texte". Pour un envoi de fichier par exemple, il faut préciser enctype="multipart/form-data".

Le formulaire contient des balises qui permettent de délimiter des objets à envoyer : case de texte, case à cocher, bouton ... et chaque balise contient au moins 2 paramètres.

  • id="..." : c'est une chaine de caractères qui commence par une lettre et qui est unique au sein d'une même page HTML. Elle permet d'identifier la balise de formulaire sans ambigüité.
  • name="..." : c'est le nom de la variable à qui sera associée la valeur enregistrée par le visiteur

Ceci peut s'appliquer à toute balise HTML du formulaire.

2.2. Les balises et leur utilité

Il existe plusieurs types de balises permettant de mettre en place un formulaire. Nous détaillerons ici les principales ainsi que les attributs principaux.

  1. <fieldset>...</fieldset> : cette balise sert à encadrer un ensemble de champs pour visuellement (ainsi qu'ergonomiquement et sémantiquement) regrouper des objets de même connotation. Exemple : utiliser un fieldset pour les coordonnées personnelles (nom, prénom, adresse), un autre pour les coordonnées bancaires (banque, compte, rib) et un autre pour le choix du produit (quantité, couleur, taille ...). Cette délimitation n'est pas obligatoire mais apporte un plus sur l'aspect ergonomique, simplement parce que lorsqu'on est dans le fieldset des coordonnées, on ne trouvera pas de données relatives au compte bancaire.
  2. <legend>...</legend> : cette balise sert à donner un titre au fieldset. Concrètement, elle se place juste après l'ouverture de fieldset.
  3. <input> (ou <input /> si XHTML) : balise générique servant à l'entrée d'information. Elle possède plusieurs attributs qui sont :
    1. son type : button (bouton), submit (bouton de soumission du formulaire), text (texte simple), radio (case radio), checkbox (case à cocher), file (fichier).
    2. son id : c'est un attribut qui sert à identifier, de manière unique, chaque élément de page. Il peut avoir la même valeur que le "name" ou pas.
    3. son name : c'est le nom de la future variable qui sera envoyée au traitement
    4. sa value : valeur par défaut, que l'utilisateur peut changer
    5. readonly="readonly" : attribut de lecture seule : empêcher le changement de la value (à préciser si nécessaire)
    6. disabled="disabled" : pour désactiver cet élément (à préciser si nécessaire)
    7. checked="checked" : pour cocher un input uniquement lorsqu'il est de type radio ou checkbox.
    8. tabindex="..." : l'ordre de sélection des champs par la touche tabulation
  4. <textarea></textarea> : un champ de texte sur plusieurs lignes, dont on peut spécifier le nombre et la longueur par les attributs cols="XXX" et rows="YYY". Il possède les mêmes attributs que le <input> à l'exception du type.
  5. <select><option>...</option></select> : un menu déroulant présentant plusieurs <option>. Les options sont caractérisées par un texte et une valeur (attribut value). Il possède les mêmes attributs que le <input> à l'exception du type. une option peut avoir pour attribut selected="selected" si elle doit être choisie par défaut.
  6. <label>...</label> : cette balise sert à lier une légende à un objet de formulaire. Concrètement, ce n'est pas parce qu'on écrit "Votre nom :" et qu'on met en face un champ input qu'ils sont logiquement liés. La balise <label> permet de le faire : elle a un attribut for="..." dans lequel on met l'id de la balise de formulaire à laquelle on rattache le label (d'où l'importance de l'unicité d'un id). Cet aspect est un plus sémantique et ergonomique non négligeable.

N'oubliez pas de mettre un bouton <input type="submit" ...> avant votre balise </form>, de façon à permettre la validation du formulaire.

2.3. Quelques exemples (simplifiés) de formulaires avec balises

en doctype HTML transitional :

<form id="formulaire" method="post" action="">
	<label for="prenom">Prénom :</label><input type="text" id="prenom" name="prenom"><br>
	<label for="case_abo">Je veux m'abonner :</label><input type="checkbox" id="case_abo" name="abo" checked>
	<input type="submit" value="Enregistrer">
</form>

en doctype HTML Strict :

<form id="formulaire" method="post" action="">
	<p><label for="prenom">Prénom :</label><input type="text" id="prenom" name="prenom"></p>
	<p><label for="case_abo">Je veux m'abonner :</label><input type="checkbox" id="case_abo" name="abo" checked></p>
	<p><input type="submit" value="Enregistrer"></p>
</form>

en doctype XHTML transitional :

<form id="formulaire" method="post" action="">
	<p><label for="prenom">Prénom :</label><input type="text" name="prenom"><br />
	<label for="case_abo">Je veux m'abonner :</label><input type="checkbox" id="case_abo" name="abo" checked="checked" /><br />
	<input type="submit" value="Enregistrer" /></p>
</form>

en doctype XHTML Strict :

<form id="formulaire" method="post" action="">
	<p><label for="prenom">Prénom :</label><input type="text" id="prenom" name="prenom" /></p>
	<p><label for="case_abo">Je veux m'abonner :</label><input type="checkbox" id="case_abo" name="abo" checked="checked" /></p>
	<p><input type="submit" value="Enregistrer" /></p>
</form>

Voilà un premier exemple de formulaire très simple, il n'y a pas de traitement, c'est juste pour présenter un peu le style d'écriture. On remarque le checked="checked" en doctype XHTML, en effet il ne peut y avoir en XML d'attribut sans valeur (l' XHTML étant de l'HTML écrit en façon XML). On lui force donc une valeur ici qui est son nom.

Ce style de formulaire est très simple, mais bien loin d'être le meilleur. En effet, il y a tout un aspect ergonomique et un aspect d'accessibilité que nous n'avons pas traités parce que les informations récoltées ne me permettent pas d'illustrer *parfaitement* (disons, "mieux") les autres balises citées plus haut. Prenons alors un exemple plus costaud.

2.4. Illustration par l'exemple : formulaire de données simples

Pour illustrer l'utilisation de ces balises, je propose que nous construisions un autre formulaire ensemble. Il s'agit d'un sondage sur la qualité d'un objet (peu importe sa nature) qui demande des informations de plusieurs types. Nous l'écrirons par la suite en doctype XHTML Strict. Le formulaire est délimité par les balises (la méthode et l'action font l'objet d'autres paragraphes dans cet article) :

<form method="" action="">
</form>

Travail sur l'ergonomie.

Informations demandées (volontairement en désordre) :

  • nom,
  • âge,
  • prénom,
  • ville,
  • code postal,
  • adresse,
  • fréquence d'utilisation,
  • commentaire,
  • note sur 10,
  • demander à la personne si elle désire être tenue au courant des résultats du sondage.

On constate de prime abord qu'il y a des données que l'on peut aisément regrouper, car elles sont de nature sensiblement égale.

La balise HTML à utiliser pour ce faire est la balise <fieldset></fieldset> : cette balise délimite un champ dans lequel toutes les informations demandées sont de la même nature.

Dans le listing précédent, on identifie clairement les champs suivants :

  • informations personnelles
  • informations pratiques sur l'objet
  • informations annexes

Je choisirai donc de créer 3 fieldset avec leurs <legend> respectives:

<form>
	<fieldset>
		<legend>Informations personnelles</legend>
	</fieldset>


	<fieldset>
		<legend>Informations sur l'objet</legend>
	</fieldset>


	<fieldset>
		<legend>Informations annexes</legend>
	</fieldset>
</form>

D'autre part, il faut déterminer la meilleure solution en termes de balises pour faciliter au maximum l'interaction. Prévoir un menu déroulant pour la note finale est mieux que de prévoir une zone de texte où le visiteur serait supposé rentrer sa note (qui dit qu'il ne rentrera pas un chiffre absurde, voire un commentaire autre ? => cf § sécurisation)

Dans le listing effectué ci-dessus, nous aurons besoin :

  • d'<input> pour du texte (nom, prénom, âge, adresse, ville, cp)
  • de <textarea> pour du texte long - plusieurs lignes (commentaires sur l'objet)
  • de <select> pour la note finale
  • d'<input> pour une demande de confirmation (case à cocher)
  • bien sûr, les champs de formulaire seront étiquettés par le <label>

2.5. Exemple d'ébauche : formulaire et ergonomie

Voici donc notre formulaire complété, vu sous l'aspect ergonomique (et sémantique !) :

<form id="sondage" method="post" action="submit.php">
	<fieldset><legend>Informations personnelles</legend>
		<p>
			<label for="nom">Nom :</label>
			<input type="text" id="nom" name="nom" />
		</p>
		<p>
			<label for="prenom">Prénom :</label>
			<input type="text" id="prenom" name="prenom" /></p>
		<p>
			<label for="age">Age :</label>
			<input type="text" id="age" name="age" /></p>
		<p>
			<label for="adresse">Adresse :</label>
			<input type="text" id="adresse" name="adressse" /></p>
		<p>
			<label for="cp">Code Postal :</label>
			<input type="text" id="cp" name="cp" /></p>
		<p>
			<label for="ville">Ville :</label>
			<input type="text" id="ville" name="ville" /></p>
	</fieldset>


	<fieldset><legend>Informations sur l'objet</legend>
		<p>Fréquence d'utilisation quotidienne :<br />
			<input type="radio" id="j1" name="freq" value="1" />
			<label for="j1">1 fois</label>

			<input type="radio" id="j2" name="freq" value="2" />
			<label for="j2">2 fois</label>

			<input type="radio" id="j3" name="freq" value="3" />
			<label for="j3">3 fois</label>

			<input type="radio" id="j4" name="freq" value="4" />
			<label for="j4">4 fois</label>
		</p>

		<p><label for="note">Note (1 = excellent) :</label>
			<select id="note" name="note">
				<option value="1">1</option>
				<option value="2">2</option>
				<option value="3" selected="selected">3</option>
				<option value="4">4</option>
				<option value="5">5</option>
			</select>
		</p>

		<p>
			<label for="commentaire">Commentaire</label>
			<textarea id="commentaire" name="commentaire" cols="40" rows="5"></textarea>
		</p>
	</fieldset>


	<fieldset><legend>Informations annexes</legend>
		<p>
			<label for="email_rep">Me tenir informé(e) du résultat ?</label>
			<input type="checkbox" id="email_rep" name="email_rep" />
		</p>
	</fieldset>

	<div style="text-align:center;"><input type="submit" name="submit" value="Participer au sondage" /></div>
</form>

2.6. Exemple affiché

Ce qui donne l'exemple suivant : Voir le formulaire HTML

Il est tout à fait possible, comme c'est le cas sur ce site, d'appliquer une mise en forme CSS aux <legend>, aux <label>...

Je ne décrirai pas plus l'écriture d'un formulaire, pour avoir de plus amples notions à celle-ci, reportez-vous à l'article de L. Jouanneau sur OpenWeb.

3. Le formulaire : sécurité HTML

Le formulaire est une façon de permettre au visiteur d'interagir avec le site, mais il ne faut pas, pour autant, que le visiteur puisse faire n'importe quoi ...

Ce court paragraphe est juste là pour rappeler que même si il n'y a aucune sécurité en HTML (puisqu'il ne s'agit que d'un présentoir pour saisir les données), il n'y a pas non plus de sécurité en Javascript : on peut tout à fait tester que le champ "email" soit bien rempli, mais si le visiteur n'a pas Javascript, le test ne sera pas réalisé ... Il faut donc avoir recours à la sécurisation côté serveur.

Quoiqu'il en soit, on peut tout de même verrouiller un minimum les entrées d'un formulaire via l'HTML simplement, bien que ça ne consiste en rien à la sécurité des données entrées. Pour cela, il faut user d'un peu de sagacité et proposer les bonnes méthodes au visiteur (ceci est plus à but esthétique/ergonomique que sécuritaire d'ailleurs, par exemple sur un téléphone mobile, le clavier peut être adapté en fonction du type de saisie demandé en HTML) :

  • S'il y a un choix d'options, préférer une liste de cases radio (1 seule cochée parmi un groupe) ou de checkboxes (plusieurs peuvent être cochées dans un même groupe - je rappelle que les "groupes" de radio ou checkboxes se font par l'attribut name qui est envoyé, avec la value="..." comme valeur si spécifiée.
  • Dans le cas d'une saisie de chiffre ou de nombre, dans la mesure du possible, présenter un menu désoulant type Select. Date de naissance, année, ou encore notation, il est plus facile pour le visiteur de choisir dans un menu déroulant que d'entrer n'importe quoi à la main.
  • Pour éviter les textes à rallonges, préférer les <input type="text" /> aux <textarea> : les input text peuvent avoir une limite de caractères : <input type="text" id="..." name="..." maxlength="30" /> : on ne pourra pas saisir plus de 30 caractères dans ce champ texte.