Vous êtes sur la page 1sur 41

Numérique et Sciences informatiques

Représentation des données et concepts


de base de la programmation
● Langages de description de pages web : HTML, CSS
● Programmation web côté client : Javascript
● Gestion des événements dans une interface web

Objectifs 3
Environnement de travail 3
Notre page html exemple 3
Outils indispensables 3
Notion de client-serveur 3
C’est parti ! 4
Structure du projet 4
Squelette d’une page web 4
Html : qu’est-ce que c’est ? 5
Rappel rapide sur le Html 5
Flux et type de balises 5
Deux grands groupes de balises 6
Spécificités d'affichage 6
Niveau structurel et imbrications 6

HTML – CSS – JavaScript 1 sur 41


Composition Html 7
Formulaires et champs 7
Comportement du formulaire 10
Méthode GET 10
Méthode POST 10
Action 11
Les URL 12
Chemin absolu ou chemin relatif ? 13
Un peu de style 14
Les feuilles de styles (CSS) 15
Le code 15
Ordre 16
Les propriétés 16
Les unités de mesure 16
Les framework CSS 16
Commençons à améliorer notre page 17
Les grilles 19
Un exemple simple 19
Création de la grille 23
Javascript 25
Définition 25
Les standards 25
Validation des données 25
Le DOM, c'est quoi exactement ? 26
Comment le DOM est créé, et à quoi il ressemble 26
Le DOM n'est pas toujours exactement le code HTML source 27
Manipulation des classes CSS 30
Validation du format : les expressions régulières 33
Envoi du formulaire 39

HTML – CSS – JavaScript 2 sur 41


Objectifs

Les objectifs de cette partie sont multiples :

● bien comprendre la différence entre :


○ la structure (html)
○ le style (css)
○ le comportement (script)
● acquérir des compétences dans ces 3 domaines
● comprendre pourquoi il est important de bien séparer ces 3 domaines dans la gestion d’un projet
● maîtriser les outils d’analyse

Environnement de travail

Et afin de tous parler de la même chose, nous préconiserons l’utilisation de l’environnement de travail ci-
dessous à installer sur vos postes personnels :

● Google Chrome ou Firefox comme navigateur (ou tout autre navigateur moderne)
● L’éditeur de code Notepad++
Notre page html exemple

Le rendu final : https://formation.88bis.fr/nsi/bloc1/

Outils indispensables

Les outils de développement de votre navigateur Chrome ou Firefox. Vous les obtiendrez en pressant la
touche F12 dans votre navigateur.
Ils vous permettront de parcourir le code de la page, de consulter les règles CSS, de débugger Javascript et
bien d’autres choses.

Notion de client-serveur
Dans une architecture web classique, nous sommes dans une relation client-serveur. Dans notre petit
projet, la notion de serveur n’a pas d’importance et nous pourrons consulter notre page web directement
dans le navigateur en faisant “fichier > ouvrir” ou en faisant glisser notre fichier html directement dans le
navigateur.

HTML – CSS – JavaScript 3 sur 41


C’est parti !
Structure du projet
Commençons par créer la structure de notre petit projet dans votre dossier Documents.

● Compte-nsi
○ index.html
○ images
○ css
■ app.css
○ js
■ app.js

Ouvrons le fichier index.html dans Notepad++ puis copier/coller le codes suivant :

<!DOCTYPE html>
<html lang="fr">
<head>
<!-- l'encodage de votre page : quel jeu de caractères utilisez-vous ? -->
<meta charset="UTF-8">
<title>Formulaire de saisie</title>
</head>
<body>

</body>
</html>
Squelette d’une page web
Le squelette d’une page HTML ressemblera toujours à cela :

<!DOCTYPE html> Permet d'indiquer au navigateur que nous utiliserons la


dernière version du HTML, le fameux HTML5.
<html lang="fr"> La balise <html> est obligatoire, l'attribut lang="fr" permet
d'indiquer au navigateur que nous utiliserons le français pour
écrire notre page.
<head>
<meta charset="UTF-8"> L'en-tête qui contient, dans notre exemple, 2 balises : la
<title>Formulaire de balise <meta charset="utf-8"> qui permet de définir
saisie</title> l'encodage des caractères (utf-8) et la balise <title> qui
</head> définit le titre de la page

<body> Le corps du document dans lequel on trouvera le code HTML


… qui permettra d’afficher des choses dans notre page web.
</body>

</html>

HTML – CSS – JavaScript 4 sur 41


Html : qu’est-ce que c’est ?
Le HyperText Markup Language, généralement abrégé HTML ou dans sa dernière version HTML5, est le
langage de balisage conçu pour représenter les pages web. C’est un langage permettant d’écrire de
l’hypertexte, d’où son nom. HTML permet également de structurer sémantiquement et logiquement et de
mettre en forme le contenu des pages, d’inclure des ressources multimédias dont des images, des
formulaires de saisie et des programmes informatiques. Il permet de créer des documents interopérables
avec des équipements très variés de manière conforme aux exigences de l’accessibilité du web. Il est
souvent utilisé conjointement avec le langage de programmation JavaScript et des feuilles de style en
cascade (CSS). HTML est inspiré du Standard Generalized Markup Language (SGML). Il s'agit d'un format
ouvert.
Source : https://fr.wikipedia.org/wiki/Hypertext_Markup_Language

Tim Berners-Lee développe le premier navigateur web (logiciel permettant de lire des pages contenant des
hypertextes), il l'appelle simplement "WorldWideWeb". Il faudra attendre 1993 et l'arrivée du navigateur
web "NCSA Mosaic" pour que le web commence à devenir populaire en dehors du petit monde de la
recherche.
Techniquement le web se base sur trois choses : le protocole HTTP (HyperText Transfert Protocol), les URL
(Uniform Resource Locator) et le langage de description HTML (HyperText Markup Language). Nous
aurons, très prochainement l'occasion de revenir sur ces trois éléments.
Une chose très importante à bien avoir à l'esprit : beaucoup de personnes confondent "web" et "internet".
Même si le "web" "s'appuie" sur internet, les deux choses n'ont rien à voir puisqu'"internet" est un "réseau
de réseaux" s'appuyant sur le protocole IP alors que, comme nous venons de le voir, le web est la
combinaison de trois technologies : HTTP, URL et HTML. D'ailleurs on trouve autre chose que le "web" sur
internet, par exemple, les emails avec le protocole SMTP (Simple Mail Transfert Protocol) et les transferts
de fichiers avec le protocole FTP (File Transfert Protocol).

Rappel rapide sur le Html


● balises. En connaissez-vous ?
● attributs. En connaissez-vous ?
● sémantique
● flux

Flux et type de balises

Le flux correspond à l'écoulement des informations (ou données) dans le processus d'interprétation des
navigateurs. En toute logique, un navigateur commence par le haut de la page, place les éléments (balises)
qu'il rencontre les unes à la suite des autres, de gauche à droite puis de haut en bas.

HTML – CSS – JavaScript 5 sur 41


Deux grands groupes de balises

● Les balises de type BLOC ("block") comme les balises <p>, <ul>, <li>, <div>, <form>, <blockquote>,
<h1>...<h6>, ...
● Les balises de type EN LIGNE ("inline") comme <a>, <strong>, <em>, <span>, <img>, ...

