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;
});
});
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).
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
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 !
Manipuler un objet créé dynamiquement
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
suggestion de présentation.