V. Améliorations de l'expérience utilisateur▲
Ce tutoriel ne traite pas des formulaires sous toutes leurs coutures. Je n'ai la prétention d'être un spécialiste ni de JavaScript (et ses déclinaisons) ni des feuilles de style. Cependant, il est toujours utile de savoir faire le minimum…
Notez que JavaScript, CSS et PHP sont des éléments totalement indépendants. Vous avez seulement besoin du code HTML pour le reste. La partie PHP est souvent indispensable, mais certaines situations permettent de s'en passer.
Vous pouvez l'habiller avec ce que vous voulez :
- HTML seul (nu)
- HTML + PHP
- HTML + CSS
- HTML + JS
- HTML + JS + CSS
- HTML + PHP + JS + CSS
- etc.
V-A. Les boutons « actualiser » et « précédent » du navigateur▲
Il faut prendre garde aux boutons « actualiser » et « précédent » du navigateur, car ils peuvent nous poser des problèmes. La solution la plus simple consiste à utiliser la méthode proposée par Ramazan Korkmaz (maximenet) dans son tutoriel : 8 commentaires .
Il s'agit simplement de réafficher la page avec la méthode GET, ce qui supprime les données POST et remplace la page actuelle de l'historique du navigateur.
La fonction header()▲
La fonction header() nous permet d'ordonner au navigateur de demander une autre page Web. Il convient de lui expliquer pourquoi nous lui donnons cet ordre, ce qui peut être fait à l'aide des en-têtes HTTP. Nous allons utiliser le code HTTP 303 : « voir autre [ressource] ».
Le mot clef exit nous assure que le navigateur ne chargera pas d'informations inutiles.
Dans les exemples de formulaire réparti sur plusieurs pages (présents dans de ce tutoriel), il faut empêcher l'exécution systématique de la commande echo implode() en la remplaçant par ceci :
Bien organiser son code▲
Afin d'obtenir un formulaire optimal, il est préférable d'effectuer dès que possible tous les traitements sur les données soumises par l'utilisateur. Cela permet d'enregistrer le contenu d'un formulaire dans une variable de session ou dans une base de données avant d'avoir envoyé quoi que ce soit au navigateur, nous permettant ainsi d'utiliser la fonction header().
V-B. Un peu de JS (JavaScript)▲
Dans certains cas, JavaScript peut être très utile dans les formulaires. D'après le W3C, un formulaire ne peut être envoyé que si tous les contrôles (ayant un nom et une valeur), ainsi que quelques exceptions, sont valides. Le bouton submit qui a été cliqué fait partie des contrôles qui doivent être valides pour que le navigateur envoie le formulaire.
Cela nous permet d'effectuer un traitement JavaScript en utilisant l'évènement onsubmit du bouton submit. La fonction JavaScript appelée permettra éventuellement d'invalider le bouton submit et ainsi de ne pas soumettre le formulaire. C'est particulièrement utilisé pour les mots de passe.
L'attribut HTML id est utilisé par la fonction JavaScript document.getElementById(). C'est celui que nous utiliserons, plutôt que l'attribut name qui est destiné à PHP (mais qui peut avoir la même valeur, ce qui est d'ailleurs assez courant).
Il faut toujours se souvenir que JavaScript est une technologie client, elle n'est donc pas exécutée dans l'environnement de confiance qu'est notre serveur Web. L'internaute peut désactiver le JavaScript ou s'arranger pour passer outre nos vérifications en JavaScript, ce qui fait que le script PHP ne devra absolument pas s'y fier. Les seules vérifications valides (point de vue sécurité) sont celles effectuées par le script PHP. Le script JavaScript ne permet que d'améliorer l'expérience utilisateur en évitant de soumettre un formulaire s'il n'est pas correctement rempli. Une vérification en JavaScript ne doit pas se substituer à une vérification en PHP, mais elle peut la compléter ou la renforcer. Il ne faut pas partir du principe qu'un formulaire reçu par PHP est un formulaire valide : l'internaute peut être en train de pirater (s'amuser avec) notre site.
Les évènements disponibles▲
Pour la balise : <form>
- onsubmit : Le formulaire est envoyé
- onreset : Le formulaire est réinitialisé à son état d'origine
Pour les contrôles : input et textarea
- onfocus : Gain du focus
- onblur : Perte du focus
- onselect : Du texte a été sélectionné
- onchange : La valeur a changé
Pour les contrôles : select, optgroup et option
- onfocus : Gain du focus
- onblur : Perte du focus
- onchange : La valeur a changé
Pour le contrôle : button
- onfocus : Gain du focus
- onblur : Perte du focus
Vérifier que le formulaire est complètement rempli▲
<form method
=
"post"
action
=
"<?php echo basename(__FILE__); ?>"
enctype
=
"multipart/form-data"
>
<label>
Nom d'utilisateur * :
<input type
=
"text"
name
=
"login"
/>
</label><br />
<label>
Adresse e-mail * :
<input type
=
"text"
name
=
"e_mail"
/>
</label><br />
<label>
Numéro de téléphone :
<input type
=
"text"
name
=
"phone"
/>
</label><br />
<label>
Adresse :
<input type
=
"text"
name
=
"address"
/>
</label><br /><br />
<input type
=
"submit"
value
=
"Envoyer"
/>
<input type
=
"reset"
value
=
"Rétablir"
/>
</form>
Les champs marqués d'une * sont obligatoires.
<?php
if
(!
empty($_POST
)){
//
// Debug
//
echo '<pre>'
;
print_r($_POST
);
echo '</pre>'
;
//
// Récupération normale des informations
//
$missing_fields
=
array
();
if
(empty($_POST
[
'login'
]
)){
$missing_fields
[]
=
'"login"'
;
}
if
(empty($_POST
[
'e_mail'
]
)){
$missing_fields
[]
=
'"e_mail"'
;
}
if
(empty($missing_fields
)){
echo 'Tous les champs ont été renseignés'
;
}
else
{
echo 'Les champs suivants doivent être remplis :<br />'
;
echo implode('<br />'
,
$missing_fields
);
}
echo '<br /><br />'
;
}
?>
<script type
=
"
text/javascript
"
language =
"
Javascript
"
>
function
is_filled
(
){
missing_fields =
''
;
if
(
document
.getElementById
(
"
login
"
).
value ==
""
){
missing_fields +=
"
\n 'login'
"
;
}
if
(
document
.getElementById
(
"
e_mail
"
).
value ==
""
){
missing_fields +=
"
\n 'e_mail'
"
;
}
if
(
missing_fields ==
""
){
return
true
;
}
else
{
alert
(
"
Les champs suivants doivent être remplis :
"
+
missing_fields);
return
false
;
}
}
</
script>
<?php
if
(!
empty($_POST
)){
//
// Debug
//
echo '<pre>'
;
print_r($_POST
);
echo '</pre>'
;
//
// Récupération normale des informations
//
$missing_fields
=
array
();
if
(empty($_POST
[
'login'
]
)){
$missing_fields
[]
=
'"login"'
;
}
if
(empty($_POST
[
'e_mail'
]
)){
$missing_fields
[]
=
'"e_mail"'
;
}
if
(empty($missing_fields
)){
echo 'Tous les champs ont été renseignés'
;
}
else
{
echo 'Les champs suivants doivent être remplis :<br />'
;
echo implode('<br />'
,
$missing_fields
);
}
echo '<br /><br />'
;
}
?>
<
form method
=
"
post
"
action
=
"
<?php
echo basename(__FILE__
);
?>
"
enctype
=
"
multipart/form-data
"
onsubmit
=
"
return is_filled();
"
>
<
label>
Nom d'utilisateur * :
<
input type
=
"
text
"
name
=
"
login
"
id
=
"
login
"
/
>
<
/label
><br /
>
<
label>
Adresse e-mail * :
<
input type
=
"
text
"
name
=
"
e_mail
"
id
=
"
e_mail
"
/
>
<
/label
><br /
>
<
label>
Numéro de téléphone :
<
input type
=
"
text
"
name
=
"
phone
"
id
=
"
phone
"
/
>
<
/label
><br /
>
<
label>
Adresse :
<
input type
=
"
text
"
name
=
"
address
"
id
=
"
address
"
/
>
<
/label
><br /
><br /
>
<
input type
=
"
submit
"
value
=
"
Envoyer
"
/
>
<
input type
=
"
reset
"
value
=
"
Rétablir
"
/
>
<
/form
>
Les champs marqués d'une * sont obligatoires.
Contrôler que les deux mots de passe sont identiques▲
<?php
if
(!
empty($_POST
)){
//
// Debug
//
echo '<pre>'
;
print_r($_POST
);
echo '</pre>'
;
//
// Récupération normale des informations
//
if
($_POST
[
'password_1'
]
!=
$_POST
[
'password_2'
]
){
echo 'Erreur de mot de passe'
;
}
else
{
echo 'Le mot de passe a été correctement saisi'
;
}
echo '<br /><br />'
;
}
?>
<
form method
=
"
post
"
action
=
"
<?php
echo basename(__FILE__
);
?>
"
enctype
=
"
multipart/form-data
"
>
<
label>
Nom d utilisateur : <
input type
=
"
text
"
name
=
"
login
"
/
></label
><br /
>
<
label>
Mot de passe : <
input type
=
"
password
"
name
=
"
password_1
"
/
></label
><br /
>
<
label>
Vérification : <
input type
=
"
password
"
name
=
"
password_2
"
/
></label
><br /
><br /
>
<
input type
=
"
submit
"
value
=
"
Envoyer
"
/
>
<
input type
=
"
reset
"
value
=
"
Rétablir
"
/
>
<
/form
>
<script type
=
"
text/javascript
"
language =
"
Javascript
"
>
function
check_password
(
field_1,
field_2){
if
(
document
.getElementById
(
field_1).
value !=
document
.getElementById
(
field_2).
value){
alert
(
'
Les mots de passe ne correspondent pas
'
);
return
false
;
}
else
{
return
true
;
}
}
</
script>
<?php
if
(!
empty($_POST
)){
//
// Debug
//
echo '<pre>'
;
print_r($_POST
);
echo '</pre>'
;
//
// Récupération normale des informations
//
if
($_POST
[
'password_1'
]
!=
$_POST
[
'password_2'
]
){
echo 'Erreur de mot de passe'
;
}
else
{
echo 'Le mot de passe a été correctement saisi'
;
}
echo '<br /><br />'
;
}
?>
<
form method
=
"
post
"
action
=
"
<?php
echo basename(__FILE__
);
?>
"
enctype
=
"
multipart/form-data
"
onsubmit
=
"
javascript: return check_password('password_1', 'password_2');
"
>
<
label>
Nom d utilisateur :
<
input type
=
"
text
"
name
=
"
login
"
id
=
"
login
"
/
>
<
/label
><br /
>
<
label>
Mot de passe :
<
input type
=
"
password
"
name
=
"
password_1
"
id
=
"
password_1
"
/
>
<
/label
><br /
>
<
label>
Vérification :
<
input type
=
"
password
"
name
=
"
password_2
"
id
=
"
password_2
"
/
>
<
/label
><br /
><br /
>
<
input type
=
"
submit
"
value
=
"
Envoyer
"
/
>
<
input type
=
"
reset
"
value
=
"
Rétablir
"
/
>
<
/form
>
V-C. Un peu de CSS (feuilles de style)▲
Les formulaires HTML ont une interface qui varie selon le navigateur utilisé et selon la configuration de ce navigateur (thèmes-skins, etc.) et cela ne correspond pas toujours à la charte graphique de notre site Web.
Les feuilles de style (CSS) sont là pour nous aider.
Nous utiliserons l'attribut HTML class pour définir l'apparence de nos formulaires.
<style type
=
"
text/css
"
>
/* BODY */
body {
color:
Black
;
background-color:
#DDEEFF
;
font-family:
Arial,
Verdana,
sans-serif
;
font-size:
13
px;
}
/* FORMULAIRE */
/* balises INPUT */
input {
background-color:
#FAFAFA
;
border-width:
1
px;
border-color:
#D1D7DC
;
color:
Black
;
font-style:
italic
;
}
/* balises spéciales dans le DIV des boutons */
#submit
input {
font-weight:
bold
;
font-style:
normal
;
background-color:
#D1D7DC
;
color:
Black
;
border-color:
Black
;
padding:
0
px 10
px 0
px 10
px;
border-width:
2
px;
}
/* le reste du DIV des boutons */
#submit
{
width:
400
px;
text-align:
center
;
}
/* FIELDSET : bloc du formulaire */
.form
fieldset {
border:
solid
;
border-width:
1
px;
border-color:
Black
;
width:
400
px;
padding:
15
px 10
px 10
px 10
px;
margin:
0
px 0
px 15
px 0
px;
background-color:
White
;
color:
Black
;
}
/* LEGEND : titre */
.form
legend {
border:
solid
;
border-width:
1
px;
border-color:
Black
;
padding:
5
px;
background-color:
#6389D8
;
font-weight:
bold
;
color:
White
;
font-size:
14
px;
}
/* LABEL : élements du formulaire */
.form
label {
display:
block
;
margin:
5
px 0
px 5
px 0
px;
text-align:
right
;
}
</
style>
<?php
if
(!
empty($_POST
)){
//
// Debug
//
echo '<pre>'
;
print_r($_POST
);
echo '</pre>'
;
}
?>
<
form method
=
"
post
"
action
=
"
<?php
echo basename(__FILE__
);
?>
"
class
=
"
form
"
>
<
fieldset>
<
legend>
Informations personnelles<
/legend
>
<
label>
Prénom : <
input type
=
"
text
"
name
=
"
personal[first_name]
"
/
></label
>
<
label>
Nom : <
input type
=
"
text
"
name
=
"
personal[last_name]
"
/
></label
>
<
/fieldset
>
<
fieldset>
<
legend>
Informations virtuelles<
/legend
>
<
label>
Pseudonyme : <
input type
=
"
text
"
name
=
"
virtual[nickname]
"
/
></label
>
<
label>
Site Web : <
input type
=
"
text
"
name
=
"
virtual[website]
"
/
></label
>
<
label>
Messagerie instantanée : <
input type
=
"
text
"
name
=
"
virtual[instant_messenger]
"
/
></label
>
<
/fieldset
>
<
div id
=
"
submit
"
>
<
input type
=
"
submit
"
value
=
"
Envoyer
"
/
>
<
input type
=
"
reset
"
value
=
"
Rétablir
"
/
>
<
/div
>
<
/form
>