bonjour, je vous solicite car apres moultes modifications je crois que je m'emmele les pinceaux.

ce que je cherche a faire : intercepter les clics sur les liens "delete" et "default" d'une liste d'image pour les remplacer par des requetes ajax.

du cote ajax, ça fonctionne correctement, j'avais une version de mon code qui fonctionnait bien avec des liens hypertextes classiques

j'ai voulu remplacer ces liens textes par des icones, j'ai donc modifié mon code html et la le javascript ne reconnaissait plus les clics sur ces elements.

j'ai donc modifié mon javascript qui a mon sens devrait fonctionner mais je n'ai meme pas un message d'erreur.

voici ou j'en suis :

<div id="list-images">
<div class="container">
  <div class="row">
    {% for image in product.productImages %}
      <div class="col-lg-2 col-sm-4">
        <div class="position-relative">
          <img class="img-fluid" src="{{asset('/uploads/product/' ~ image.filename)}}" alt="image" width="200">
          <div class="d-flex justify-content-between align-items-center position-absolute p-2" style="bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.2);"> 
            {% if (image.isDefault==true) %}
              <span class="text-success"><i class="bi-star-fill" style="color:white;"></i></span>
            {% else %} 
              <a href="{{ path('set_default_product_image', {id: image.id, product_id:product.id})}}" data-default data-token="{{ csrf_token('default' ~ image.id )}}"><i class="bi-star" style="color:white;"></i></a>
            {% endif %}
            <a href="{{ path('delete_product_image', {id: image.id, product_id:product.id})}}" data-delete data-token="{{ csrf_token('delete' ~ image.id )}}"><i class="bi-trash" style="color:white;"></i></a>
          </div>
        </div>
      </div>
    {% endfor %}
  </div>
</div>
</div>

...

<script>

window.onload = () => {

    document.addEventListener("click", function(e) {
      if (e.target.matches("[data-default]")) {
      alert('ok');
        // Code pour la gestion des boutons "Mettre par défaut"

            e.preventDefault();
            e.stopPropagation();

            // Send an Ajax request to the server
            fetch(e.target.getAttribute("href"), {
                method: "POST",
                headers: {
                    "X-Requested-With": "XMLHttpRequest",
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({ "_token": e.target.dataset.token })
            }).then(
                // On récupère la réponse en JSON
                response => response.json()
            ).then(data => {
                if (data.success) {
                    // Update the list-images div with the new HTML
                    list_images_div.innerHTML = data.html;
                } else {
                    alert(data.error);
                }
            }).catch(e => alert(e))     

      } else if (e.target.matches("[data-delete]")) {
        // Code pour la gestion des boutons "Supprimer"

        e.preventDefault();
        e.stopPropagation();

        // Ask for confirmation
        if (confirm("Do you want to delete this image?")) {
          // Send an Ajax request to the server with the DELETE method
          fetch(e.target.getAttribute("href"), {
            method: "DELETE",
            headers: {
              "X-Requested-With": "XMLHttpRequest",
              "Content-Type": "application/json"
            },
            body: JSON.stringify({ "_token": e.target.dataset.token })
          }).then(
            // Get the response as JSON
            response => response.json()
          ).then(data => {
            if (data.success) {
              // Remove the image element
              e.target.parentElement.parentElement.parentElement.remove();
            } else {
              alert(data.error);
            }
          }).catch(e => alert(e))
        }       

      }
    });

}
</script>

quelqu'un est il inspiré ?

1 réponse


ce probleme est réglé (merci chatGPT, je suis epoustouflé)
donc mon code precedent ne fonctionnait pas sur les icones, il suffisait de prendre les icones comme selecteur
voici donc le code fonctionnel, fourni par chatGPT

<div id="list-images">
<div class="container">
  <div class="row">
    {% for image in product.productImages %}
      <div class="col-lg-2 col-sm-4">
        <div class="position-relative">
          <img class="img-fluid" src="{{asset('/uploads/product/' ~ image.filename)}}" alt="image" width="200">
          <div class="d-flex justify-content-between align-items-center position-absolute p-2" style="bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.2);"> 
            {% if (image.isDefault==true) %}
              <span><i class="bi-star-fill" style="color:yellow;"></i></span>
            {% else %} 
              <a href="{{ path('set_default_product_image', {id: image.id, product_id:product.id})}}" data-default data-token="{{ csrf_token('default' ~ image.id )}}"><i href="{{ path('set_default_product_image', {id: image.id, product_id:product.id})}}" class="bi-star" style="color:white;"></i></a>
            {% endif %}
            <a href="{{ path('delete_product_image', {id: image.id, product_id:product.id})}}" data-delete data-token="{{ csrf_token('delete' ~ image.id )}}"><i  href="{{ path('delete_product_image', {id: image.id, product_id:product.id})}}" data-delete data-token="{{ csrf_token('delete' ~ image.id )}}"class="bi-trash" style="color:white;"></i></a>
          </div>
        </div>
      </div>
    {% endfor %}
  </div>
</div>
</div>

<script>
  // Gestion des clics sur le div "list-images"
  let list_images_div = document.getElementById("list-images");
  list_images_div.addEventListener("click", function(e) {

    // Si l'élément cible a l'attribut data-default
    if (e.target.matches(".bi-star")) {
      e.preventDefault();
      e.stopPropagation();

      // Envoi d'une requête Ajax pour mettre l'image par défaut
      fetch(e.target.getAttribute("href"), {
        method: "POST",
        headers: {
          "X-Requested-With": "XMLHttpRequest",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ "_token": e.target.dataset.token })
      }).then(
        // Récupération de la réponse en JSON
        response => response.json()
      ).then(data => {
        if (data.success) {
          // Mise à jour du div "list-images" avec le nouveau HTML
          list_images_div.innerHTML = data.html;
        } else {
          alert(data.error);
        }
      }).catch(e => alert(e))
    }

    // Si l'élément cible a l'attribut data-delete
    if (e.target.matches(".bi-trash")) {
      e.preventDefault();
      e.stopPropagation();

 // Demande de confirmation avant suppression
  if (confirm("Do you want to delete this image?")) {
    // Envoi d'une requête Ajax au serveur avec la méthode DELETE
    fetch(e.target.getAttribute("href"), {
      method: "DELETE",
      headers: {
        "X-Requested-With": "XMLHttpRequest",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ "_token": e.target.dataset.token })
    }).then(
      // Récupération de la réponse en JSON
      response => response.json()
    ).then(data => {
      if (data.success) {
        // Suppression de l'élément image
        e.target.parentElement.parentElement.parentElement.remove();
      } else {
        alert(data.error);
      }
    }).catch(e => alert(e))
  }
}
});
</script>