Mini-cours de JavaScript

Jour 8

Nous savons remplacer, une seule fois, un caractère dans une chaîne de caractères. Mais comment répéter l'opération, comment remplacer chaque caractère à remplacer ?

Aujourd'hui, nous apprendrons à créer une boucle et même un peu de magie ...

La boucle : while

Pour répéter plusieurs fois une série d'instructions, il nous faut créer une boucle. La quatrième caractéristique de tous les programmes informatiques est de permettre de créer des boucles.

Il existe plusieurs type de boucles : while, do while, for, ...
Rappel : Mot-clés déjà appris : function, var, if, else
Liste des mot-clés

while est un mot-clé qui dit ( au programme qui lit le code ) : " ce qui suit est la définition d'une boucle while. "

Pour définir une boucle while, il faut :

  1. taper le mot-clé while,
  2. faire suivre de parenthèses ( () ),
  3. taper, dans ces parenthèses, une condition ( comme avec un if )
  4. ouvrir une accolade ( { ),
  5. placer des instructions,
  6. fermer l'accolade ( } ).

Si la condition est vraie, les instructions entre accolades sont exécutées. Et, après la dernière instruction, la condition est retestée et si elle est encore vraie, on recommence. Et ainsi de suite, jusqu'à la fin de l'éternité !

Donc, une chose très importante est de coder de telle sorte qu'on quitte la boucle à un moment. Donc, dans la boucle, la variable utilisée dans la condition doit varier.

Imaginons qu'on veuille retirer tous les "e" d'une phrase et afficher cette nouvelle phrase.

Plusieurs solutions existent pour résoudre ce problème. Certaines sont plus rapides, élégantes, ...

Je vous propose, ici, de lire chaque caractère et de le recopier dans une autre variable que si ( if ) ce n'est pas un "e". On quittera la boucle lorsqu'on aura testé le dernier caractère. Oui, mais comment ?

On sait que le programme doit boucler autant de fois qu'il y a de caractères. Et, on sait que la propriété .length de l'objet-String retourne le nombre de caractères. Donc, nous sommes capables de dire au programme combien de fois il devra boucler.

Dans le cadre d'une répétition, une notion importante est souvent utilisée : le compteur de boucles (= la variable de boucle).

On utilise donc une variable, utilisée dans la condition, nommée par tradition i, auquel on ajoute 1 à chaque tour.

function remplacerUnAUn(){

    /* récupération des données */
    var maChaine = document.getElementById("chaine1").value;
    var caractereARemplacer = document.getElementById("caractere1").value;

    /*initialisations des données */
    var longueurDeMaChaine = maChaine.length;
    var nouvelleChaine = "";
    var i = 0; /* le compteur est mis à zéro avant d'entrer dans la boucle */

    while ( i < longueurDeMaChaine ) {

        if ( maChaine.charAt(i) != caractereARemplacer ) {
            nouvelleChaine = nouvelleChaine + maChaine.charAt(i);
        }

        i = i + 1; /* ne pas oublier de modifier le compteur !
        À chaque caractère testé, la valeur du compteur grandit de 1 */

    }

    /* affiche la nouvelle chaîne */
    document.getElementById("chaine2").innerHTML = nouvelleChaine;
}

function effacer(){
    document.getElementById("chaine2").innerHTML="";
}

Les boucles donnent de la "puissance" à votre programme, puisqu'il le fera plus vite que vous. Et, si on y ajoute des conditions, votre programme sera presqu'intelligent, puisqu'il sera capable de faire des choix et d'afficher la réponse très rapidement.

( Laissez vide pour supprimer )

function remplacerToutCaractere(){
    var maChaine = document.getElementById("chaine12").value;
    var caractereARemplacer = document.getElementById("caractere12").value;
    var caractereDeRemplacement = document.getElementById("caractere12b").value;
    var reg = new RegExp(caractereARemplacer, "g"); /* g comme global */
    var nouvelleChaine = maChaine.replace( reg, caractereDeRemplacement);
    document.getElementById("chaine13").value = nouvelleChaine;
}

Ce code est plus rapide et élégant ...
Mais l'étude des expressions régulièresnew RegExp(caractereARemplacer, "g") ) dépasse le cadre d'un mini-cours.
Retenez simplement qu'il existe différentes façons de résoudre à un problème.

La notion de boucle était la quatrième et dernière notion commune à tous les langages de programmation. Vous avez bien mérité une petite récompense, un peu de magie ...

.innerHTML

La propriété .innerHTML de l'objet-element est magique !

Elle permet au programme de remplacer le texte affiché !

Vous savez qu'en HTML, le texte s'écrit dans une zone, c'est-à-dire entre deux balises. Pour ajouter du texte à l'écran, il suffit de sélectionner une balise, puis de taper son contenu comme valeur de propriété .innerHTML. Par exemple,

document.getElementById("paragraphe1").innerHTML = "Bonsoir !!!";

Bonjour !

function afficherBonsoir(){
    document.getElementById("paragraphe1").innerHTML="Bonsoir !!!";
}
function afficherBonjour(){
    document.getElementById("paragraphe1").innerHTML="Bonjour !";
}

Non seulement le programme peut remplacer du texte, mais aussi remplacer du code HTML !

function afficherSurprise(){
    document.getElementById("paragraphe2").innerHTML="<img src=\"tintin-milou.webp\" />";
}
function afficherVide(){
    document.getElementById("paragraphe2").innerHTML="";
}

Souvenez-vous ! Attention aux guillemets ...
N'oubliez pas le rôle du caractère d'échappement.

Grâce à la propriété .innerHTML vous avez le contrôle sur toute zone affichée.

La propriété .innerHTML ne permet pas de modifier le fichier HTML. Le fichier est lu par le navigateur. Puis, sur base de ce fichier, il crée une représentation de ce fichier dans la mémoire de l'ordinateur, puis affiche cette représentation à l'écran. Grâce au JavaScript, il est possible de modifier cette représentation en mémoire. La mise à jour de l'affichage est automatique. Le fichier HTML, lui, reste intact.

C'est le programme ( le navigateur ) qui modifie votre page web, mais c'est vous, le programmeur, qui dites, en JavaScript, au programme ce qu'il doit faire.

Formulaire (suite)

Dans un formulaire, il existe d'autres champs que ceux que nous déjà avons vus.

Voyons, les derniers champs :

et les dernières balises liées au formulaire :

Nous reparlerons de la balise qui envoie des informations cachées - <input type="hidden" /> - dans le prochain mini-cours ( sur le PHP ), lorsque nous étudierons la gestion des données envoyées sur un serveur !

<input type="checkbox" />

Souvent, à la fin d'un formulaire de commande, on trouve une case à cocher liée aux Conditions générales. Généralement, la case est décochée pour obliger l'utilisateur à la cocher, signifiant ainsi qu'il a lu ces Conditions générales. Un lien est lié aux mots Conditions générales. Souvent, une autre case à cocher concerne l'envoi de lettres d'informations ( en anglais, "newsletters" ).

Cochez pour accepter nos Conditions Générales. ( Ce lien ne fonctionne pas )

Remarquez que pour cocher ou décocher la première case à cocher, il faut placer le curseur de la souris sur la case à cocher. Mais, pour cocher ou décocher la seconde case à cocher, on peut aussi cliquer sur le texte qui suit cette case à cocher. Ce qui est pratique pour l'utilisateur.

Regardons le code HTML pour découvrir ce mystère ...

<form id="form3" onsubmit="validerCheckbox();return false;" name="form3">
    <p>
        <input type="checkbox" id="chkConditions"> Cochez pour accepter nos <a href="#"
        onclick="return false;">Conditions Générales</a>.
        <span class="note">( Ce lien ne fonctionne pas )</span>
    </p>
    <p>
        <input type="checkbox" id="chkNewletters" checked="checked" />
         <label for="chkNewletters">Cochez pour recevoir nos dernières promotions très avantageuses.</label>
    </p>
    <p>
        <input type="submit" value="Envoyer votre commande">
    </p>
</form>

<script>
function validerCheckbox(){
    if ( document.getElementById("chkConditions").checked ){
         /* la propriété .checked vaut true ou false */
        alert("Merci pour votre commande.");
    }
    else{
        alert("Veuillez accepter nos conditions générales.");
    }
}
</script>

La case à cocher est une zone ( <input /> ). Mais, vous pouvez lier cette zone avec une étiquette ( <label> ). Pour lier les deux balises ( lorsque l'input n'est pas encadré ), la valeur de l'attribut id de l'une doit correspondre à la valeur de l'attribut for de l'autre.

Toutefois, le plus simple est d'encadrer la balise <input /> par la balise <label>. Dans ce cas, l'attribut for est inutile.

<label>
  <input type="checkbox" id="chkNewletters" checked="checked" />
  Cochez pour recevoir nos dernières promotions très avantageuses.
</label>

Remarquons aussi que la seconde case à cocher était cochée. En HTML, pour que la case à cocher s'affiche cochée, il faut utiliser l'attribut checked. Pour respecter la règle du XML, qui veut qu'à tout attribut correspond une valeur, on donne une valeur à cet attribut. La seule valeur valide de cet attribut est checked. Au final, pour que la case soit pré-cochée, il faut coder :
checked="checked"

En ce qui concerne le JavaScript, la nouveauté est le code :
document.getElementById("chkConditions").checked

La propriété .checked retourne un booléen.
Elle retourne true si la case est cochée et false si elle ne l'est pas.

document.getElementById("chkConditions").checked retourne un booléen.

Dans les parenthèses d'un if on peut trouver :

Au final, on peut donc coder " si la case à cocher est cochée " par :
if ( document.getElementById("chkConditions").checked ){ ... }

Exemple pour décocher une checkbox, via JS
document.getElementById("chkConditions").checked=false;

<input type="radio" name="..." />

Souvent, au début d'un formulaire de demande de renseignements, on trouve des options dont une seule doit être cochée ( contrairement aux cases à cocher où plusieurs cases peuvent être cochées ). Un bouton-radio est représenté par un rond blanc, contenant un rond noir si l'option est choisie.

Bouton-radio car, comme avec une vraie radio, on ne peut écouter qu'une seule émission à la fois.


Remarquez que les bouton-radio<input /> ) sont liés à des étiquettes ( <label> ). Ce qui est pratique pour l'utilisateur.