Spécificités d'affichage

● Les blocs se placent toujours l'un en-dessous de l'autre (saut de ligne). Par exemple : une suite de
paragraphes ou une liste. De même par défaut, les boîtes de type bloc seront affichées dans une
succession verticale.
● Les “en ligne” se placent toujours l'un à côté de l'autre. Par exemple : la mise en gras d'une partie de
texte à l'aide de la balise <strong>

Niveau structurel et imbrications

● Une balise bloc peut contenir une (ou plusieurs) balise bloc et/ou inline, et peut avoir une
dimension (largeur, hauteur définies)
● Uane balise inline ne peut contenir QUE des balises inline, et n'a pas de dimension à proprement
parler (il n'occupe que la place minimum nécessaire à son contenu)

Une mise en page se fera donc à l'aide de balises blocs, la balise <div> étant la plus indiquée pour cet
usage.

La balise <div> est une balise neutre servant de conteneur, de zone (elle signifie Diviseur). Elle désigne une
boîte rectangulaire invisible que l'on peut configurer à souhait (position, couleurs, taille, ...).

Tout élément HTML possède une boîte rectangulaire qui délimite son contenu. Prenons l’exemple d’un
bloc. <div>Mon bloc</div>

Lorsque le navigateur dessine le bloc, il définit une boîte rectangulaire possédant plusieurs zones
distinctes.

Marge (margin)
Bordure (border)
Ajustement (padding)

Mon bloc

HTML – CSS – JavaScript 6 sur 41


Composition Html
Formulaires et champs

Commençons par créer 2 <div> qui serviront à :

● Entourer notre contenu.


● Délimiter notre contenu lui-même.

...
<body>

<div>
<div>
...
</div>
</div>
</body>

À l’intérieur nous allons pouvoir rentrer notre contenu : un titre général, un titre pour le formulaire et un
formulaire avec ses différents champs.

Imaginons que notre designer web ait préparé une maquette qui dispose d’un champ par ligne,
comprenant :

● Un libellé de champ.
● Le champ lui-même.
● Un petit texte explicatif.

On décide de délimiter chaque ligne avec une <div>. Comme il s’agit d’un bloc neutre mais de type bloc, il
sera facile de styliser les lignes.

Pour l’instant, entre le libellé, le champ et le texte explicatif, on va à la ligne avec la balise <br>.
<body>
<h1>Création de votre compte NSI</h1>
<form>
<div>
<div>
<h2>Fiche de renseignements</h2>
<div class="div-control">
<label for="nom">Votre nom</label><br>
<input type="text" id="nom" name="nom" aria-describedby="nom_aide"><br>
<small id="nom_aide">Entrez votre nom de famille</small>
</div>
...
Les autres champs
...
</div>
</div>

HTML – CSS – JavaScript 7 sur 41


</form>
Prenons le temps d’expliquer les balises et les attributs :
• La balise <form> est utilisée pour créer un formulaire HTML.
• La balise <label> permet de définir une étiquette. L’attribut for doit être égal à l’attribut id de
l’élément associé pour les lier.
• La balise <input> crée un champ qui permettra à l’utilisateur de saisir des données. L’élément
<input> dépend fortement de la valeur indiquée dans son attribut type.
• L’attribut id permet de cibler un élément grâce à sa valeur.
• L’attribut name sert à l’envoie du formulaire pour récupérer la valeur saisie.

Vous remarquerez que nous avons pris le temps de positionner un attribut aria-describedby qui concerne
l’accessibilité.

Cette notion est très importante pour rendre votre site ou application accessible au plus grand nombre.
Aux déficients visuels, par exemple.
Un clavier braille pourra comprendre ces instructions et aider dans la navigation.

Pour en savoir plus sur cette notion, rendez-vous ici :


https://developer.mozilla.org/fr/docs/Accessibilité/ARIA

Sur le même modèle, ajoutons maintenant les champs suivants :


● Nom
● Prénom
● Email
● Date de naissance
● Adresse
● Code postal
● Ville
● Téléphone

Ainsi qu’un bouton pour enregistrer le formulaire. On obtient :

<body>
<h1>Création de votre compte NSI</h1>
<form>
<div>
<div>
<h2>Fiche de renseignements</h2>

<div>
<input type="radio" id="genre1" name="genre" value="f">
<label for="genre1">Femme</label>
</div>

<div>
<input type="radio" id="genre2" name="genre" value="h">
<label for="genre2">Homme</label>

HTML – CSS – JavaScript 8 sur 41


</div><br><br>

<div>
<label for="nom">Votre nom</label><br>
<input type="text" id="nom" name="nom" aria-describedby="nom_aide"
class="champs_texte"><br>
<small id="nom_aide">Entrez votre nom de famille</small>
</div>

<div>
<label for="prenom">Votre prénom</label><br>
<input type="text" id="prenom" name="prenom" aria-describedby="prenom_aide"
class="champs_texte"><br>
<small id="prenom_aide">Entrez votre prénom</small>
</div>

<div>
<label for="email">Votre email</label><br>
<input type="text" id="email" name="email" aria-describedby="email_aide"
class="champs_texte"><br>
<small id="email_aide">Entrez votre adresse de messagerie principale</small>
</div>

<div>
<label for="daten">Votre date de naissance</label><br>
<input type="text" id="daten" name="daten" aria-describedby="daten_aide"
class="champs_texte"><br>
<small id="daten_aide">Entrez votre de date de naissance au format jj/mm/aaaa</small>
</div>

<div>
<label for="adresse">Votre adresse</label><br>
<input type="text" id="adresse" name="adresse" aria-describedby="adresse_aide"
class="champs_texte"><br>
<small id="adresse_aide">Entrez votre adresse (numéro + rue)</small>
</div>

<div>
<label for="cp">Votre code postal</label><br>
<input type="text" id="cp" name="cp" aria-describedby="cp_aide"
class="champs_texte"><br>
<small id="cp_aide">Entrez votre code postal (Ex : 44000)</small>
</div>

<div>
<label for="ville">Votre ville</label><br>
<select id="ville" name="ville" aria-describedby="ville_aide" class="champs_texte">
<option>Carquefou</option>
<option>La Chapelle-sur-Erdre</option>
<option>Nantes</option>
<option>Orvault</option>

HTML – CSS – JavaScript 9 sur 41


<option>Rezé</option>
<option>Saint-herblain</option>
</select><br>
<small id="ville_aide">Entrez votre ville</small>
</div>

<div>
<label for="tel">Votre numéro de téléphone</label><br>
<input type="text" id="tel" name="tel" aria-describedby="tel_aide"
class="champs_texte"><br>
<small id="tel_aide">Entrez votre numéro de téléphone</small>
</div>

<button type="submit" class="bouton_enregistrer">Enregistrer</button>

</div>
</form>
</body>

Comportement du formulaire

Il est peut-être temps de déterminer le comportement de notre formulaire. Pour cela nous allons
positionner 2 attributs sur la balise <form> :

● method="..."
● action="..."

La première détermine la façon dont nos données vont être envoyées pour traitement. Nous avons le choix
entre la valeur get et la valeur post.

Méthode GET

Avec la première méthode, les données du formulaire seront encodées dans une URL. Celle-ci est
composée du nom de la page ou du script à charger avec les données de formulaire empaquetée dans une
chaîne.
Les données sont séparées de l'adresse de la page pas le point d'interrogation et entre elles par le « et
commercial » (&).
Elle est également limitée en taille : env. 2000 caractères.

Méthode POST

Elle envoie un en-tête et un corps de message au serveur. Le corps est généralement constitué des
données entrées dans le champ de formulaire par l'utilisateur.

Les données du formulaire n'apparaissent pas dans l'URL. En conséquence, il n'est pas possible de
récupérer directement les données en JavaScript, il faut ajouter un traitement côté serveur.

Cette méthode est généralement à préférer car :

HTML – CSS – JavaScript 10 sur 41


● plus sécurisée
● permet de traiter les données non ASCII

Action

L’action détermine à quel endroit (quelle adresse ou quelle url) doivent être expédiées les données. Il s’agit
d’une url pointant vers un autre fichier.

S’il s’agit d’un fichier placé au même endroit que le fichier en cours qui contient le formulaire, il n’est pas
nécessaire de mettre toute l’url mais il faut cependant bien comprendre qu’un aller - retour sera fait sur le
serveur.

Ajoutons donc :

<form action="traitement.html" method="POST">

Et créons le fichier traitement.html qui servira uniquement de réception mais nous ne traiterons pas les
données, il faudrait pour cela un langage serveur. Nous verrons cela plus tard.

Contenu du fichier traitement.html :

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Traitement des données</title>
</head>
<body>
<h1>Traitement des données</h1>
<div>
Nous avons bien reçu vos données, merci !
</div>
<p>
<a href="index.html">&larr; Retour au formulaire</a>
</p>
</body>
</html>

Vous pouvez tester le formulaire et changer la méthode de ce dernier de POST à GET pour expérimenter la
façon dont sont passés les données.

HTML – CSS – JavaScript 11 sur 41


Les URL

Dans la barre d'adresse de votre navigateur web vous trouverez, quand vous visitez un site, des choses du
genre : "https://www.w3schools.com/tags/tag_html.asp".

• Le protocole est https.


• Le nom de domaine sur Internet de la machine est www.w3schools.com, le préfixe www étant le
nom usuel du dossier public sur un serveur Web.
• La partie "/tags/tag_html.asp " s'appelle une URL.

Une URL (Uniform Resource Locator) permet d'identifier une ressource (par exemple un fichier) sur un
réseau.
L'URL indique « l'endroit » où se trouve une ressource sur un ordinateur. Un fichier peut se trouver dans un
dossier qui peut lui-même se trouver dans un autre dossier...
Ici, le chemin vers la ressource sur le serveur : le fichier tag_html.asp qui se trouve dans le dossier tags
lui-même dans le dossier public www.

On parle d'une structure en arborescence, car elle ressemble à un arbre à l'envers :

Structure en arborescence

Comme vous pouvez le constater, la base de l'arbre s'appelle la racine de l'arborescence et se représente
par un /

Autre représentation un peu plus "jolie" :

HTML – CSS – JavaScript 12 sur 41


Structure en arborescence
Chemin absolu ou chemin relatif ?

Pour indiquer la position d'un fichier (ou d'un dossier) dans l'arborescence, il existe 2 méthodes : indiquer
un chemin absolu ou indiquer un chemin relatif. Le chemin absolu doit indiquer « le chemin » depuis la
racine. Par exemple l'URL du fichier fichier3.jpg sera : /dossier2/dossier3/fichier3.jpg

