Le langage HTML fournit une interface permettant aux internautes de communiquer des informations au serveur web : les formulaires
Ils sont principalement utiles pour envoyer des données
(par la méthode POST
du protocole HTTP) :
poster un commentaire, s'authentifier sur un site…
Mais ils permettent aussi de spécifier des paramètres pour une page :
champ de recherche, contrôle de l'affichage du contenu (ordre, filtrage), etc.
(par la méthode GET
du protocole HTTP)
Ils fonctionnent exactement de la même manière pour les deux usages : des widgets (éléments d'interface) permettent à l'internaute de choisir des valeurs pour des « variables » spécifiées dans le code
form
On peut mettre des éléments classiques à l'intérieur (comme du texte, des paragraphes, des div
…), mais surtout des widgets
input
,
qui donne des résultats très différents en fonction de son attribut type
:
<form>
<input type="text" />
<input type="checkbox" />
<input type="radio" />
</form>
Les légendes des champs du formulaires doivent être placés dans des éléments label
(étiquettes)
Les labels doivent être explicitement associés à leurs champs : extrêmement important pour l'accessibilité et pour l'ergonomie !
<form>
<label>Ville : <input type="text" /></label>
<label>Capitale : <input type="checkbox" /></label>
</form>
for
, qui fait référence à l'id
du champ.
En général, la solution précédente suffit, est plus rapide à écrire et donne un code plus lisible.
<form>
<div>
<label for="ville">Ville :</label>
<input type="text" id="ville" />
</div>
<div>
<label for="cap">Capitale</label>
<input type="checkbox" id="cap" />
</div>
</form>
Un formulaire est inutile si on ne peut pas le soumettre
button
<form action="demo/recup.php">
<input type="text" value="Texte par défaut"/>
<button type="submit">Envoyer !</button>
</form>
submit
envoie les donnéesreset
remet tous les champs du formulaire à leur valeur par défautbutton
ne fait rien ! Utile pour les scripts côté clientLes données entrées sur les widgets servent à donner des valeurs à des variables
Il faut donner des noms à ces variables, pour que le serveur sache à quoi sert chaque donnée !
Jamais d'espace ou de caractère accentué dans le nom
name
pour cela
<form action="demo/recup.php">
<input type="text" value="Caen" name="ville" />
<input type="text" value="France" name="pays" />
<input type="checkbox" name="coche" />
<button type="submit">Envoyer !</button>
</form>
Attention au comportement des checkbox
Ne pas confondre les attributs name
et id
…
Pour renvoyer vers une autre page, il faut donner l'URL dans
l'attribut action
de l'élément form
Le navigateur a ajouté des paramètres d'URL, construits à partir des noms des widgets et des valeurs fournies par l'internaute
Dans cet exemple on renvoie vers une page qui fait quelque chose avec les paramètres :
<form action="demo/recup.php">
<input type="text" value="Caen" name="ville" />
<input type="text" value="France" name="pays" />
<input type="checkbox" name="coche" />
<button type="submit">Envoyer !</button>
</form>
Les paramètres d'URL ne conviennent pas à toutes les situations
On a souvent besoin d'envoyer des données au serveur
Dans ce cas, on peut spécifier que le navigateur doit utiliser la
méthode POST
de HTTP, en écrivant method="POST"
comme attribut de l'élément form
(la valeur par défaut de method
est GET
⇒ construit une URL paramétrée)
<form action="demo/recup.php" method="POST">
<input type="text" value="Caen" name="ville" />
<input type="text" value="France" name="pays" />
<input type="checkbox" name="coche" />
<button type="submit">Envoyer !</button>
</form>
La récupération des données côté serveur sort largement du cadre des cours TW1 et TW2. Cependant il est bon de comprendre dès maintenant la différence d'utilisation GET/POST
Dans les deux cas, cliquer sur le bouton submit
construit les couples
(clef, valeur) et les communique au serveur
N'importe quel programme peut être utilisé pour les récupérer : il suffit qu'il comprenne le protocole HTTP, ou qu'il puisse être lancé par le serveur lorsqu'un client demande l'URL en question (ex. : script PHP)
NB : une simple page HTML ne sait rien faire avec les paramètres d'URL, c'est le serveur qui va analyser les paramètres et modifier le HTML envoyé en fonction.
La récupération et l'utilisation des données envoyées au serveur est faite par un programme exécuté sur le serveur.
Module TW3 le Licence 3e année (S5)
Les boutons radio n'ont d'intérêt qu'en groupe : un seul peut être sélectionné
C'est l'attribut name
qui les groupe
value
<form action="demo/recup.php" method="POST">
Les formulaires HTML, vous êtes :
<label><input type="radio" value="oui" name="fan" /> Fan</label>
<label><input type="radio" value="non" name="fan" /> Pas fan</label>
<label><input type="radio" value="?" name="fan" /> NSPP</label>
<button type=submit>Envoyer !</button>
</form>
L'élément fieldset
permet de grouper des champs qui ont un rapport logique
entre eux
et de leur associer un label commun avec legend
<form action="demo/recup.php" method="POST">
<fieldset>
<legend>Les formulaires HTML, vous êtes :</legend>
<label><input type="radio" value="oui" name="fan" /> Fan</label>
<label><input type="radio" value="non" name="fan" /> Pas fan</label>
<label><input type="radio" value="?" name="fan" /> NSPP</label>
</fieldset>
<button type=submit>Envoyer !</button>
</form>
textarea
pour du texte sur plusieurs lignes
<form action="demo/recup.php" method="POST">
<textarea cols="30" rows="5" name="multi">Mettre du texte ici !</textarea>
<button type="submit">Go</button>
</form>
Propriété CSS resize
pour que l'internaute puisse modifier la taille
(valeurs : horizontal
, vertical
, both
)
Attention, contrairement à input
,
textarea
a une balise ouvrante et une balise fermante (le contenu
est utilisé comme valeur par défaut)
<form action="demo/recup.php" method="POST">
<label>Prénom<br>
<input type="text" size="10" name="prenom" value="Prénom" /></label>
<label>Commentaire<br>
<textarea cols="10" rows="5" name="comm">Votre commentaire…</textarea></label>
<button type="submit">Envoyer</button>
</form>
L'internaute doit effacer le contenu avant de taper
En règle générale, c'est plutôt une sorte de « mode d'emploi » qu'on voudrait
placeholder
:
<form action="demo/recup.php" method="POST">
<label>Prénom<br>
<input type="text" size="10" name="prenom" placeholder="Prénom" /></label>
<label>Commentaire<br>
<textarea cols="10" rows="5" name="comm" placeholder="Votre commentaire…"></textarea></label>
<button type="submit">Envoyer</button>
</form>
Le menu déroulant s'obtient avec l'élément select
, qui contient plusieurs éléments option
value
de chaque option
<form action="demo/recup.php" method="GET">
<select name="fruit">
<option value="fraise">Fraise</option>
<option value="pomme">Pomme</option>
<option value="raison">Raisin</option>
</select>
<button type="submit">Go</button>
</form>
optgroup
<form action="demo/recup.php" method="GET">
<select name="instrument">
<optgroup label="Bois">
<option value="clarinette">Clarinette (si♭)</option>
<option value="basson">Basson (ut)</option>
<option value="sax">Saxophone (mi♭)</option>
</optgroup>
<optgroup label="Cuivres">
<option value="trompette">Trompette (si♭)</option>
<option value="trombone">Trombone (ut)</option>
<option value="tuba">Tuba (fa)</option>
</optgroup>
</select>
<button type="submit">Go</button>
</form>
remarquer l'utilisation de value
(on n'utilise
pas les noms « compliqués » des instruments dans le code)
Améliore aussi l'accessibilité
Tout n'est pas modifiable par CSS dans les formulaires, notamment les menus déroulants…
input
:
utiliser les sélecteurs par attribut
input[type=text] {
border: 2px dotted green;
}
:focus
, sélectionne les éléments qui ont le focus, très utile pour les champs texte:checked
sélectionne les cases cochées, les boutons radio sélectionnés,
et les options choisies dans un menu déroulant (peut être détourné, un peu comme :target
, pour rendre les pages un peu dynamiques !):default
sélectionne les éléments qui sont dans leur état par défaut
(ex.: cases à cocher):valid
et :invalid
, pour styler les champs dont
la validation est correcte ou non:disabled
et :enabled
sélectionnent les éléments désactivés ou non
par l'attribut HTML disabled
:required
et :optional
sélectionnent
les élements obligatoires ou non (attribut HTML required
)Attention à width
: les widgets ont chacun leur propre interprétation. Préciser box-sizing: border-box;
pour être tranquille
Tous les détails sur le tutoriel de MDN
Le traitement des données envoyées (programmation côté serveur) est hors programme en L1
<form id="form-1" action="demo/recup.php" method="GET">
<label>Votre mot <input type="text" name="texte" id="texte" value="Texte par défaut"></label>
<button type="submit">Go</button>
</form>
<script>
document.getElementById("form-1").addEventListener("submit", affiche);
function affiche(event) {
let texte = document.getElementById("texte").value;
alert(texte.toUpperCase());
}
</script>
Le alert
bloque l'exécution
Mais ensuite les données sont envoyées
C'est bien si on veut continuer avec le traitement côté serveur
Mais c'est un problème si on veut continuer à travailler sur la page
Applications client : tout doit être exécuté dans le navigateur
submit
<form id="form-2" action="demo/recup.php" method="GET">
<label>Votre mot <input type="text" name="texte" id="texte" value="Texte par défaut"></label>
<button type="submit">Go</button>
</form>
<script>
document.getElementById("form-2").addEventListener("submit", affiche);
function affiche(event) {
alert("Bloquer la soumission du formulaire avec l'évènement submit et event.preventDefault()");
event.preventDefault();
}
</script>
Attention capter le clic sur le bouton "Envoyer" ne suffit pas !
Form
method
: méthode (POST/GET) utilisée
action
: valeur de l'attribut action
elements
: tableau non modifiable des éléments widgets du formulaire
submit()
: faire envoyer les données du formulaire
reset()
: remettre à zéro les champs du formulaire
reset
est déclenché quand le formulaire est réinitialisé
submit
est déclenché au moment de l'envoi des données
Propriété elements de l'objet Form
contient la liste des champs du formulaire
Accès à l'objet JS de chaque champ par son nom càd attribut name
Chaque champ est un objet JS dont la nature dépend du type de champ, par
ex. HTMLInputElement
pour les éléments input
Accès à la valeur du champ en temps réel avec sa propriété value (en lecture/écriture)
<form id="form-3" action="demo/recup.php" method="GET">
<label>Votre mot <input type="text" name="saisie" value="Texte par défaut"></label>
<button type="submit">Go</button>
</form>
<script>
document.getElementById("form-3").addEventListener("submit", affiche);
function affiche(event) {
event.preventDefault();
let formulaire = document.getElementById("form-3");
// syntaxe 1
let champ = formulaire.elements.saisie;
alert(champ.value);
// syntaxe 2
let champ2 = formulaire.elements['saisie'];
alert(champ2.value);
}
</script>
form
l'objet Form
dans lequel se trouve le champvalue
la valeur du champ en temps réelfocus()
donner le focus au champblur()
enlever le focus au champfocus
et blur
déclenché quand le champ reçoit/perd le focusinput
déclenché à chaque changement du champ (assez récent, attention ne marche pas avec les vieux navigateurs pour les select
et boutons radio/checkbox)change
déclenché quand un élément perd le focus et a changé de valeurRegarder en console pour avoir les messages
<form id="form-4" action="demo/recup.php" method="GET">
<label>Votre mot <input type="text" name="saisie" value="Texte par défaut"></label>
<fieldset>
<legend>Vos langages préférés</legend>
<label><input type="checkbox" value="HTML" name="prog" /> HTML</label>
<label><input type="checkbox" value="javascript" name="prog" /> Javascript</label>
<label><input type="checkbox" value="python" name="prog" /> Python</label>
<label><input type="checkbox" value="c" name="prog" /> C</label>
<label><input type="checkbox" value="java" name="prog" /> Java</label>
<label><input type="checkbox" value="swift" name="prog" /> Swift</label>
<label><input type="checkbox" value="cobol" name="prog" /> Cobol</label>
<br>
<button type="button" id="tout">Tout sélectionner</button>
</fieldset>
<button type="submit">Go</button>
</form>
<script>
let form4 = document.getElementById("form-4");
// le input texte capte le focus
form4.elements.saisie.addEventListener("focus", inputFocus);
function inputFocus(event) {
console.log("Le input a maintenant le focus");
}
// le input texte capte le blur
form4.elements.saisie.addEventListener("blur", inputBlur);
function inputBlur(event) {
console.log("Le input a perdu le focus");
}
// cocher tous les checkox
document.getElementById("tout").addEventListener("click", toutCocher);
function toutCocher(event) {
let cases = form4.elements.prog;
for (let i = 0; i < cases.length; i++) {
cases[i].checked = true;
}
}
// empêcher le submit et afficher les données du formulaire
form4.addEventListener("submit", demo);
function demo(event) {
event.preventDefault();
let texte = form4.elements.saisie.value;
console.log("Texte saisi : " + texte);
let checkboxes = form4.elements.prog;
let langages = "";
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
langages += checkboxes[i].value + " ";
}
}
console.log("Vous aimez les langages suivants : " + langages);
}
</script>
Essentiel bien comprendre event.preventDefault()
pour empêcher l'envoi des données et rester sur la page
DOM et Javascript fournissent tous les outils pour manipuler les formulaires et les données saisies
Il n'y a plus qu'à construire les applications !