<form id="form4" onsubmit="validerRadio();return false;" name="form4">
    <p>
        <label><input type="radio" name="sexe" id="Homme">
        Monsieur</label><br>
        <label><input type="radio" name="sexe" id="Femme">
        Madame</label>
    </p>
    <p>
        <input type="submit" value="Envoyer votre identité">
        <button onclick="effacerRadio();">Effacer votre choix</button>
    </p>
</form>

<script>
function validerRadio(){
    var choix=0;

    /* la propriété .checked vaut true ou false */
    if (document.getElementById("Homme").checked){
        choix=1;
    }

    if (document.getElementById("Femme").checked){
        choix=2;
    }

    if (choix==0){
        alert("Veuillez indiquer votre sexe.");
    }
    else{
        alert("Merci d'avoir choisi.");
    }
}

function effacerRadio(){
/* le fait de changer l'état d'une option provoque un événement comme un clic */
    document.getElementById("Homme").checked=false;
    document.getElementById("Femme").checked=false;
}
</script>

Attention. Lorsque l'attribut type vaut "radio", l'attribut name est obligatoire et la valeur doit être identique aux autres bouton-radio, pour former un groupe. Ici, le nom du groupe est "sexe".

Le fait que la valeur de l'attribut name soit identique à celle d'autres bouton-radio permet de créer un groupe de bouton-radio. Dans un groupe de bouton-radio, on ne peut choisir qu'une seule option. Si on clique sur une option, le navigateur va alors automatiquement désactiver la précédente option choisie.