Remarquez que nous démarrons bien de la racine / (attention les symboles de séparation sont aussi des /)
Imaginons maintenant que le fichier fichier1.css fasse appel au fichier fichier3.jpg (comme un fichier HTML
peut faire appel à un fichier CSS). Il est possible d'indiquer le chemin non pas depuis la racine, mais depuis
le dossier (dossier2) qui accueille le fichier1.css, nous parlerons alors de chemin relatif :

dossier3/fichier3.jpg

Remarquez l’absence du / au début du chemin (c'est cela qui nous permettra de distinguer un chemin
relatif et un chemin absolu).
Imaginons maintenant que nous désirions indiquer le chemin relatif du fichier fichier5.svg depuis l'intérieur
du dossier dossier4.

Comment faire ?

Il faut "remonter" d'un "niveau" dans l'arborescence pour se retrouver dans le dossier dossier2 et ainsi
pouvoir repartir vers la bonne "branche" (vers le dossier3). Pour ce faire il faut utiliser 2 points : ..

../dossier3/fichier5.svg

Il est tout à fait possible de remonter de plusieurs "crans" : ../../ depuis le dossier dossier4 permet de
"retourner" à la racine.

À faire vous-même

Soit la structure en arborescence suivante :

HTML – CSS – JavaScript 13 sur 41


Donnez le chemin relatif permettant d'atteindre le fichier "fichier5.svg" depuis le dossier "dossier4".
__________________________________________________________

Donnez le chemin absolu permettant d'atteindre le fichier "fichier6.html".


__________________________________________________________

Remarque : la façon d'écrire les chemins (avec des slash (/) comme séparateurs) est propre aux systèmes
dits « UNIX », par exemple GNU/Linux ou encore Mac OS. Sous Windows, ce n'est pas le slash qui est
utilisé, mais l'antislash (\). Pour ce qui nous concerne ici, les chemins réseau (et donc le web), pas de
problème, c'est le slash qui est utilisé.

Un peu de style

Comme vous avez pu le constater, le formulaire fonctionne mais en termes de navigation et d’expérience
utilisateur, ce n’est pas terrible !

Il va falloir améliorer notre interface en stylisant notre page et le formulaire à l’aide des feuilles de styles
en cascade, les fameuses CSS.

Si ce n’est pas déjà fait, créons un nouveau fichier dans le dossier css que nous nommerons app.css.

Il faut également le lier à la page pour que les instructions que nous allons rentrer dedans soient
interprétées.

En haut de votre fichier index.html, entre les balises <head> … </head> :

<head>
<meta charset="UTF-8">
<title>Formulaire de saisie</title>
<link rel="stylesheet" href="css/app.css">

HTML – CSS – JavaScript 14 sur 41


</head>

Les feuilles de styles (CSS)

Les CSS (Cascading Style Sheets en anglais, ou « feuilles de style en cascade ») sont le code utilisé pour
mettre en forme une page web.

Le code

p {
color: yellow;
}

Comme le montre l’exemple ci-dessus, on écrit le CSS en désignant l’élément (ou les éléments) que l’on
veut styliser et on leur applique une déclaration. Cette dernière est composée d’un couple propriété /
valeur.

Ici :
● p est le sélecteur
● color: yellow; la déclaration
● color la propriété
● yellow la valeur

Ce petit bout de code signifie que toutes les balises html <p> auront la couleur jaune. Autrement dit que le
texte de tous les paragraphes sera jaune.

On peut insérer plusieurs déclarations dans un sélecteur. Par exemple :

p {
color: yellow;
border: 1px solid red;
}

Il est également possible d’attribuer ces déclarations à plusieurs sélecteurs en les séparant par une virgule.

p, h1 {
color: yellow;
border: 1px solid red;
}

