Calcul automatique d'un panier
Calcul et mise à jour automatique d'un panier en fonction des quantités choisies.
Liste produits
Remarques
Les articles sélectionnés sont ajoutés à un formulaire, élément <form>
, le but final étant quand même d'envoyer les données côté serveur pour traitement.
Différentes méthodes peuvent être utilisée pour transférer un article dans le panier, clonage, copie, création dynamique.
On peut se servir avantageusement du CSS pour afficher/masquer des éléments suivant qu'ils se trouvent dans la liste ou dans le panier.
Ne jamais faire confiance aux données soumises via un formulaire, ou autres d'ailleurs, toujours les vérifier côté serveur, on ne le dira jamais assez.
Dans le cas présent seules les données REF_PRODUIT et QUANTITE seraient à exploiter.
Gestionnaire d'événements
On pourrait affecter un écouteur à chaque <input type="number" name="quantite[]">
comme suit par exemple :
const inputs = element.querySelectorAll("[name='quantite[]']");
inputs.forEach((input) => {
input.addEventListener("input", calculArticle);
});
Mais le panier étant dynamique, il faudrait donc affecter cet événement à chaque nouvel ajout. On notera quand même que cela peut dépendre de la méthode utilisée pour transférer un article dans le panier.
En mettant l'écouteur directement sur le formulaire cette gestion n'est plus à faire, on ne se soucie pas du nombre d'articles dans le formulaire, c'est ce que l'on appelle la délégation d’événement.
C'est sur l'élément <form>
que nous allons mettre l'écouteur pour le changement de quantité des articles.
const formPanier = document.getElementById(ID_FORM_PANIER);
formPanier.addEventListener("input", calculArticle);
Mise à jour du panier
Lors de la modification d'une quantité, on va mettre à jour la ligne concernée puis faire une mise à jour de l'ensemble du panier en parcourant tous les articles présents dans le formulaire.
/**
* @param {event} e.target contient l'INPUT type="number" modifié
*/
function calculArticle(e) {
// get élément ligne
const input = e.target;
const parent = input.closest(".article");
const elemPrix = parent.querySelector("[name='prix[]']");
const elemTotal = parent.querySelector(".total-ligne");
// calcul
const value = +input.value * +elemPrix.value;
// affiche résultat
elemTotal.textContent = value.toFixed(2);
// mise à jour total
calculTotalPanier();
}
function calculTotalPanier() {
const elemTotal = document.getElementById(ID_TOTAL_PANIER);
const elemPrix = document.querySelectorAll(".total-ligne");
let somme = 0;
elemPrix.forEach((el) => {
somme += +el.textContent;
});
// affiche résultat
elemTotal.textContent = somme.toFixed(2);
// active/désactive le bouton soumission
document.getElementById("valid-panier").disabled = somme == 0;
}
On pourrait également faire la mise à jour d'une façon plus globale en parcourant tous les articles présents dans le panier, en mettant à jour leur total et en faisant le cumul pour mettre à jour le total du panier.
Dans ce cas même les articles n'ayant pas été modifiés seraient (re)mis à jour.
Le résultat serait le même, et encore heureux !