'creat event listener for each product JS

I have to build an event listener that listens for a click to delete the product it's linked to; for this I was asked to use element.closest().

Here is the HTML that is being generated for each product:

<article class="cart__item" data-id="${product._id}" data-color="${chosenProduct.color}">
  <div class="cart__item__img">
    <img src="${product.imageUrl}" alt="${product.altTxt}">
  </div>
  <div class="cart__item__content">
    <div class="cart__item__content__description">
      <h2>${product.name}</h2>
      <p>${chosenProduct.color}</p>
      <p>${product.price}€</p>
    </div>
    <div class="cart__item__content__settings">
      <div class="cart__item__content__settings__quantity">
        <p>Qté : ${quantity}</p>
        <input type="number" class="itemQuantity" name="itemQuantity" min="1" max="100" value="${quantity}">
      </div>
      <div class="cart__item__content__settings__delete">
        <p class="deleteItem">Supprimer</p>
      </div>
    </div>
  </div>
</article>

As you can see, the identity of the product is inside the article tag.

I launch my function with the event listener with a delay, to make sure the HTML is created, so that I can collect the button(s).

window.setTimeout(function deleteButton() {
  const buttons = document.querySelectorAll(".deleteItem");

  buttons.forEach((button) => {
    button.addEventListener("click", deleteProduct);
  });
}, 800);

With this code, each button responds to the function, but they only delete the first product.

Here is what the delete function looks like:

function deleteProduct() {
  const itemToDelete = document.querySelector(".cart__item__content");
  const idProductToDelete = itemToDelete.closest("article").getAttribute("data-id");
  const colorProductToDelete = itemToDelete.closest("article").getAttribute("data-color");
  const productToDelete = "product-" + idProductToDelete + "-" + colorProductToDelete;
  //remove the item from local storage
  localStorage.removeItem(productToDelete);
  //remove from the html instantly
  deleteHtml();
}

What I understand is that: element.closest() only works with querySelector() (I can't get it to work with getElements etc...), but querySelector() returns only the first element it finds.

How can I make this work?



Solution 1:[1]

    function deleteProduct() {
  const itemToDelete = event.target.querySelector(".cart__item__content");
  const idProductToDelete = itemToDelete.closest("article").getAttribute("data-id");
  const colorProductToDelete = itemToDelete.closest("article").getAttribute("data-color");
  const productToDelete = "product-" + idProductToDelete + "-" + colorProductToDelete;
  //   //remove the item from local storage
  localStorage.removeItem(productToDelete);
  //   //remove from the html instantly
  deleteHtml();
}

Instead of using document.querySelector, you can use the click event's target element. closest would work for it.

or you can directly use

const idProductToDelete = event.target.closest("article").getAttribute("data-id");

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anuja