L'attribut HTML checked="checked" peut être utilisé pour définir le choix par défaut.

checked est :

  • Dans le code HTML,
    • le nom d'un attribut
    • la valeur d'un attribut (du même nom)
  • Dans le code JavaScript, le nom d'une propriété

<select> et <option>

De même que la balise <form> contient des balises <input />, la balise <select> contient des balises <option>.

La balise <select> crée une liste déroulante. Et, la balise <option> permet de créer une option dans cette liste.

La balise <select> est elle-même contenue dans une balise <form>

Liste de pays :  

<form id="form5" onsubmit="determinerLePaysChoisi();return false;" name="form5">
    <p>
    Liste de pays : <select id="ListePays">
        <option>
            &nbsp;
        </option>
        <option value="BE">
            Belgique
        </option>
        <option value="FR">
            France
        </option>
        <option value="XX">
            Autre
        </option>
        </select>
        <input type="submit" value="Choisissez un pays">
    </p>
</form>

<script>
function determinerLePaysChoisi(){
    if (document.getElementById("ListePays").selectedIndex == 0){
        alert("Veuillez sélectionner un pays");
    }
    else{
        var code=document.getElementById("ListePays").value;
        alert("Code du pays choisi = "+code);
    }
}
</script>

On ne peut pas coder : <option></option>
car le contenu de la balise est vide et que la balise n'a pas d'attribut.
Mais on peut coder : <option>&nbsp;</option>
On peut aussi coder : <option value=""></option>