Ici, les balises <p> et <h1> auront le texte de couleur jaune et un bord de 1px et de couleur rouge.

Les sélecteurs les plus utilisés :

<body>
<h1>Je suis un titre</h1>

HTML – CSS – JavaScript 15 sur 41


<p class="info">Voici un paragraphe</p>
<form id="formid">
<p>un autre paragraphe</p>
...

● Sélecteur d’élément : tapez l’élément lui-même => p ou a ou h1, etc.


● Sélecteur de classe : on utilise le point suivi du nom de la classe => .info
● Sélecteur d’id : on utilise l’hashtag => #formid
● Sélecteur descendant : on utilise un simple espace => #formid p

Ordre

Le code CSS est lu par le navigateur dans l’ordre où il est écrit, c’est à dire de haut en bas et si une
déclaration vient en contredire une autre, la dernière a préséance.
L’ordre de vos déclarations est donc important.
Les propriétés

Parmi les propriétés les plus utilisées, citons :

● color
● font -family / -size / -weight ...
● width / height
● background -color / -image / -position ...
● display
● position
● margin / padding
● border
● …

Il en existe des dizaines.

Les unités de mesure

● px
● em
● %
● vw et vh

https://www.w3.org/Style/Examples/007/units.fr.html

Les framework CSS

Un framework CSS est une bibliothèque permettant une conception Web plus simple et plus conforme aux
normes à l'aide du langage Cascading Style Sheets. La plupart de ces cadres contiennent au moins une
grille.

HTML – CSS – JavaScript 16 sur 41


Source: Wikipedia

Écrire du css peut vite devenir fastidieux. Sur de gros projets, il est compliqué de garder une organisation
claire du code tout en conservant l’ensemble des bonnes pratiques en termes de design (espacements,
cohérence des couleurs, des fonts, etc.).

De ce constat sont nés il y a un peu plus de 10 ans, des librairies permettant de s’affranchir de ces tâches.

Parmi les plus connus :

● Bootstrap
● Foundation
● Bulma
● Tailwind
● ...

Commençons à améliorer notre page

On veut mettre un bord bleu tout en haut de la page, avoir la même police de caractère sur toute la page
et le fond de la page doit être blanc.
/* Un bord bleu en haut de page */
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
border-top: 10px solid #0069D9;
background-color: white;
margin: 0;
}

Un peu d’espace sous le titre :


/* un peu d'espacement */
h1 {
margin-left: 10%;
}

On change la couleur du sous-titre :


/* une couleur différente pour le sous-titre */
h2 {
color:#0069D9;
margin-bottom:1em;
}

Un peu d’espacement, une autre couleur de fond et une ombre portée pour le formulaire :
/* un peu d'espacement et une ombre portée */
form {
margin-top: 1em;
padding: 1em;
background-color: #f6fbff;

HTML – CSS – JavaScript 17 sur 41


box-shadow: 0 0 10px rgba(0,0,0,.3);
}

Les deux boutons radios sont dans une balise <div> de type block. On veut qu’ils soient sur la même ligne.
On va transformer une balise de type block en balise de type inline. On commence par créer les règles de la
classe « bouton_radio » dans le code CSS :
/* les boutons radios sur une même ligne */
.bouton_radio {
display:inline;
margin-right:2rem;
}

Et on n’oublie pas de définir la classe dans les balises qu’on désire voir hériter de cette classe :
<div class="bouton_radio">
<input type="radio" id="genre1" name="genre" value="f">
<label for="genre1">Femme</label>
</div>

<div class="bouton_radio">
<input type="radio" id="genre2" name="genre" value="h">
<label for="genre2">Homme</label>
</div><br><br>

Avec les deux balises <br> on a créé de l’espace entre les boutons radios et le champs nom.

On va mettre en gras les libellés :


/* du gras pour les libellés et un peu d'espace */
label {
font-weight: bold;
line-height: 2em;
}

On va atténuer la couleur des textes d’aide. Ils sont dans des balises <small> qui se trouvent dans la balise
<form>. D’autres balises <small> en dehors du formulaire ne seraient pas affectées par le code suivant :
/* atténuation de la couleur des textes d'aide et un peu d'espace */
form small {
color:grey;
line-height: 2em;
}

On va aussi mettre de l’espace entre tous les champs (attention au point qui indique qu’on a affaire à une
classe :
/* un peu d'espacement entre les lignes du formulaire */
.div-control {
margin-bottom: 1.5rem;
}

HTML – CSS – JavaScript 18 sur 41


On va aussi customiser les champs texte :
/* On customise les champs texte */
.champs_texte {
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
width:90%;
height:35px;
border-radius: 8px;
border: 1px solid #c3c3c3;
}

Et le bouton enregistrer :
.bouton_enregistrer{
height:35px;
background-color:#157ffb;
border:none;
border-radius: 8px;
font-size: 16px;
color:white;
margin-left:45%;
}

Les grilles

Le module CSS Grid layout (modèle de disposition en grille) est un module de la spécification CSS qui
permet de créer des mises en page en divisant l'espace d'affichage en régions utilisables par une
application ou en définissant des relations de taille, position et d'empilement entre les éléments HTML.

Comme les tableaux, la grille permet d'aligner des éléments sous forme de colonnes et de lignes mais à la
différence des tableaux, la grille n'a pas de structure de contenu. Ainsi, on peut créer de nombreuses mises
en page qui n'auraient pas été possibles avec les tableaux. Ainsi, les éléments fils d'un conteneur en grille
peuvent être positionnés afin qu'ils se chevauchent ou qu'ils se comportent comme des éléments
positionnés.

Source : https://developer.mozilla.org/fr/docs/Web/CSS/CSS_Grid_Layout

Un exemple simple

Dans l'exemple qui suit, on montre comment utiliser une grille avec trois pistes en colonnes pour laquelle
les nouvelles lignes créées mesureront au moins 100 pixels et auront au plus la taille automatique (définie
par leur contenu). Les éléments sont placés sur la grille grâce aux numéros des lignes horizontales et
verticales.

HTML
<div class="wrapper">

HTML – CSS – JavaScript 19 sur 41


<div class="one">Un</div>
<div class="two">Deux</div>
<div class="three">Trois</div>
<div class="four">Quatre</div>
<div class="five">Cinq</div>
<div class="six">Six</div>
</div>

CSS
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column: 1 / 3;
grid-row: 1;
}
.two {
grid-column: 2 / 4;
grid-row: 1 / 3;
}
.three {
grid-column: 1;
grid-row: 2 / 5;
}
.four {
grid-column: 3;
grid-row: 3;
}
.five {
grid-column: 2;
grid-row: 4;
}
.six {
grid-column: 3;
grid-row: 4;
}

HTML – CSS – JavaScript 20 sur 41


HTML – CSS – JavaScript 21 sur 41
À faire vous-même

Dessinez sur l’image ci-dessous la grille qui compose notre page :

HTML – CSS – JavaScript 22 sur 41


Création de la grille

On crée notre grille à l’aide de classes dans le CSS :


