Les formulaires HTML5 dans Firefox 4
jeudi 19 mai 2011 - 6 commentaires
Firefox 4 est sorti il y a plus d'un mois (et il faut aller le télécharger d'ailleurs !). Parmi la liste des nombreuses améliorations, on trouve un bien meilleur support des formulaires HTML5. De nouveaux champs (email, url, tel, search), de nouveaux attributs (placeholder, autofocus, list), des formulaires découplés et différents mécanismes de validations. On doit principalement remercier Mounir Lamouri pour cela.
Cet article est basé sur celui publié en novembre sur hacks.mozilla.org
Précision: certains exemples fonctionneront dans d'autres navigateurs mais vous aurez besoin de Firefox 4 pour les voir tous.
Nouveaux types de champs
À l'instar des nouveaux éléments, HTML5 introduit de nouveaux types de champs pour mieux exprimer le genre d'informations que l'on souhaite recevoir. Le comportement et l'apparence de la plupart de ces nouveaux champs ne s'éloignent pas beaucoup du champ texte mais ils apportent un nouveau sens. Cela permet aux navigateurs de fournir une meilleure expérience aux utilisateurs. Par exemple, un navigateur mobile pourra fournir un clavier spécial pour certains champs[1]. Ou alors il pourra pré-remplir les champs téléphoniques en se basant sur votre carnet d'adresses. Et si ce n'est pas le navigateur, des extensions pourront imaginer d'autres usages en s'appuyant sur ces nouveaux champs.
Firefox 4 ajoute quatre nouveaux types de champs :
<input type="search">
<input type="tel">
<input type="url">
<input type="email">
Parmi ces quatre champs, url
et email
valideront aussi leur contenu. Mais on en parlera plus en détails plus loin.
Il y a aussi une nouvelle sorte de champ:
<output for="i1 i2">
Vous pouvez utiliser cet élément pour représenter une partie de la page qui réagit aux interactions avec le formulaire. Pensez au prix total dans un panier d'achats après avoir changé la quantité d'articles ou les options d'envoi. Ce champ ne calculera rien de lui-même, il faudra le faire avec JavaScript, mais cela donnera des indications aux technologies d'assistance. L'attribut for
est la liste des ID des éléments qui ont participé au calcul.
Les champs textes ont été améliorés par le support de <datalist>
. Cela permet de fournir une liste de suggestions à l'utilisateur pendant qu'il tape. On associe le champ et les suggestions en utilisant l'attribut list
. Et pour les navigateurs qui ne supportent pas ce mécanisme, ils afficheront le contenu de l'élément <datalist>
. Donc n'oubliez pas d'y mettre un balisage correct afin d'avoir une bonne dégradation.
<label>Entrez une ville : <input list="cities"></label>
<datalist id="cities">
ou
<label>choisissez-en une
<select>
<option value="Paris">Paris</option>
<option value="Londres">Londres</option>
<option value="Berlin">Berlin</option>
<option value="New York">New York</option>
<option value="Tokyo">Tokyo</option>
<option value="Sydney">Sydney</option>
<option value="Johannesburg">Johannesburg</option>
<option value="Melun">Melun</option>
</select>
</label>
</datalist>
Nouveaux attributs
Autofocus
Avec cet attribut sur un élément, il recevra le focus dès que possible. L'avantage direct pour l'utilisateur c'est que tous les sites utiliseront le même algorithme pour l'autofocus plutôt que d'avoir un bout de JavaScript différent sur chaque site. Et des navigateurs ou des extensions pourront facilement désactiver ce comportement si cela gêne l'utilisateur.
<input autofocus>
Placeholder
La valeur de cet attribut sera affichée lorsque le champ est vide et qu'il n'a pas le focus. Cela permet de donner un exemple de valeur attendue.
<label>Telephone: <input placeholder="+33 1 16 64 33 42"></label>
<label>Comments: <textarea placeholder="Dites nous ce que vous pensez de ce service…"></textarea></label>
Formulaires découplés[2]
Vous avez de nouvelles options pour configurer l'interaction entre les champs et les formulaires.
Attribut form
Les éléments <input>
ne doivent plus obligatoirement être des enfants d'un élément <form>
. Vous pouvez les définir où vous souhaitez et les rattacher à un formulaire en utilisant l'attribut form
. Sa valeur est l'ID du formulaire auquel il doit se rattacher.
Voyons un exemple. Disons que vous travaillez sur un moteur de recherche pour un outil de blog. Vous voulez un formulaire très simple pour le cas général et quelques options avancées si l'utilisateur a besoin de plus de contrôle.
En haut de votre page, vous pouvez placer:
<input type="search" name="search_field" form="search_form">
Et plus bas:
<form id="search_form" action="search.php" method="post">
<fieldset>
<legend>Options avancées</legend>
<input type="checkbox">Inclure les articles privés
<!-- Autres options -->
</fieldset>
</form>
Tout ceci se comportera comme si le champ de recherche faisait partie du formulaire. Mais vous avez la flexibilité de le placer où bon vous semble.
Les options de formulaires pour chaque champ
Toutes les options pouvant être définies au niveau du formulaire peuvent être redéfinies au niveau du champ. Tous les champs de soumissions (<button>
et <input type="submit">
) acceptent quatre nouveaux attributs : formenctype
, formaction
, formmethod
et formtarget
.
On peut imaginer les utiliser pour un formulaire avec des boutons publier et aperçu. Chacun a besoin des informations complètes du formulaire mais ils effectuent une action très différente.
<form action="new_post.php" method="post">
<label>Titre: <input type="text"></label>
<label>Contenu: <textarea></textarea></label>
<input type="submit" formaction="preview.php" formmethod="get" value="Aperçu">
<input type="submit" value="Publier">
</form>
Quand l'utilisateur clique sur le bouton Aperçu, ces attributs écraseront ceux du formulaire. Dans ce cas, au lieu d'une requête POST vers new_post.php, la totalité du formulaire sera soumise au script preview.php avec une méthode GET.
Mécanismes de validation
La validation est l'une des grandes améliorations des formulaires. Afin de fournir la meilleure expérience, il est de bon ton de donner un retour dès que possible à l'utilisateur. Du coup, chacun écrit beaucoup de JavaScript pour gérer cela. Ne serait-ce pas mieux que les navigateurs se débrouillent tous seuls ?
Depuis la parution de l'article original en novembre dernier, le style par défaut des champs invalides a été modifié et de nouvelles pseudo-classes ::-moz-ui-valid
et ::-moz-ui-invalid
ont été introduites. Du coup, les exemples ne sont plus aussi pertinents qu'à l'époque. Heureusement, Mounir a expliqué tous les changements.
required
Avec cet attribut, vous indiquez que ce champ est obligatoire. Pour les champs textes, cela signifie qu'ils ne doivent pas être vides. Pour les boutons checkbox, ils doivent être cochés. Et pour les boutons radios, l'un des boutons d'un groupe doit être sélectionné.
Essayez les exemples suivants pour voir les changements d'états.
<input type="text" required>
<input type="checkbox" required>
<input type="radio" name="radiogroup" required>
<input type="radio" name="radiogroup" required>
<input type="radio" name="radiogroup" required>
url
Les champs URLs sont automatiquement validés.
<input type="url" value="mozilla">
<input type="url" value="http://mozilla.org">
Les emails sont aussi validés automatiquement. En passant l'attribut multiple
(utilisable sur type="file"
aussi), il validera une liste d'emails séparés par des virgules.
<input type="email" value="foo">
<input type="email" value="foo@bar.org">
<input type="email" multiple value="foo@bar.org, spongebob">
<input type="email" multiple value="foo@bar.org, spongebob@squarepants.org">
pattern
Les URLs et les emails ne sont pas les seuls types de données que vous voulez valider. Pour cela, vous pouvez fournir une expression rationnelle JavaScript à l'attribut pattern
. Elle sera utilisée pour valider la valeur d'un champ. Il est aussi conseillé de fournir un attribut title
pour expliquer le type de contenu demandé.
Dans l'exemple suivant, survolez le champ. Vous devriez voir une aide vous expliquant comment remplir le champ.
<input pattern="[0-9][A-Z]{3}" title="A part number is a digit followed by three uppercase letters.">
L'API de validation des contraintes.
Si vous avez besoin d'encore un peu plus de contrôle sur la validation, vous pouvez utiliser la méthode setCustomValidity
. Si vous l'appelez avec une chaîne vide, l'élément sera considéré comme valide. Sinon, il sera marqué invalide et la chaîne sera utilisée dans l'aide apparaissant pour l'utilisateur.
<label>Mot de passe : <input type="password" id="password1" oninput="checkPasswords()"></label>
<label>Confirmer mot de passe : <input type="password" id="password2" oninput="checkPasswords()"></label>
<script>
function checkPasswords() {
var password1 = document.getElementById('password1');
var password2 = document.getElementById('password2');
if (password1.value != password2.value) {
password2.setCustomValidity('Les mots de passe ne sont pas identiques');
} else {
password2.setCustomValidity('');
}
}
</script>
Si l'un des champs dans un formulaire est invalide, la soumission du formulaire sera bloquée et le premier champ invalide sera mis en avant avec un message expliquant le problème. Si vous ne désirez pas ce comportement, vous pouvez ajouter l'attribut novalidate
sur le formulaire ou l'attribut formnovalidate
sur l'un des boutons de soumission.
Pour plus de détails sur le mécanisme de validation, je vous recommande l'article de Mounir.
Nouveaux sélecteurs CSS
Pour accompagner toutes ces magnifiques nouveautés, quelques nouveaux sélecteurs ne seront pas de trop.
:required, :optional
Tous les champs sont marqués :optional
par défaut. S'ils ont l'attribut required
, alors ils répondront à la pseudo-classe :required
.
:valid, :invalid
Ces pseudos-classes représentent l'état de validation d'un champ. Vous pouvez utiliser :invalid
pour redéfinir le style par défaut que Firefox 4 fournit.
Voici un exemple de champ avec le style par défaut modifié.
:-moz-placeholder
Cette pseudo-classe sélectionne les champs affichant un "placeholder". Ce n'est pas encore défini par CSS donc vous aurez besoin d'utiliser un pseudo-élément pour les navigateurs basés sur WebKit.
<style>
#selectors2 :-moz-placeholder {
font-style: italic;
}
#selectors2 ::-webkit-placeholder {
font-style: italic;
}
</style>
<form id="selectors2">
<input placeholder="Donnez moi du style !">
</form>
Conclusion
Les fonctionnalités HTML5 des formulaires sont très récentes et il y a encore de grandes différences entre les navigateurs. Opera a implémenté une partie de la spécification (elle s'appelait encore Webforms2 à l'époque) donc le support est plutôt bon même si vous trouverez des différences étant donné que la spécification a évolué depuis. Les navigateurs basés sur WebKit sont actuellement en train d'implémenter donc vous trouverez un peu de support de ce côté là aussi.[3]
Il n'y aura pas d'autres nouveautés concernant les formulaires dans Firefox 4. Mais il y a encore beaucoup à faire pour avoir un support complet: de nouveaux types de champs (number, color, date), de nouveaux attributs (step, min, max), etc. Cela viendra dans de prochaines versions.
Ceci n'est qu'une vague introduction. Pour tous les détails, je recommande la documentation sur le Mozilla Developer Network.
Notes
[1] Voir mon article sur le comportement de l'iPhone. D'ailleurs, Firefox 4 aussi s'adapte.
[2] Je n'ai pas trouvé mieux pour exprimer cette idée.
[3] Honnêtement, c'est implémenté n'importe comment mais je ne vais pas m'étendre.
Commentaires
Au passage, avec cet article, j'ai pu découvrir un petit bug sur les formulaires radios et required. Ouvert à 17h28, patch à 19h13, on attend la review et ça devrait être corrigé pour Firefox 6.
Salut,
Article très intéressant, merci :)
Dommage qu'il me faille déguiser Opera 11.11 en Internet Explorer 8 pour profiter du code en couleur :-/
@+
--
Pierre
Pierre: La coloration syntaxique marche bien pour moi avec Opera 11.11 sur Mac. J'utilise http://softwaremaniacs.org/soft/highlight/en/ (qui vient d'être mis à jour, je viens de le changer)
Par contre, les exemples sur une ligne sont tronqués sur Opera. Je ne sais pas pourquoi.
Ok, trouvé pour les morceaux de code tronqués, j'avais écrit du HTML invalide (</pre></code> au lieu de </code></pre>). Merci à Karl pour avoir vu ça très vite.
Article simple et très synthétique.. Utile pour savoir ce que ça apporte.. Hélas pour beaucoup il faudra attendra une plus grosse part des navigateurs compatible HTML5 pour mettre cela en pratique.
S.
Merci.
Je n'insiste pas trop sur ce point mais la plupart des fonctionnalités sont conçues pour bien s'adapter avec les navigateurs ne supportant pas les nouveautés. Au lieu de donner du JS à tout le monde, on peut utiliser ces nouveautés et faire de la détection de fonctionnalité en JS pour les navigateurs ne supportant pas. C'est flagrant avec la partie validation, c'est aussi le cas avec les nouveaux champs (qui sont considérés comme <input type="text"> si non reconnus).
Donc oui, tout n'est pas utilisable aujourd'hui mais, comme le reste de HTML5, ça a été conçu de manière progressive. On peut rajouter des petites touches ici ou là.