Voici la version du Techies Lab:

Screenshot of Techies Lab page

En passant, le site LottieFiles offre des animations gratuites pour illustrer le coronavirus.

Crée un nouveau dossier pour ton projet avec les trois fichiers habituels:

  • index.html
  • style.css
  • app.js

Ouvre ton dossier dans ton éditeur de texte (Sublime Text, par exemple).

Crée l'HTML de base de ta page web. On va commencer avec un formulaire qui contient deux entrées: les rouleaux restants et le nombre de jours de confinement.

Le résultat final devrait avoir l'air de ceci:

Et ton code HTML devrait avoir l'air de ceci:

Lorsque les utilisateurs appuient sur le bouton "Calculons", cela doit déclencher un événement: le calcul du ratio.

Comment créer un événement en Javascript? Avec la fonction addEventListener(EVENT, CALLBACK); qui prend deux arguments, EVENT et CALLBACK.

Cette fonction s'appelle sur un élément HTML qu'il faut d'abord obtenir (get) et sauvegarder dans une variable:

const form = document.getElementById('form');
form.addEventListener(EVENT, CALLBACK);

Quel est l'événement déclencheur?

Tu trouveras une liste ici avec tous les événements. Lequel choisir? "scroll", "click", "mouseover"?

Regarde dans la section Form events, c'est à dire tous les événements reliés aux formulaires.

Il s'agit de l'événement 'submit'

Le callback d'une fonction c'est généralement... une autre fonction! C'est le code qui va être exécuté lorsque l'événement est déclenché.