/* Création de notre grille */
.grille {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: auto;
grid-auto-rows: auto, auto, auto, auto;
}
/* On définit chaque case de la grille */
.one {
grid-column: 1 / 4;
grid-row: 1;
}
.two {
grid-column: 4 / 7;
grid-row: 1;
}
.three {
grid-column: 1 / 3;
grid-row: 2;
}
.four {
grid-column: 3 / 5;
grid-row: 2;
}
.five {
grid-column: 5 / 7;
grid-row: 2;
}
.six {
grid-column: 1 / 4;
grid-row: 3;
}
.seven {
grid-column: 1 / 7;
grid-row: 4;
}

Il nous faut maintenant ajouter ces classes dans le code HTML.


On a déjà nos deux premières balises <div> à compléter :
<body>
<h1>Création de votre compte NSI</h1>
<form action="traitement.html" method="POST">
<div class="grille">
<div class="one">
<h2>Fiche de renseignements</h2>

HTML – CSS – JavaScript 23 sur 41


La class "one" s’arrête après le champ date de naissance. Il faut ensuite avoir la case 2 de la première ligne
pour accueillir l’image. On va donc fermer ici la balise </div> pour arrêter la première case et en rouvrir
une autre pour la case 2.

<div class="div-control">
<label for="daten">Votre date de naissance</label><br>
<input type="text" id="daten" name="daten" aria-describedby="daten_aide"
class="champs_texte"><br>
<small id="daten_aide">Entrez votre de date de naissance au format jj/mm/aaaa</small>
</div>

</div>

<div class="two">
<img src="images/illustration.svg">
</div>

On place les classes dans les balises <div> des autres champs en lui affectant le nom de la classe qui lui
convient en fonction de sa position dans la grille.
On pensera à créer une blaise <div> pour le bouton enregistrer afin qu’il soit lui aussi à sa place dans la
grille.

Maintenant que tout le monde est à sa place, on va réduire la taille de l’image :


/* taille de l'illustration */
form img {
width: 22vw;
max-width: 300px;
}

On aimerait aussi que cette image soit alignée au centre horizontalement et verticalement. On place le
code suivant dans le fichier CSS, dans ce qui correspond à la case de la grille où se trouve l’image.

justify-self: center;
align-self: center;

HTML – CSS – JavaScript 24 sur 41


Javascript
Définition

https://fr.wikipedia.org/wiki/JavaScript

Les standards

https://apprendre-a-coder.com/es6/

Validation des données

Maintenant que notre formulaire a pris forme, nous allons ajouter du code pour nous permettre de
contrôler les données que l’utilisateur rentre.

Pour ce faire, nous allons avoir besoin d’intercepter des événements sur le formulaire, clic, focus sur un
champs, etc.

Il est possible d’ajouter ces événements directement dans le formulaire html, par exemple :

<button type="submit" class="bouton_enregistrer"


onclick="alert('clic!')">Enregistrer</button>

Tester cet exemple.

Cela fonctionne parfaitement mais nous allons essayer d’avoir de bonnes pratiques en séparant
distinctement :

● la structure : html
● le style : css
● le comportement : javascript (ou autre langage)

Ainsi une modification fondamentale de l’un n’a pas d’incidences sur les autres.

Javascript permet d’accéder au DOM (Document Object Model) et ainsi d’ajouter des gestionnaires
d’événement.

HTML – CSS – JavaScript 25 sur 41


Le DOM, c'est quoi exactement ?

Le DOM (Document Object Model) est une interface pour vos pages web. C'est une API permettant aux
programmes de lire et de manipuler le contenu de la page, sa structure et ses styles.

Le cheminement d'un navigateur partant d'un document source HTML pour finalement afficher une page
stylée et interactive s'appelle le chemin critique du rendu (critical rendering path). Ce processus peut
comporter de nombreuses étapes mais celles-ci peuvent être regroupées en deux grandes étapes. La
première consiste en l'analyse du document par le navigateur pour déterminer ce qui sera finalement
rendu sur la page, et la seconde est le rendu par le navigateur.

La première étape permet de construire l'arbre de rendu (render tree), une représentation sous forme
d'arbre des éléments HTML qui seront rendus sur la page ainsi que leurs styles associés.

Comment le DOM est créé, et à quoi il ressemble

Le DOM est une représentation du document HTML source. Comme nous le verrons plus loin, il comporte
quelques différences, mais il s’agit pour l'essentiel d’une conversion de la structure et du contenu du
document HTML en un modèle objet utilisable par divers programmes.

La structure d'objet du DOM est représentée par ce qu'on appelle une "arborescence de noeuds" (node
tree). On l'appelle ainsi parce qu'il peut être considéré comme un arbre qui se ramifie en plusieurs
branches enfants, chacune pouvant avoir des feuilles. Le premier parent est l'élément racine <html> , les
"branches" enfants sont les éléments imbriqués et les "feuilles" sont le contenu des éléments.

HTML – CSS – JavaScript 26 sur 41


Prenons par exemple ce document HTML :
<!doctype html>
<html lang="fr">
<head>
<title>Ma prmière page web</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>Comment allez-vous ?</p>
</body>
</html>

Ce document peut être représenté comme une arborescence de nœuds :

Le DOM n'est pas toujours exactement le code HTML source

Bien que créé à partir du document source HTML, le DOM n'en est pas toujours l'exact reflet. Il peut en
différer dans deux cas :

1. Lorsque le HTML n'est pas valide

Le DOM est une interface pour les documents HTML valides. Pendant le processus de création du DOM, le
navigateur peut être amené à corriger des informations invalides.

Prenons ce document HTML par exemple :


<!doctype html>
<html>
Hello, world!

</html>

HTML – CSS – JavaScript 27 sur 41


Il manque les éléments <head> et <body> à ce document, alors qu'ils sont requis dans un HTML valide. Si
nous inspectons l'arborescence créée, nous pouvons constater que l'erreur a été corrigée :

2. Lorsque le DOM est modifié par JavaScript

En plus d'être une interface permettant de visualiser le contenu d'un document HTML, le DOM peut être
modifié, ce qui en fait une ressource vivante.

Nous pouvons par exemple créer des nœuds supplémentaires via JavaScript.
var newParagraph = document.createElement("p");
var paragraphContent = document.createTextNode("I'm new!");
newParagraph.appendChild(paragraphContent);
document.body.appendChild(newParagraph);

Le DOM sera mis à jour, mais bien entendu notre document source HTML restera inchangé.

À faire vous-même

Représenter l’arbre de rendu du DOM de notre page HTML

HTML – CSS – JavaScript 28 sur 41


========= LIEN VERS LE SCRIPT ====

Nous allons créer un dossier js dans le même dossier contenant le fichier index.html. Dans le dossier js, on
va créer un fichier app.js.

Il nous faut dire au fichier index.html qu’il y a un fichier js dont il faut tenir compte.

On va écrire la ligne suivante dans le <head> de notre fichier index.html :

<script type="text/javascript" src="js/app.js" async></script>

L’attribut async permet de charger et lancer l'interprétation de code JavaScript après avoir chargé le code
HTML, c’est à dire sans bloquer le rendu HTML (son affichage à l'écran).

Dans le fichier app.js, commençons par définir une constante qui ciblera un élément en particulier, le
champ email par exemple :

const email = document.getElementById('email')

Attention : la méthode getElementById cherche un élément avec l’id spécifiée, cela implique que nous
ayons bien placé un attribut id=”email” dans le code html.

Puis ajoutons un écouteur d’événement en ciblant “la perte du focus” dans le champ. Cela signifie que
l'événement sera déclenché lorsque le champ email perdra le focus (qu’il aura donc reçu au préalable par
un clic ou une navigation clavier avec TAB).

email.addEventListener('blur', <listener>)

D’après la documentation (https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener)


le premier argument est le type d’événement ciblé “blur” (perte de focus) pour nous et le deuxième sera
une fonction qui représente la conséquence de l’événement.

Plaçons-y un alert() pour constater que cela fonctionne :

email.addEventListener('blur', function (event) {


alert("Vous avez quitté le champ")
});

function (event) {alert("Vous avez quitté le champ")} : ici, on a créé une fonction qui n’a pas de nom.
Entre les parenthèses, on trouve l’argument de la fonction créée et entre les accolades, on trouve le corps
de la fonction.

HTML – CSS – JavaScript 29 sur 41


Manipulation des classes CSS

Maintenant que nous savons utiliser le gestionnaire d’événements, nous allons manipuler les éléments du
DOM pour en changer l’apparence en fonction du résultat d’un événement.

Pour ce faire, il nous faut repasser par le CSS pour préparer deux classes qui représenteront
(graphiquement parlant) les états d’un champ :

● la classe valid avec un design vert


● la classe invalid avec un design rouge

/* champ avec la class "valid" : vert avec un icone de validation */


input.valid {
border-color: #28a745;
background-image: url(../images/tick.svg);
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 1.2em;
}
/* champ avec la class "valid" : rouge avec un icone d'exclamation */
input.invalid {
border-color: #dc3545;
background-image: url(../images/exclamation.svg);
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 1.2em;
}

Peut-on simplifier ces règles ?

Il y a des règles qui se répètent et que l’on peut écrire dans une seule règle qui s’appliquera aux deux
classes :

/* champ avec le commun des class "valid" et "invalid" */


input.valid, input.invalid {
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 1.2em;
}

HTML – CSS – JavaScript 30 sur 41


On peut ensuite ajouter les règles qui sont spécifiques à chaque classe :

/* champ avec la class "valid" : vert avec un icone de validation */


input.valid, input.invalid {
border-color: #28a745;
background-image: url(../images/tick.svg);
}
/* champ avec la class "invalid" : rouge avec un icone d'exclamation */
input.invalid {
border-color: #dc3545;
background-image: url(../images/exclamation.svg);
}

Maintenant, sur l’événement « perte du focus », testons la valeur du champ. Si ce dernier est vide
ajoutons-lui la classe CSS « invalid » sinon la classe « valid ».
Nous utiliserons la propriété classList de l’élément du DOM et sa méthode « add » :

email.addEventListener('blur', function (event) {


if(email.value=='') {
email.classList.add('invalid')
} else {
email.classList.add('valid')
}
});

Testons cela ! Est-ce que cela fonctionne ? N’y a-t-il pas un problème ?

Maintenant nous allons ajouter un message lorsque le champ passe en “invalid”. Il faut tout d’abord
insérer une nouvelle balise html de cette façon :

<div class="div-control">
<label for="email">Votre email</label><br>
<input type="text" id="email" name="email" aria-describedby="email_aide"
class="champs_texte"><br>
<small class="help" id="email_aide">Entrez votre adresse de messagerie
principale</small>
<small class="error">Votre adresse email est requise</small>
</div>

L’idée étant d’afficher seulement le premier <small> avec la classe “help” (à rajouter si vous ne l’avez pas
fait) lorsque tout est valide et seulement le deuxième si le champ est marqué “invalid”.

HTML – CSS – JavaScript 31 sur 41


On peut faire cela avec CSS uniquement. Essayer par vous-même.

On pourra penser au combinateur " ~ " qui permet de sélectionner les nœuds qui suivent un élément et qui
ont le même parent.
Syntaxe : A ~ B
Exemple : p ~ span permettra de cibler les éléments <span> qui suivent (immédiatement ou non) un
élément <p> et qui ont le même élément parent.

On pensera aussi à la propriété display qui peut prendre pour valeur "none" pour ne pas afficher un
élément ou la valeur "block" qui permet à un élément d’être affiché et de type block.

Pour rappel en CSS, c’est la dernière déclaration qui a préséance et donc l’ordre est important.

input ~ .error {
display: none;
}
input.valid ~ .help {
display: block;
}
input.valid ~ .error {
display: none;
}
input.invalid ~ .help {
display: none;
}
input.invalid ~ .error {
display: block;
color: #dc3545;
}

• On rend invisible toutes les balises qui sont de la classe « error » et qui suivent une balise <input> dans
la même balise <div>.
• On rend visible toutes les balises qui ont la classe « help » et qui suivent une balise <input> de classe
« valid » à l’intérieur d’une même balise <div>.

Si tout est correct et comme nous savons mettre en place le gestionnaire d’événement sur un élément en
particulier nous pouvons répéter l’opération pour tous les champs.

Cependant, nous pouvons essayer de rendre notre validation plus générique en associant un événement
sur chaque champ avec une boucle :

On remplace notre constante par une requête qui cible tous les champs de type “text”, “email” :
const inputs = document.querySelectorAll('input[type="text"], input[type="email"]')

inputs est un tableau contenant les objets ci-dessus.

HTML – CSS – JavaScript 32 sur 41


Nous allons maintenant boucler sur le résultat de cette requête pour associer un événement à chaque :
inputs.forEach(item => {

item.addEventListener('blur', function() {
if(item.value=='') {
item.classList.remove('valid')
item.classList.add('invalid')
} else {
item.classList.remove('invalid')
item.classList.add('valid')
}
})

})

Notez qu’en ES6, item => {} est la forme courte de function (item) {}

inputs.forEach() : la méthode « forEach() » va parcourir chaque élément du tableau « inputs » et exécute


la fonction qui se trouve entre les parenthèses à chaque élément du tableau « inputs ».

addEventListener() : La méthode addEventListener() installe une fonction à appeler chaque fois que
l'événement spécifié est envoyé à la cible.

Testez le formulaire. Tous les champs devraient être “invalides” s’ils sont vides à la perte du focus et
retrouver leur classe « valid » sinon.

Validation du format : les expressions régulières

Nous aimerions améliorer notre système de validation en prenant en compte le format attendu dans le
champ.

Nous allons faire appel à un concept nommé “les expressions régulières” dont voici la définition :
https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re

Les expressions régulières ne sont pas propres à Javascript, elles sont implantées dans la plupart des
langages de programmation et permettent un gain de temps dans la recherche et le remplacement d’une
chaîne de caractères en la décrivant plutôt qu’en l’écrivant.

Tous les bons outils de recherche les implémentent, c’est probablement le cas de votre éditeur de code.

Cours sur le sujet : https://openclassrooms.com/fr/courses/1916641-dynamisez-vos-sites-web-avec-


javascript/1920128-les-expressions-regulieres-partie-1-2

HTML – CSS – JavaScript 33 sur 41


Au premier abord, les expressions régulières semblent compliquées car on obtient des chaînes de
description comme :

^(0[1-9]|[1-2]\d|3[0-1])\/(0[1-9]|1[0-2])\/([1-2]\d{3})$