La propriété .selectedIndex retourne un nombre correspondant à la position de l'option sélectionnée. La position de la première option est zéro.

En informatique, la première position vaut toujours zéro. Que ce soit la première position d'une option, d'un caractère dans une chaîne de caractère, d'un élément dans un tableau, ... ( Nous verrons ce qu'est un tableau plus tard )

Rappel. == est l'opérateur de comparaison
= est l'opérateur d'affection ( qui place à gauche, ce qui est à droite )

Le contenu de l'attribut value représente la valeur qu'on souhaite envoyer au formulaire lorsque l'option est sélectionnée. Si cet attribut n'est pas défini, la valeur sera le contenu textuel de l'élément

Lors d'une mise à jour d'un enregistrement, la valeur affichée dans une liste déroulante doit correspondre à celle enregistrée (avant modification). Dans ce cas, il faut au niveau du code JS attribuer à .value la valeur enregistrée.

document.getElementById("...").value = ... ;

Cette affectation affectera la liste déroulante qui affichera l'option enregistrée.

Attention avec l'objet select il existe une particularité :
Les propriétés .selectedIndex et .value sont appliquées à l'objet select, mais les valeurs retournées concernent ses sous-objets, donc les objets option.


<p>
  <select id="mois" name="mois"></select>
  <select id="annee" name="annee"></select>
</p>
const d = new Date(); var x = document.getElementById("mois")
moisFR=["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"]
for (let i=0;i<12;i++){ let o=document.createElement("option");o.text=moisFR[i];x.add(o)}
let intMois = d.getMonth(); x.selectedIndex = intMois;
x = document.getElementById("annee")
for (let i=2022;i<2032;i++){ let o=document.createElement("option");o.text=i;x.add(o)}
let intAnnee = d.getFullYear(); x.value = intAnnee;

<textarea>

Il est courant de permettre à l'utilisateur d'envoyer un commentaire ( de plusieurs lignes ). La zone de texte est représentée par un rectangle de dimensions variables.

Cette balise dispose des attributs : rows et cols

rows : permet d'indiquer le nombre de lignes souhaité.
cols : permet d'indiquer le nombre de colonnes souhaité (non recommandé, à cause des écrans moyens ou petits)

La balise <textarea> est normalement fille de la balise <form>

   

Si le texte est plus grand que la zone de texte, un ascenseur vertical apparaît automatiquement.

<form id="form6" onsubmit="afficherCommentaire();return false;" name="form6">
    <textarea id="commentaire" rows="10" cols="100" placeholder="Votre commentaire">
    </textarea>
    <p>
        <input type="submit" value="Envoyer votre commentaire" />
        <input type="reset" value="Effacer" />
        <button onclick="preremplir();return false;">
            Pré-remplir
        </button>
    </p>
</form>

<script>
function afficherCommentaire(){
    var commentaire=document.getElementById("commentaire").value;
    if (commentaire.length==0){
        alert("Vous n'avez pas fait de commentaire.")
    }
    else{
        alert(commentaire);
    }
}

function preremplir(){
    document.getElementById("commentaire").value="Ligne1\nLigne2"; }
</script>

Attention, avec textarea, il existe une particularité :

En HTML, pour pré-remplir la zone de texte, il suffit de taper le texte entre les balises <textarea> et </textarea>.

En JavaScript, pour récupérer le contenu ou insérer du contenu dans la balise <textarea> on utilise la propriété .value de l'objet textarea

( Pour ajouter du contenu à la balise <textarea> on n'utilise pas la propriété .innerHTML )

La plupart des propriétés d'un objet représentant une balise ont le même nom que celui de l'attribut de la balise. Toutefois, il existe des particularités. La propriété .value de l'objet select correspond à l'attribut value de la balise <option> sélectionnée. Et, la propriété .value de l'objet textarea correspond au contenu de la balise <textarea>.

Maintenant, vous savez créer des formulaires et récupérer toutes les données que l'utilisateur peut fournir. Vous êtes capable de les valider et de les traiter. Demain, avant-dernier jour d'apprentissage, nous verrons quelques trucs pour vous faciliter la tâche.