Partage
  • Partager sur Facebook
  • Partager sur Twitter

Manipuler un objet créé dynamiquement

Sujet résolu
    10 mai 2022 à 16:28:51

    Bonjour,

    J'ai une petite fonction Javascript qui clone une ligne d'un tableau lorsque je clique sur une icône de cette même ligne.
    Pas de souci pour ça, la ligne est parfaitement copiée.

    Le problème que je rencontre est qu'en cas de clique sur l'icône de clonage de la nouvelle ligne, alors rien ne se passe, et je ne parviens pas à trouver la solution pour que mon "querySelectorAll" du départ prenne en charge ce nouvel élément.

    Mon javascript de clonage :

    let table = document.getElementById('customFieldTable').tBodies[0];
            let CustomFieldRowsUps = document.querySelectorAll('[data-action="up"]');
            CustomFieldRowsUps.forEach(CustomFieldRow => {
                CustomFieldRow.addEventListener('click', function(e) {
                    let row = this.parentNode.parentNode;
                    let newNode = table.rows[row.rowIndex - 1].cloneNode(true);
                    let newRow = table.insertRow(row.rowIndex - 2);
                    newRow.innerHTML = newNode.innerHTML;
                });
            });

    Par avance, merci !! :)

    • Partager sur Facebook
    • Partager sur Twitter
      10 mai 2022 à 19:36:15

      Bonjour, en principe quand tu as cloné la ligne les écouteurs d'événements on été cloner aussi:

      let newNode = table.rows[row.rowIndex - 1].cloneNode(true);

      Donc la nouvelle ligne aurait dût déjà avoir sont "icône de clonage" qui fonctionne correctement.

      Le problème vient de l'insertion de contenu.

      Quand tu utilises innerHTML pour insérer du contenu tu insère uniquement la structure HTML en perdant toutes les données qui leurs étaient associé (comme des écouteurs d'événements par exemple).

      Voir stackoverflow - innerHTML and event listeners

      Tu peux peut-être ajouter le nouvelle élément avec un appendChild:

      // newRow.innerHTML = newNode.innerHTML;
      newRow.appendChild(newNode);

      Une autre façon de régler le problème pourrait être d'ajouter l'écouteur d'événement sur l'icone après avoir insérer le contenu:

      let table = document.getElementById('customFieldTable').tBodies[0];
      let CustomFieldRowsUps = document.querySelectorAll('[data-action="up"]');
      
      function onCloneRow(e) {
      
          let row = this.parentNode.parentNode;
          let newNode = table.rows[row.rowIndex - 1].cloneNode(true);
          let newRow = table.insertRow(row.rowIndex - 2);
      
      	// l'insertion de contenu via innerHTML
          // à tué les écouteurs d'événements sur le contenue
          newRow.innerHTML = newNode.innerHTML;
          
          // ajoute "artificiellement" les écouteurs d'événements sur le contenu qui à été inseré
          const newIconClone = newNode.querySelector("[data-action=\"up\"]");
          newIconClone.addEventListener("click", onCloneRow);
      }
      
      CustomFieldRowsUps.forEach(CustomFieldRow => {
          CustomFieldRow.addEventListener('click', onCloneRow);
      })

      Pour que cela fonctionne il faut déplacer la fonction anonyme dans une fonction nommé et appart, car on à besoin d'y faire référence.

      Je trouve cette technique assez "artificiel" il faut re construire les écouteurs d'événements (est éventuellement les autres données perdue durant l'insertion de contenu) et si il y en a plusieurs il faudra ajouter des lignes de codes pour ré ajouter les autres écouteurs d'événements.

          // ajoute "artificiellement" les écouteurs d'événements sur le contenu qui à été inseré
          const newIconClone = newNode.querySelector("[data-action=\"up\"]");
          newIconClone.addEventListener("click", onCloneRow);
          
          // si newNode contient d'autre écouters d'événements
      	// il devront être ajouté ici:
          // newNode.querySelector("...").addEventListener(...);






      -
      Edité par SamuelGaborieau3 10 mai 2022 à 19:42:01

      • Partager sur Facebook
      • Partager sur Twitter

      suggestion de présentation.

        11 mai 2022 à 9:30:22

        Bonjour,

        Tout d'abord merci pour l'explication très détaillée ! :)

        J'avais testé avec "newRow.appendChild(newNode);" mais il était ajouté le TR complet à l'intérieur de la ligne nouvellement créée (donc un TR), ce qui amenait quelques soucis d'affichage... ;)
        Je vais voir pour trouver comment insérer seulement l'intérieur du TR et du coup, ça devrait fonctionner.

        Merci ! :)

        • Partager sur Facebook
        • Partager sur Twitter

        Manipuler un objet créé dynamiquement

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown