Mini-cours de JavaScript

Jour 4

Maintenant, vous savez créer un formulaire et connaissez, par rapport au mini-cours sur le HTML, 7 balises HTML supplémentaires : <form>, <input />, <label>, <fieldset>, <legend>, <button> et <script>

La balise <input /> dispose de nombreux attributs qui peuvent parfois avoir de nombreuses valeurs.

Vous savez que l'événement le plus courant est click et que l'appel de fonction se place :

Si l'événement submit se produit, non seulement la valeur de l'attribut onsubmit ( = code JavaScript ) sera exécuté, mais les données seront envoyées à l'adresse URL indiquée par l'attribut action de la balise form. Si l'attribut action est absent ou sa valeur n'est pas une URL, la page ( appelante ) se ré-affichera ( en réinitialisant les champs ).

Pour éviter ce rafraîchissement de page, il faut alors y ajouter l'instruction : return false;

Si l'événement reset se produit, non seulement la valeur de l'attribut onreset ( = code JavaScript ) sera exécuté, mais les champs seront réinitialisés.

Même lorsque les données ne sont pas envoyées à un serveur, le recours à la balise form est recommandé, car le navigateur va effectuer un contrôle ( s'il existe au moins une contrainte : type="number", type="email", min="", max="", required="required", ... )

Dans une balise form,
la balise button peut ne rien "soumettre", si son type="button" ( et qu'elle ne possède pas d'attribut "onsubmit" )
Exemple : <button type="button" onclick="...">Mon bouton</button>

Vous savez aussi que le code JavaScript se place un attribut d'une balise, dans la balise <script> ou un fichier externe .js. Et, que ce fichier externe est appelé via l'attribut src de la balise <script>. Et que cet appel se fait juste avant la fin du body

        ...
        <script src="monScript.js"></script>
    </body>
</html>

Vous savez ce qu'est une fonction, comment on la déclare, comment on l'appelle, qu'une fonction contient des instructions, qu'elle peut appeler d'autres fonctions, ( qu'elle peut même s'appeler ! ), qu'elle a ou non des arguments - aussi appelés paramètres -, qu'elle retourne ou non une valeur, que la fonction est l'une des quatre notions fondamentales en programmation.

Voyons tout de suite la seconde notion fondamentale : la variable.

Une variable

La notion de variable est une des notions les plus importantes en programmation.

Aujourd'hui, nous allons apprendre ce qu'est une variable, à récupérer une valeur mise dans un champ d'un formulaire et à afficher un résultat.

Qu'est-ce qu'une variable ?

Une variable permet de stocker quelque chose dans la mémoire de l'ordinateur dont la valeur peut changer.

On parle de variable, car le contenu de la variable peut varier durant l'exécution du programme.

Comment définir une variable ?

Définir une variable est beaucoup plus simple que définir une fonction.

<script>
   var nombre1;
</script>

Pour définir une variable, il suffit de taper le mot-clé var, un espace, un nom et un point-virgule.

Recommandation : Les règles concernant le nom d'une fonction s'applique au nom d'une variable : [a-z][a-zA-Z0-9_$]+
Néanmoins, et à vos risques et périls : Liste des caractères admis

Toutefois, la tradition veut que le nom d'une variable ne soit pas un nom de verbe (ou de pseudo verbe) à l'infinitif, mais un nom qui correspond au contenu.

Il faut s'imaginer la mémoire de l'ordinateur comme une armoire avec beaucoup de tiroirs.

Lorsqu'on écrit var nombre1;, on dit au navigateur met sur un tiroir l'étiquette "nombre1".
Et, comme on donne un ordre, on met un point-virgule.

Il est possible de déclarer plusieurs variables à la suite en les séparant de virgules :

var maVariable = 1, /* cette variable vaut 1 */
    maVariable2, /* celle-ci est déclarée, mais vide */
    maVariable3 = true; /* celle-ci contient le booléen true */

Ou, de manière plus condensée (sans retour à la ligne) :

var maVariable = 1, maVariable2, maVariable3 = true;

On doit déclarer les variables avant de les utiliser (logique !). Par commodité (pour y voir plus clair) et par respect du C, on déclare les variables en début de code.

Que peut contenir une variable ?

C'est ici qu'il faut s'accrocher ...

Si vous ne comprenez pas ce qui suit du premier coup, c'est tout à fait normal. Vous savez déjà ce qu'est un nombre et un caractère. Vous comprendrez facilement ce qu'est une chaîne de caractères. Faites un effort pour comprendre ce qu'est un booléen; ils ne sont que deux.

Une variable peut contenir :

Une variable peut contenir un caractère, mais il n'existe pas en JavaScript de variable de type caractère ( contrairement au C ). Nous verrons plus tard qu'une chaîne de caractères est un objet et un tableau est aussi un objet ...

Si vous souhaitez connaître le type d'une variable, il suffit de taper :
alert(typeof(maVariable)); // affichera string, number, boolean, undefined, object, ...

<script>
   var nombre1;        /* met l'étiquette "nombre1" sur un tiroir */
   nombre1=2;          /* met 2 dans le tiroir nommé "nombre1" */
   var nombre2=3;      /* met l'étiquette "nombre2" sur un tiroir et la valeur 3 dans ce tiroir */
   var resultat=4+5;   /* met l'étiquette "resultat" sur un tiroir et dans ce tiroir le résultat (soit 9) */
   resultat=nombre1+6  /* met dans le tiroir "résultat" le résultat = 2+6 (soit 8) */
   resultat=nombre2+nombre1; /* = 3+2 (soit 5) */
</script>

En programmation, = veut dire au programme met à gauche la valeur qui est à droite.

Ici, à gauche du signe = c'est le nom d'une variable.
Si, à droite du signe = c'est un booléen => le programme met ce booléen dans le tiroir
Si, à droite du signe = c'est un nombre => il met ce nombre dans le tiroir
Si, à droite du signe = c'est une expression => il résout l'expression et met le résultat dans le tiroir
Si, à droite du signe = c'est le nom d'une fonction => il met ce que renvoie la fonction ... Nous verrons cela plus tard.

En programmation, == veut dire égal. Nous verrons cela bientôt.

On constate que le contenu du tiroir ayant comme étiquette resultat a varié durant l'exécution du programme.
Il valait 9, puis 8, puis 5. resultat est bien une variable !

Il n'est pas nécessaire que le contenu du tiroir varie beaucoup pour que ce soit une variable.
Il suffit de la définir - une seule fois - avec le mot-clé var

<script>
function afficherResultat(){
   var nombre1;        /* met l'étiquette "nombre1" sur un tiroir */
   nombre1=2;          /* met 2 dans le tiroir nommé "nombre1" */
   var nombre2=3;      /* met l'étiquette "nombre2" sur un tiroir et la valeur 3 dans ce tiroir */

   var resultat=4+5;   /* met l'étiquette "resultat" sur un tiroir et
                          dans ce tiroir le résultat (soit 9) */
   alert(resultat);    /* affiche dans la boîte de dialogue "9" */

   resultat=nombre1+6  /* met dans le tiroir "résultat" le résultat = 2+6 (soit 8) */
   alert(resultat);    /* affiche "8" */

   resultat=nombre2+nombre1; /* = 3+2 (soit 5) */
   alert(resultat);          /* affiche "5" */
}
</script>

Tester ce code :

On constate qu'on peut aussi mettre entre les parenthèses de la méthode alert() le nom d'une variable pour afficher la valeur de la variable. Ce qui est très pratique.

Attention. Il faut toujours définir une variable avant de l'utiliser.

Si on pouvait mettre des choses dans un tiroir sans connaître l'emplacement de ce tiroir, on ne pourrait plus utiliser le contenu de ce tiroir. En effet, pour retrouver tout contenu nous avons besoin de connaître l'adresse de ce contenu. Sinon, il est non-retrouvable et donc perdu !

Affectation en cascade

x=y=z=25; /* les trois variables valent 25 */

Portées d'une variable

Une variable peut être déclarée :


Vous êtes toujours là ? Bien ! La première partie la plus dure est passée !

Vous n'avez rien compris ? Pas de panique ! C'est normal !
Continuez, vous y reviendrez plus tard.

document.getElementById()

Grâce aux parenthèses, on sait déjà qu'on va parler d'une fonction / méthode ...
Et, grâce aux majuscules, on voit que le nom est composé de plusieurs mots.
get Element By Id = obtenir élement via son ID
Obtenir quoi ? Un objet ( plus exactement une référence à un objet )

Une méthode est une fonction d'un objet.
Nous verrons plus tard ce qu'est un objet.

Vous savez que, dans une page web, chaque zone peut être identifiée par son attribut id.
zone ( en français ) = balise ( en HTML ) = element ( en JavaScript )

élement ( en français ) = element ( en anglais )

getElementById() est donc une méthode qui permet d'obtenir une référence d'un élément grâce à la valeur de l'attribut id.

var maBalise = document.getElementById("nombre1");
/* maBalise vaut un objet qui représente la balise identifiée par "nombre1" */

Récupérer la valeur donnée par l'utilisateur

Maintenant, vous allez comprendre ...

Il est indispensable que le programme puisse récupérer la valeur donnée par l'utilisateur pour les utiliser et les traiter, faire des calculs, ...

Et, dans quoi allons-nous mettre ce que le visiteur de notre page va taper dans un champ ?
Dans une variable ...

Tapez un nombre entier

Voici le code :
<form id="exemple1" onsubmit="afficherValeur(); return false;">
   <p>
      <label>Nombre entier 1 :
      <input type="number" id="nombre1" required="required" />
      </label>
      <input type="submit" value="Afficher" />
      <input type="reset" />
   </p>
</form>

<script>
function afficherValeur(){
    var nombre1=document.getElementById("nombre1").value;
    alert(nombre1);
}
</script>

Ici, la nouveauté est document.getElementById("nombre1").value;

On sait qu'en JavaScript "element" correspond à "balise".
"document" correspond à "page web".

Donc, cela signifie : obtient la valeur de l'attribut value de la balise HTML identifiée par "nombre1" dans la page web.

Cette valeur, ici un nombre entier, transformé en chaîne de caractères (!), est mise dans le tiroir appelé "nombre1".
Ensuite, on affiche dans une boîte de dialogue, le contenu du tiroir appelé "nombre1"

Notez que le champ identifié par "nombre1" est du type number.
Attention. Bien que de type="number", la valeur du champ n'est pas un nombre, mais une chaîne de caractères qui représente un nombre.

NB. Si la balise identifiée contient l'attribut title, vous pouvez récupérer la valeur de cet attribut.
var titre = document.getElementById("nombre1").title;
Vous pouvez donc récupérer la valeur de n'importe quel attribut d'une balise HTML identifiée, il suffit de mettre le nom de son attribut dans le code JavaScript.

Placer une valeur dans un champ

Maintenant, nous allons fournir une réponse ... dans la page web.

Ajouter 1

Attendez-vous à une surprise ...

Voici le code :
<form id="exemple2" onsubmit="ajouterUn(); return false;">
   <p>
      <label>Nombre entier 1 :
      <input type="number" id="n1" required="required" />
      </label>
      <input type="submit" value="Ajouter 1" />
   </p>
   <p>
      <label>Nombre entier 2 :
      <input type="number" id="n2" readonly="readonly" class="fondGris" />
      </label>
      <input type="reset" />
   </p>
</form>

<script>
function ajouterUn(){
    var nombre1=document.getElementById("n1").value;
     /* La valeur d'un champ est toujours une chaîne de caractères ! */

    var nombre2=nombre1+1; /* chaîne de caractères + nombre => collage (et non addition) */
    document.getElementById("n2").value=nombre2;
}
</script>

Ici, il va falloir s'accrocher pour comprendre la logique de JavaScript.
Heureusement, c'est logique ...

La valeur "récupérée" d'un champ est toujours une chaîne de caractères.

Supposons que l'utilisateur tape : "123", le résultat sera "1231" !

Explication.

Dans le script, la variable nombre1 contient "123" et non 123 !
La variable contient une chaîne de caractères et non un nombre ...
... contrairement à ce que laisse supposer le nom de la variable.

1 est bien ajouté, mais il n'est pas additionné !

Le signe plus (+) est toujours entre deux termes.
Un terme peut être un nombre ou une chaîne de caractères.

En JavaScript, + a deux significations :

Or, il ne peut coller que 2 chaînes de caractères. Si un des termes est un nombre alors, il le transformera en chaîne de caractères avant le collage.

Au niveau du code, la nouveauté est document.getElementById("nombre2").value=nombre2;
Donc, on donne une valeur à un champ, donc on écrit sur la page web ...

Rappel. On met ce qui est à droite du signe = dans ce qui est à gauche de ce signe.
Ici, ce qui est à droite du signe = est la valeur de la variable nombre2, c-à-d le contenu du tiroir nommé "nombre2". Et ce contenu est une chaîne de caractères qui représente un nombre.

Donc, cela signifie : la valeur de l'attribut value de l'élément identifié par l'id "nombre2" dans la page web vaut celle de la variable appelée nombre2.

Notez que le champ identifié par "n2" est non modifiable par l'utilisateur  : readonly="readonly"
Notez également que lorsqu'il y a plusieurs formulaires sur la présente page web, on donne un ID différent pour chaque formulaire.

function plus(){               /* il = le navigateur
                                  rappel : alert() n'affiche jamais un nombre,
                                  mais, toujours une chaîne de caractères */

        var nom="Einstein";
        var prenom="Albert";
        alert(prenom+nom);     /* il colle les deux mots (pas d'espace)
                                  affiche "AlbertEinstein" */

        var nombr1="123";      /* nombr1 est une chaîne de caractères */
        var nombr2=nombr1+"1"; /* il colle "123" et "1" */
        alert(nombr2);         /* affiche "1231" */

        var n1="123";
        n1=parseInt(n1);       /* il transforme, sur ordre, "123" en 123 ! */
        var n2=n1+1;           /* n1 et 1 sont deux nombres => il additionne */
        alert(n2);             /* affiche "124" */

        var nombre1="123";     /* nombre1 n'est pas un nombre ! */
        var nombre2=nombre1+1; /* on ne peut pas additionner une chaîne et un nombre
                                  => il transforme, sans ordre, 1 en "1"
                                  puis il colle */
        alert(nombre2);        /* affiche "1231" */
}

Testons le script ci-dessus :

Vous êtes toujours là ? Bien ! La seconde et dernière partie la plus dure est passée !

Les fonctions pré-définies

En JavaScript, il existe plusieurs fonctions pré-définies. Vous ne devez donc pas les définir. Il vous suffit juste de les appeler.

Voici les 3 principales fonctions pré-définies :

  1. parseInt()
  2. parseFloat()
  3. isNaN()

parseInt()

Transformer une chaîne de caractères en nombre est nécessaire pour réaliser des opérations arithmétiques. Heureusement, JavaScript est là pour vous faciliter la vie.

Dans un système décimal, il n'existe que 10 chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Dans un système binaire, il n'existe que 2 chiffres : 0, 1
Dans un système octal, il n'existe que 8 chiffres : 0, 1, 2, 3, 4, 5, 6, 7
Dans un système hexadécimal, il n'existe que 16 chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

Un chiffre est un caractère ( un symbole, un signe, un dessin ).

Un nombre peut être composé d'un seul chiffre ou plusieurs chiffres.

Nous utilisons 10 signes différents pour représenter un nombre.
Nous nous basons sur 10 signes. Le nombre est alors représenté en base 10.
Aucune chose ( rien ) est représenté par 0 ( le premier signe ).
Le nombre neuf est représenté par 9 ( le dernier signe ).
Le nombre dix est représenté alors par 2 signes : 10 ( soit un dans la première colonne + zéro dans la seconde colonne, soit une dizaine + zéro unité )

Si nous utilisons 2 signes différents pour représenter un nombre.
Nous nous basons sur 2 signes. Le nombre est alors représenté en base 2.
Aucune chose ( rien ) est représenté par 0 ( le premier signe ).
Le nombre un est représenté par 1 ( le dernier signe ).
Le nombre deux est représenté alors par 2 signes : 10 ( soit un dans la première colonne + zéro dans la seconde colonne )

Si nous utilisons 8 signes différents pour représenter un nombre.
Nous nous basons sur 8 signes. Le nombre est alors représenté en base 8.
Aucune chose ( rien ) est représenté par 0 ( le premier signe ).
Le nombre sept est représenté par 7 ( le dernier signe ).
Le nombre huit est représenté alors par 2 signes : 10 ( soit un dans la première colonne + zéro dans la seconde colonne )

Si nous utilisons 16 signes différents pour représenter un nombre.
Nous nous basons sur 16 signes. Le nombre est alors représenté en base 16.
Aucune chose ( rien ) est représenté par 0 ( le premier signe ).
Le nombre quinze est représenté par F ( le dernier signe ).
Le nombre seize est représenté alors par 2 signes : 10 ( soit un dans la première colonne + zéro dans la seconde colonne )

Mais, alors comment savoir si "10" représente 10, 2, 8 ou 16 ?
C'est bien là le problème ...

Pour des raisons historiques - remontant au langage C - un nombre qui commence par "0" est considéré comme un nombre octal. Et, un nombre qui commence par "0x" ou "0X", comme un nombre hexadécimal.
Cependant, les navigateurs récents ont adopté la norme ECMAScript 5 - sortie le 3 décembre 2009 - qui a défini que dans le cas où la chaîne de caractères commence par "0" la base 10 doit être utilisée. Mais, votre visiteur pourrait utiliser un très ancien navigateur. Dans ce cas, "08" sera considéré par la fonction parseInt() comme valant 0 ! Et, "010" = 8 !

La fonction parseInt() autorise un second paramètre permettant de préciser la base à utiliser. La solution consistait à toujours indiquer la base utilisée dans la chaîne de caractères utilisée comme premier paramètre.

Notez que la fonction parseInt() reconnaît 35 bases : de la base 2 à la base 36 ...
alert(parseInt("10",36)); // affiche 36
alert(parseInt("11",36)); // affiche 37 ...

Aujourd'hui, pratiquement, vous n'est plus obligé d'utiliser ce second paramètre, si comme tout le monde vous travaillez en base 10.

Pour transformer une chaîne de caractères en nombre sans virgule décimale, il suffit de passer cette chaîne à la fonction parseInt(). Si ce qui lui est passé ne représente pas un nombre, cette fonction retourne NaN.

function tansformerEnUnNombre(){

   var nombre;                      /* nombre vaut undefined */

   nombre=parseInt("toto12345");    /* toto12345 n'est pas un nombre (nombre vaut maintenant NaN) */
   alert(nombre);                   /* affiche "NaN" */

   nombre=parseInt("12345toto");    /* seul le début est un nombre
                                       nombre vaut 12345 */
   alert(nombre);                   /* affiche "12345" */

   var prenom="Albert";             /* n'est pas un nombre */
   nombre=parseInt(prenom);         /* nombre vaut NaN */
   alert(nombre);                   /* affiche "NaN" */

   alert(parseInt(""));             /* une chaîne de caractères vide n'est pas un nombre */
                                    /* affiche "NaN */

   alert(isNaN(""));                /* la fonction isNaN() retourne un booléen
                                       une chaîne vide n'est pas un nombre
                                       affiche "false" */

   nombre="123";                    /* n'est pas un nombre (mais une chaîne de caractères) */
   nombre=parseInt(nombre);         /* nombre vaut maintenant 123 (un nombre) */
   alert(nombre+1);                 /* 123 + 1 => les deux termes sont des nombres */
                                    /* affiche "124" */

   nombre="123";                    /* n'est pas un nombre */
   nombre=parseInt(nombre);         /* nombre vaut 123 */
   nombre=nombre+"";                /* 123 + "" => les deux termes ne sont pas des nombres */
                                       => il transforme le nombre en chaîne => 123 devient "123"
                                       "123" + "" => il colle ( => nombre vaut "123") */
   alert(nombre+1);                 /* "123" + 1 => les deux termes ne sont pas des nombres
                                       il transforme le nombre en chaîne => 1 devient "1"
                                       "123" + "1" => il colle
                                       affiche "1231" */
}

Testons le script ci-dessus :

On constate que la méthode alert() affiche non seulement une chaîne de caractères, la valeur d'une variable transformée en chaîne de caractères (  et peut aussi être undefined, NaN, true, false), ainsi que le résultat d'une expression transformée en chaîne de caractères : alert(nombre+1);.

En programmation, il faut faire attention :

Rappel : type="number" avertit immédiatement l'utilisateur et ne validera pas le champ ( lorsqu'il sera traité par l'événement submit ). Seuls les caractères qui sont utiles pour écrire un nombre décimal américain seront admis. La virgule décimale ne peut donc être tapée. Pour les francophones, type="number" peut être utilisé pour tout nombre entier.