function calculateRatio() {
  console.log("je suis dans la fonction!!!");
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Si tu ouvres ta console dans ton navigateur et appuies sur le bouton "Calculons", il ne se passe... rien! On ne voit pas les mots "je suis dans la fonction".

C'est un peu bizarre, mais pour régler ce problème, il faut rajouter une ligne dans notre fonction calculateRatio():

function calculateRatio() {
  console.log("je suis dans la fonction!!!");
  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Maintenant que notre fonction calculateRatio() fonctionne (haha), au lieu de faire un console log sur la string "je suis dans la fonction", on va faire un console.log() sur notre formulaire HTML.

Pourquoi?

Parce que dans notre formulaire se cachent les valeurs qu'on cherche pour calculer notre ratio!

Dans quelle variable de notre code JS avons-nous stocké l'élément HTML form? Comment pouvons-nous l'inspecter?

Regarde la variable form...

function calculateRatio() {
  console.log(form);
  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Ceci nous donne accès à l'élément form dans la console. Si tu cliques sur le triangle à côté de form tu vas pouvoir voir les "sous-éléments" input:

Comme on a vu à l'étape précédente, quand on clique sur l'élément form dans la console, on a accès à ses sous-éléments, dont les éléments input. Chaque input a un index, un peu comme dans un tableau (array en anglais). On accède à un élément d'un tableau en utilisant les accolades []: form[0].

Dans la console de ton navigateur, essaie de trouver comment accéder à la valeur (value, hint, hint) du premier input.

form[0].value

Tu peux maintenant utiliser ce code dans ta fonction calculateRatio() et sauvegarder le nombre de rouleaux dans une belle variable! Vérifie que ta variable stocke la bonne donnée avec un petit... console.log()!

function calculateRatio() {
  const rolls = XXXXX ;
  console.log(rolls);
  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Trouve l'index de l'élément input pour le nombre de jours de confinement dans l'élément form.

Comme pour les rouleaux, sauvegarde le nombre de jours de confinement dans une variable const lockdownDays = XXXX;

Vérifie que ta variable stocke la bonne donnée avec... console.log()!

function calculateRatio() {
  const rolls = XXXXX ;
  console.log(rolls);

  const lockdownDays = XXXXX ;
  console.log(lockdownDays);

  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Toujours dans la fonction calculateRatio(), on peut maintenant calculer le fameux ratio.

Imaginons qu'un dure 5 jours. Pour calculer le nombre total de jours pour lesquels on aura du papier, il faut faire: rolls * 5

Encore une fois, utilisons une variable pour stocker ce nombre total de jours: const paperDays = rolls * 5;

Vérifie que ta variable paperDays stocke la bonne donnée avec... Ok, ok, tu sais déjà quoi faire!

Il ne reste plus qu'à calculer le ratio. Imaginons que j'ai 3 chez moi. Vu que chaque dure 5 jours, il me reste du papier pour 15 jours. Si le confinement dure 15 jours, c'est parfait j'ai tout juste assez de papier. Mon ratio est de 100%.

Mais imagine que le confinement dure 30 jours. Là, je n'ai du papier de toilette que pour la moitié de mon confinement. Mon ratio est de 50%.

Quelle est la formule du ratio?

La formule du ratio est la suivante: paperDays / lockdownDays * 100

Tu peux maintenant stocker ton ratio dans une variable et... oui, oui, console.log(ratio); for the win!

function calculateRatio() {
  const rolls = XXXXX ;
  const days = XXXXX ;

  const paperDays = rolls * 5;
  // console.log(paperDays);

  const ratio = XXXXX ;
  console.log(ratio);

  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Que se passe-t-il s'il te reste 3 et que tu es confiné 27 jours? Quel sera ton ratio?

Pas génial, tous ces chiffres après la virgule! On a besoin d'arrondir notre ratio. Pour ceci, JavaScript a une fonction qui s'appelle... round().

En regardant documentation pour la fonction round(), arrives-tu à arrondir ton ratio?

Voici comment arrondir le ratio: Math.round(paperDays / lockdownDays * 100)

Il est temps d'afficher notre ratio sur notre page web (plutôt que dans la console).

Pour cela, il va falloir l'injecter dans notre HTML. Dans ton fichier HTML tu peux ajouter un élément div. Donne-lui un id pour que tu puisse facilement retrouver ta div dans ton JavaScript.

Retourne maintenant dans ton JavaScript. On veut que le contenu de la div soit notre ratio. En d'autres termes, on veut que notre HTML ressemble à ceci:

Pour spécifier le contenu d'un élément HTML, il y a une chouette fonction JavaScript qui s'appelle innerText. Si tu cliques sur lien de innerText, tu verras un exemple de comment utiliser cette fonction. Il y a deux étapes:

  1. Sélectionner l'élément HTML
  2. Insèrer le contenu

En JavaScript, il y a plusieurs fonctions pour séléctionner un ou plusieurs éléments HTML. Sais-tu lesquelles?

Comme notre div a déjà un id, on va utiliser la fonction .getElementById(). Celle-ci s'utilise ainsi:

document.getElementById("XXXX")

Remplace les XXXX par le nom de ton id, en gardant la même syntaxe que dans ton HTML. Dans mon cas, ce sera document.getElementById("output")

Il ne reste plus qu'à stocker notre élément HTML dans une variable et utiliser la fonction .innerText:

function calculateRatio() {
  // BLABLA PLEIN DE BEAU CODE

  const outputDiv = document.getElementById("output");
  outputDiv.innerText = XXXX;

  event.preventDefault();
}

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Et ça y est, notre ratio s'affiche!!!

Ratio s'affiche

Notre ratio fait un peu pitié. Il est perdu en-dessous du formulaire, on ne sait pas qu'il représente un pourcentage...

Première chose: ajouter le symbole %. Rajoute une string à ton ratio:

outputDiv.innerText = ratio + " %";

Et si on voulait que le ratio soit dans une balise h1? Dans ce cas, la fonction innerText n'est pas la plus appropriée. On a besoin d'une fonction qui permet d'insérer de l'HTML: innerHTML

On peut utiliser la fonction innerHTML comme ceci:

outputDiv.innerHTML = "<h1>" + ratio + " %" + "</h1>";

Pourrait-on simplifier cette ligne de code? La "refactoriser"? Si je pose la question, c'est que la réponse est oui... Essaie!

outputDiv.innerHTML = "<h1>" + ratio + " %</h1>";

À côté de notre ratio, on va ajouter un bel émoji! Celui-ci va dépendre du ratio. Si on est au-dessus de 100%, on est 😄, sinon c'est la... 💩

Et qui dit si, dit condition! Petit rappel sur la syntaxe d'une condition:

if (condition) {
  // SOME CODE
} else {
  // MORE CODE
}

Notre code aurait donc l'air de quelque chose comme ceci:

if (ratio XXXX 100) {
  outputDiv.innerHTML = "<h1>" + ratio + " %" + "😄" + "</h1>";
} else {
  XXXX
}

La version refactorisée de ce code?

if (ratio XXXX 100) {
  outputDiv.innerHTML = `<h1>${ratio} % 😄</h1>`;
} else {
  XXXX
}

ratio with emoji

Maintenant que la base fonctionne, on peut s'amuser avec le style. Au lieu d'un formulaire quelconque, pourquoi ne pas utiliser un curseur sur une ligne (slider en anglais)? Comme ceci:

On aura toujours besoin de l'élément HTML input mais cette fois-ci le type ne sera pas text mais range. Range veut dire écart.

Tu peux donc remplacer ton code HTML existant comme ceci:

À ton avis que veulent dire les propriétés min et max?

Elles veulent dire que le nombre de rouleau minimum est de zéro et le nombre maximum de 20. Tu sais quoi faire si tu veux permettre à tes visiteurs de calculer leur ratio avec un nombre de rouleaux plus élevé.

Finalement, tu peux te débarasser de l'input de type submit. En effet, on n'a plus besoin du bouton "Calculons".

sliders

Notre beau ratio a disparu 😭. C'est la faute du JavaScript! Regarde les dernières lignes de ton JS:

const form = document.getElementById('form');
form.addEventListener('submit', calculateRatio);

Notre fonction .addEventListener() attendait (écoutait) un événement de type 'submit'. Manque de pot, on vient d'enlever notre bouton "Calculons" (qui lui était un input de type submit). Qu'à cela ne tienne:on a de beaux curseurs, on va s'en servir!

On va maintenant écouter... nos curseurs! Et plus particulièrement, quand nos curseurs changent de position. Le temps est venu de retourner à notre documentation sur les événements.

S'il ne s'agit pas de 'submit', duquel s'agit-il?

Il s'agit de l'événement 'input'

Dans notre code JS, mettons en commentaire l'event listener sur notre variable form:

const form = document.getElementById('form');
// form.addEventListener('submit', calculateRatio);

Créons une variable rollsInput pour stocker l'élément HTML <input type="range">:

const form = document.getElementById('form');
// form.addEventListener('submit', calculateRatio);

const rollsInput = document.getElementById('XXXX');

Et finalement, ajoutons notre event listener:

const form = document.getElementById('form');
// form.addEventListener('submit', calculateRatio);

const rollsInput = document.getElementById('XXXX');
rollsInput.addEventListener('XXXX', calculateRatio);

Tu peux faire la même chose pour l'input des jours. Résultat des courses, le ratio s'affiche à nouveau:

sliders

Ce qui serait chouette, c'est que nos visiteurs puissent savoir exactement combien de rouleaux et de jours ils ont sélectionné avec les curseurs et que ces nombres se mettent à jour dès qu'on bouge le curseur:

sliders

La première chose à faire, c'est ajouter un élément HTML dans lequel on pourra injecter le nombre, grâce au JavaScript. Le plus facile, c'est d'utiliser un élément <span> dans notre élément <p>:

<p>Rouleaux restants: <span id="rolls-output"></span></p>

À ton avis, pourquoi a-t-on ajouté l'attribut id="rolls-output" à notre élément <span>?

Pour pouvoir sélectionner plus facilement l'élément dans notre JavaScript grâce à la fonction .getElementById()

À l'intérieur de notre fonction calculateRatio, on peut à présent aller sélectionner l'élément <span id="rolls-output"> et y injecter le nombre de rouleux. D'ailleurs... dans quelle variable est stockée le nombre de rouleaux?

function calculateRatio() {
  const rolls = form[0].value;
  const lockdownDays = form[1].value;

  const rollsOutput = document.getElementById('XXXX');
  rollsOutput.innerHTML = XXXX;

Fais la même chose pour le nombre de jours et le tour est joué!

C'est le temps de rendre tout ça BEAU!!! Voici quelques idées:

  • Choisis de belles couleurs: coolors peut t'aider à choisir une palette harmonieuse
  • Choisis de belles polices sur Google Fonts
  • Personnifie tes curseurs - tu trouveras un bon exemple sur w3schools
  • Centre tout grâce à des <div> et la propriété CSS margin