Pour cet exercice le SASS/CSS est purement décoratif.
Le JavaScript
main.js
Le point d’entrée de nos scripts est celui que l’on a chargé directement dans le HTML : main.js.
Voici donc le contenu du fichier assets/javascript/main.js :
Il n’a l’air de rien comme ça mais c’est la magie des modules : on isole les comportements.
Nous commençons par importer une fonction initCart depuis notre module cart.js.
Nous appelons ensuite cette fonction dès que le DOM a fini de se charger.
cart.js
cart.js est un plus gros morceau puisqu’il contient tout notre logique, nous allons donc progresser étape par étape.
Tout d’abord, initCart() qui était appellée dans notre main.js doit être déclarée et ensuite être exportée (pour que nous puissions l’importer dans main.js).
initCart() fait donc appel à 4 choses différentes :
getCart() va nous permettre de récupérer l’état actuel du panier
saveCart() va nous permettre de sauvegarder l’état actuel du panier
fakeCart sont des données de démonstration pour notre panier
renderCart() nous permet d’afficher notre panier en l’injectant dans notre HTML
getCart()
La fonction getCart() va nous permettre de récupérer l’état actuel du panier que nous stockons dans le sessionStorage :
Nous allons chercher dans le sessionStorage notre panier. Pour économiser le storage nous transformons notre avons transformé notre objet en string JSON avant de le stocker.
Nous devons donc utiliser JSON.parse pour le retransformer en objet.
saveCart()
La fonction saveCart() va nous permettre de sauvegarder dans le sessionStorage l’état actuel de notre panier.
Nous sauvegardons donc le $cart que nous avons reçu sous forme de string JSON (JSON.stringify) dans le sessionStorage.
fakeCart
fakeCart est un objet représentant notre panier et son contenu que nous utilisons pour faire notre démonstration.
Dans un vrai site il serait relié, via des appels à fetch au panier réel de notre client-e.
renderCart()
renderCart() c’est la fonction qui va nous permettre d’afficher notre panier et ses produits.
Elle va remplir notre HTML avec le HTML qui correspond aux produits du panier.
Tout d’abord nous récupérons la version la plus à jour de notre panier pour être sûr-e-s d’afficher le bon :
Petit rappel de notre HTML notre liste de produits va aller se placer dans le <main> de l’<aside>:
Il faut savoir que quand on veut ajouter des éléments HTML avec du JavaScript il faut les ajouter un par un.
Pour éviter de devoir ajouter tous nos <li> un par un, nous allons retirer le <ul> déjà présent pour le remplacer par le notre que nous aurons pré-rempli.
Nous allons ensuite créer une liste de <li> contenant les bonnes infos sur nos produits ainsi que nos boutons d’action et l’ajouter à notre <ul>.
Nous n’ajoutons un <li> dans notre HTML que si la quantité du produit dans le panier est supérieure à 0.
Comme nous avons pas mal de manipulations du DOM à faire pour créer les articles dans notre panier, nous isolons la création dans une fonction : createCartItem().
createCartItem()
Comme vous pouvez le voir la fonction est longue mais en soi elle n’est pas compliquée juste répétitive.
Nous créons d’abord la <section> qui contiendra tout le monde puis la <figure> et l’<img> de notre produit puis nous assemblons le tout.
Nous créons ensuite la <section> qui contiendra les informations du produit et nous l’ajoutons à la suite du reste :
Ensuite nous construisons bloc par bloc la <section> qui contient les boutons pour changer la quantité et l’affichage du prix du produit et nous lájoutons à la suite :
Et enfin nous renvoyons le tout pour qu’il soit inséré dans le <li> :
Retour à notre fonction renderCart(), qui doit finir son travail.
Elle affiche le prix total du panier dans le header du panier. Puis elle appelle une fonction loadListeners() maintenant que notre nouveau DOM est en place.
loadListeners()
loadListeners() est la fonction qui va nous permettre d’écouter les clics sur tout nos boutons d’ajout ou retrait de quantité d’articles dans le panier.
En utilisant leur attribut class, nous récupérons tous nos boutons :
Nous parcourons la liste et attachons à chaque bouton d’ajout la fonction addItem et à chaque bouton de retrait la fonction removeItem :
addItem()
addItem() est la fonction qui permet d’augmenter de 1 la quantité d’un produit dans le panier :
Nous récupérons l’id du produit concerné en utilisant l’attribut data-product-id de notre bouton.
Comment savons nous quel bouton a été cliqué ? En utilisant l’attribut event.target de l’évenement que nous envoie notre listener.
Nous recherchons ensuite dans les produits de notre panier l’index auquel se trouve celui que nous voulons modifier en utilisant une fonction findItem() que nous avons créée.
findItem() parcourt notre liste de produit et nous renvoie l’index du produit que nous cherchons si elle le trouve sinon elle renvoie null.
Attention : nous avons récupéré l’id depuis le DOM c’est donc une string mais dans notre objet c’est un nombre, pour éviter les problèmes lors de la comparaison nous transformons l’id du DOM en nombre (parseInt()).
Nous vérifions que findItem a bien trouvé le produit (en vérifiant que son retour n’est pas null) puis nous mettons à jour la quantité et enfin nous suavegardons notre panier.
Nous allons ensuite utiliser la fonction computeCartTotal() pour mettre à jour le prix total du panier et appeler renderCart() pour afficher notre panier modifié.
computeCartTotal()
computeCartTotal met le prix total du panier à 0, puis parcourt la liste des produits puis ajoute pour chaque produit quantité x prix au prix total puis sauvegarde le panier.
removeItem()
removeItem fonctionne exactement comme addItem sauf que l’on fait - 1 au lieu de + 1 :
Vous pourrez ensuite relier ce panier au vrai système backend de votre site (par exemple en utilisant fetch et les $_SESSION en PHP) !