Mais une fois que l’on a compris la logique et appris les métacaractères les plus utilisés, il n’y a rien de bien
compliqué pour une puissance inégalée.

Voici un petit mémo des métacaractères :

Les métacaractères / ancres Les classes de caractères

• ^ accent circonflexe : marque le début d'une • [ ] les crochets : indique une classe.
chaîne (voir classe aussi).
• - le tiret : indique l'intervalle dans une classe.
• $ dollar : marque la fin d'une chaîne.
Memo :
Memo :
[a-z] : reconnaît les lettres de a à z.
^chat$ : reconnaît chat seul. [Yy]ves : reconnaît un mot avec ou sans majuscule.
^$ : reconnaît chaîne vide. <h[1-6]> : reconnaît une balise de titre par
^ : début de chaîne. exemple.
$ : fin de chaîne.

L'alternative La classe complémentée

• | barre verticale : marque l'alternative. • [^... ] au lieu de [...] : indique une classe
complémentée. Reconnaît tout caractère
Memo : qui n'est pas énuméré.
L[y|i]s : reconnaît Lys ou Lis.
Memo :
^(De|Sujet|Date):@ : reconnaît tout ce qui
commence par De:@ ou Sujet:@ ou Date:@. [^0-9] : reconnaît tout ce qui n'est pas des chiffres.
[^1-6] : reconnaît tout sauf les chiffres de 1 à 6.

Rappel : l'accent circonflexe est un métacaratère à


l'intérieur de la classe. À l'extérieur, c'est une
ancre qui signifie le début de...

HTML – CSS – JavaScript 34 sur 41


Les quantificateurs Le tiret

• ? point d'interrogation : Facultatif, zéro ou • - indique un intervalle dans une classe [0-9].
une occurrence.
• * étoile : Facultatif, zéro, une ou plusieurs Rappel : Le tiret est un métacaractère à l'intérieur
occurrences. d'une classe à condition qu’il exprime bien un
• + signe plus : Obligatoire, une ou plusieurs intervalle.
occurrences. Pour utiliser le tiret en tant que littéral à l'intérieur
• {x} accolade + nombre : Obligatoire d'une classe, soit le placer au début, soit en fin de
restrictif doit apparaître exactement x fois. classe [-0-9] ou [0-9-].
• {x,} accolade + nombre : Obligatoire non À l'extérieur d'une classe le tiret est un caractère
restrictif, doit apparaître au moins x fois. normal.
• {x,y} accolade + nombre : Obligatoire
restrictif, doit apparaître exactement x fois
et maximum y fois

Memo :
a? reconnaît 0 ou 1 a
a* reconnaît 0 ou plusieurs a
a+ reconnaît 1 ou plusieurs a
Les types génériques Les parenthèses

• \d : Trouve un caractère décimal (un chiffre). • ( ) : encadrer les instructions, capture de


• \D : Trouve un caractère qui n'est pas décimal sous-chaînes.
(donc pas un chiffre).
• \s : Trouve un caractère blanc. Rappel : Les parenthèses en dehors de leur
• \S : Trouve un caractère qui n'est pas un fonction d'encadrer les instructions, permettent la
caractère blanc. capture de la partie de sous-chaîne définie et
• \w : Trouve un caractère « de mot » : une satisfaisant le motif.
lettre, accentuée ou non, ainsi que
l'underscore.
• \W : Trouve un caractère qui n'est pas un
caractère « de mot »

En javascript une expression régulière s’écrit entre slashs : /mon_expression/


Pour commencer, nous allons nous focaliser sur le champ de la date de naissance qui nécessite le format
suivant : jj/mm/aaaa.

Dans la boucle du gestionnaire d’événements on va isoler « daten » avec un « si » et écrire notre première
expression.

HTML – CSS – JavaScript 35 sur 41


Pour tester une expression sur une chaîne en Javascript, on utilise la syntaxe suivante :
<mon_expression>.test(<ma_chaîne>)

item.addEventListener('blur', function() {
...
if(item.id==='daten') {
let regex = /[0-9\/]+/
// le résultat du test s'écrit dans la console du navigateur
console.log(regex.test(item.value))
}
})

L’expression régulière ci-dessus cherche si la chaîne (item.value) contient un caractère dans l’intervalle 0-9
ou un slash (que l’on est obligé d’échapper avec l’antislash puisqu’il s’agit d’un métacaractère) et cela une
seule fois ou plusieurs, c’est la vocation du métacaractère +.

Si vous tapez une lettre par exemple, le test va échouer. On se rapproche de ce que l’on veut mais si vous
tapez 2 slashs de suite ou une année avec 6 chiffres, le test fonctionnera.

Pour info :
• L'égalité faible (==) effectue une conversion des deux éléments à comparer avant d'effectuer la
comparaison.
• L'égalité stricte (===) effectue la même comparaison mais sans conversion préalable (elle renverra
toujours false si les types des deux valeurs comparées sont différents).

Peut-on améliorer cette expression pour vérifier plus exactement le format de date attendu (jj/mm/aaaa) ?
Vous pouvez faire des essais ici : https://www.regextester.com/

Si on applique cela à tous nos champs, on peut alors récrire :


item.addEventListener('blur', function() {

if(item.value=="") {
item.classList.remove('valid')
item.classList.add('invalid')
} else if(!(/^([0-9]{2}\/){2}[0-9]{4}$/.test(item.value))) {
item.classList.remove('valid')
item.classList.add('invalid')
item.parentNode.querySelector('.error').innerHTML = 'Le format n\'est pas valide !'
} else {
item.classList.remove('invalid')
item.classList.add('valid')
}
})

HTML – CSS – JavaScript 36 sur 41


On écrit un message spécifique si le problème correspond à une date invalide plutôt qu’à un champ vide.
Il nous faut sélectionner le sélecteur où écrire ce message. Notre fonction parcourt les sélecteurs un à un.
On veut que le message soit écrit dans la balise <small>, celle qui a la classe « error » juste en-dessous du
champ texte concerné.

On va donc utiliser la méthode querySelector() qui retourne le premier élément dans le document
correspondant au sélecteur spécifié. item.parentNode.querySelector('.error') indique que l’on va
chercher le premier sélecteur de classe « error » qui se trouve dans le nœud parent du champ où l’on se
trouve. Ici, le nœud parent sera la <div> dans laquelle se trouve l’<input> testé et il n’y a qu’un <small> de
classe « error » dans cette <div>.

La propriété innerHTML permet de remplacer le contenu de ce qui se trouve dans la balise <small> par ce
qui est entre quote.

Notre système semble fonctionner mais nous avons de multiples formats à tester comme le téléphone, le
code postal qui ne fonctionneront pas avec l’expression régulière de la date de naissance.

À faire vous-même :

Écrire une expression régulière permettant de tester le format :


• d'un numéro de téléphone : _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ;
• d’un code postal français : _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ;

Pour pallier à ce problème nous allons ajouter un attribut (nommé data-validation mais ceci est arbitraire,
ça pourrait être autre chose) aux éléments html pour dire à javascript quel format il devra tester :
• data-validation="email"
• data-validation="date"
• data-validation="telephone"
• data-validation="cp"

Exemple :
<input type="text" id="daten" name="daten" aria-describedby="daten_aide" class="champs_texte"
data-validation="date"><br>

Ensuite nous allons préparer nos différentes expressions régulières dans un objet, de cette façon :
const types = {
email: /^[0-9a-z._-]+@{1}[0-9a-z.-]{2,}[.]{1}[a-z]{2,5}$/,
date: /^([0-9]{2}\/){2}[0-9]{4}$/,
telephone: /^0[1-7]{1}[0-9]{8}$/,
cp: /^[0-9]{5}$/
}

HTML – CSS – JavaScript 37 sur 41


On obtient alors :
// les éléments à valider
const inputs = document.querySelectorAll('input[type="text"], input[type="email"]')

// les types de validation


const types = {
email: /^[0-9a-z._-]+@{1}[0-9a-z.-]{2,}[.]{1}[a-z]{2,5}$/,
date: /^([0-9]{2}\/){2}[0-9]{4}$/,
telephone: /^0[1-7]{1}[0-9]{8}$/,
cp: /^[0-9]{5}$/
}

inputs.forEach(item => {

item.addEventListener('blur', function() {

// récupération du format de validation attendu


let regex = types[ item.getAttribute('data-validation') ]

if(item.value=="") {
item.classList.remove('valid')
item.classList.add('invalid')
} else if(!regex.test(item.value)) {
item.classList.remove('valid')
item.classList.add('invalid')
item.parentNode.querySelector('.error').innerHTML = 'Le format n\'est pas valide !'
} else {
item.classList.remove('invalid')
item.classList.add('valid')
}
})

Il reste un cas de figure à traiter. Certains champs, tel que le nom ou le prénom n’ont pas de format à
tester (pas d’attribut data-validation), la ligne :
let regex = types[ item.getAttribute('data-validation') ]
va donc échouer pour eux, vous pouvez le vérifier dans la console.

Pour éviter cela, nous allons ajouter un test sur cette ligne avec l’opérateur ternaire :
let regex = item.hasAttribute('data-validation') ? types[ item.getAttribute('data-validation') ]
: /./

qui signifie que la variable regex aura toujours une valeur : soit l’expression récupérée dans l’objet types
soit l’expression /./ qui signifie n’importe quel caractère.

L'opérateur (ternaire) conditionnel est le seul opérateur JavaScript qui comporte trois opérandes. Cet
opérateur est fréquemment utilisé comme raccourci pour la déclaration de Instructions/if . . . else.

Syntaxe : condition ? exprSiVrai : exprSiFaux

HTML – CSS – JavaScript 38 sur 41


Envoi du formulaire

Il nous reste à gérer l’envoi du formulaire. En effet nous pouvons constater que malgré des erreurs nous
pouvons quand même envoyer le formulaire !

Il faudrait en quelque sorte intercepter ce dernier avant qu’il soit envoyé pour vérifier que toutes les
données ont été validées.

La solution de facilité est souvent de vouloir placer un événement sur le bouton « envoyer » mais ce n’est
pas une bonne pratique car le formulaire peut être validé d’une autre manière : la touche entrée sur un
champ texte par exemple.

En revanche un événement existe pour les éléments de type « form », il s’agit de « submit ».

Ajoutons un id à l’élément html :


<form action="traitement.html" method="POST" id="formId">

Ajoutons également un bloc qui affichera un message d’erreur si le formulaire contient des erreurs. On
l’insère dans une ligne de la grille juste avant le bouton « enregistrer » :
<div class="seven">
<div class="alert" id="msg">
Le formulaire contient des erreurs !
</div>
</div>

<div class="eight">
<button type="submit" class="bouton_enregistrer">Enregistrer</button>
</div>

On pense à modifier la grille en conséquence (on ajoute un 5ème « auto » pour la 5ème ligne) :
/* Création de notre grille */
.grille {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: auto;
grid-auto-rows: auto, auto, auto, auto, auto;
}

Et on ajoute notre classe « eight » :


.eight {
grid-column: 1 / 7;
grid-row: 5;
}

HTML – CSS – JavaScript 39 sur 41


Puis dans notre fichier app.js, créons un nouvel événement :
// envoi du formulaire
const form = document.getElementById('formId')

form.addEventListener('submit', event => {


...
})

Maintenant nous devons chercher si le formulaire contient des erreurs. Si oui, nous afficherons le message.
Pour ce faire, il suffit de chercher la classe CSS « invalid ». Si elle est présente au moins une fois c’est que le
formulaire contiendra des erreurs.
// on regarde si on a des erreurs
const error = document.querySelector('.invalid')

const msg = document.getElementById('msg')

//on affiche le message d'erreur


if(error) {
msg.classList.add('show')
}

On ajoute un peu de CSS pour le message :


/* bloc message indiquant que le formulaire contient des erreurs */
#msg {
display:none;
}
#msg.show {
display: block;
color: #842029; background-color: #f8d7da;
border: 1px solid #f5c2c7; border-radius: 8px;
padding: 1rem; margin: 0 30% 1.5rem;
font-size: 18px; text-align: center;
}

Testons le formulaire. Que constate-t-on ?

Le formulaire est visiblement envoyé quoiqu’il arrive. En effet l’événement « submit » est appelé juste
avant l’envoi mais ne gère aucunement l’envoi ou non.

En revanche, lorsqu’on écoute un événement, on a accès à ce dernier (event => {) et une méthode existe
pour stopper le cheminement habituel de celui-ci :
//on affiche le message d'erreur
if(error) {
msg.classList.add('show')
event.preventDefault()
}

Testons à nouveau.

HTML – CSS – JavaScript 40 sur 41


Vous l’avez peut-être remarqué, un dernier cas de figure n’est pas pris en compte par notre programme : la
validation du formulaire dès le chargement de la page.
Dans ce cas, il n’y a aucune erreur alors le formulaire est posté alors que tous les champs sont vides !

Nous devrions effectuer la validation de chaque champ, ce que l’on fait dans chaque événement « blur » !
Puisque nous avons déjà effectué cela, il ne sert à rien de le réécrire, on va le réutiliser.

Pour ce faire, on déporte le contenu de l’événement « blur » dans une fonction que l’on pourra réutiliser :

function validItem(item) {

// récupération du format de validation attendu


let regex = item.hasAttribute('data-validation') ? types[ item.getAttribute('data-validation')
] : /./

if(item.value=="") {
item.classList.remove('valid')
item.classList.add('invalid')
} else if(!regex.test(item.value)) {
item.classList.remove('valid')
item.classList.add('invalid')
item.parentNode.querySelector('.error').innerHTML = 'Le format n\'est pas valide !'
} else {
item.classList.remove('invalid')
item.classList.add('valid')
}
}

La fonction prend en paramètre un “item” (champ de formulaire).

On modifie alors l’événement “blur” :


inputs.forEach(item => {
item.addEventListener('blur', event => {
validItem(item)
})
})

Et on termine par effectuer la validation de tous les champs dans l’événement “submit” :
// envoi du formulaire
const form = document.getElementById('formId')

form.addEventListener('submit', event => {

// on effectue la validation
inputs.forEach(item => {
validItem(item)
})
...

HTML – CSS – JavaScript 41 sur 41

Vous aimerez peut-être aussi