53 votes

jQuery clone les ID en double

J'ai un élément HTML qui contient une grande collection de listes non ordonnées. J'ai besoin de cloner cet élément pour le placer ailleurs sur la page avec des styles différents (c'est assez simple en utilisant jQuery).

$("#MainConfig").clone(false).appendTo($("#smallConfig"));

Le problème, cependant, est que toutes les listes et les éléments de liste qui leur sont associés ont des ID et des noms de domaine. clone les duplique. Existe-t-il un moyen simple de remplacer tous ces identifiants en double à l'aide de jQuery avant de les ajouter ?

44voto

Crescent Fresh Points 54070

Si vous avez besoin d'un moyen de référencer les éléments de la liste après les avoir clonés, vous devez utiliser des classes, et non des ID. Remplacez tous les id="..." par des class="...".

Si vous avez affaire à un code hérité ou autre et que vous ne pouvez pas changer les ID en classes, vous devez supprimer les attributs id avant de les ajouter.

$("#MainConfig").clone(false).find("*").removeAttr("id").appendTo($("#smallConfig"));

Sachez simplement que vous n'avez plus la possibilité de faire référence à des éléments individuels.

1 votes

Ne peut-on pas réaliser quelque chose de similaire mais en remplaçant les identifiants ?

1 votes

Vous devez ensuite déterminer comment les identifiants ont été modifiés (préfixe, postfixe) et utiliser la concaténation de chaînes de caractères pour reconstituer les identifiants corrects lors de la référence aux éléments clonés. C'est ennuyeux. Utilisez simplement des classes.

0 votes

Clone et changement d'identifiant : " stackoverflow.com/questions/10126395/ "

19voto

Russell G Points 188

Puisque le PO a demandé un moyen de remplacer tous les identifiants en double avant de les ajouter, quelque chose comme ceci pourrait fonctionner. En supposant que vous vouliez cloner MainConfig_1 dans un bloc HTML tel que celui-ci :

<div id="smallConfig">
    <div id="MainConfig_1">
        <ul>
            <li id="red_1">red</li>
            <li id="blue_1">blue</li>
        </ul>
    </div>
</div>

Le code pourrait être quelque chose comme le suivant, pour trouver tous les éléments enfants (et descendants) du bloc cloné, et modifier leurs identifiants en utilisant un compteur :

var cur_num = 1;    // Counter used previously.
//...
var cloned = $("#MainConfig_" + cur_num).clone(true, true).get(0);
++cur_num;
cloned.id = "MainConfig_" + cur_num;                  // Change the div itself.
$(cloned).find("*").each(function(index, element) {   // And all inner elements.
    if(element.id)
    {
        var matches = element.id.match(/(.+)_\d+/);
        if(matches && matches.length >= 2)            // Captures start at [1].
            element.id = matches[1] + "_" + cur_num;
    }
});
$(cloned).appendTo($("#smallConfig"));

Pour créer un nouveau HTML comme celui-ci :

<div id="smallConfig">
    <div id="MainConfig_1">
        <ul>
            <li id="red_1">red</li>
            <li id="blue_1">blue</li>
        </ul>
    </div>
    <div id="MainConfig_2">
        <ul>
            <li id="red_2">red</li>
            <li id="blue_2">blue</li>
        </ul>
    </div>
</div>

16voto

Salty Points 4407
$("#MainConfig")
    .clone(false)
    .find("ul,li")
    .removeAttr("id")
    .appendTo($("#smallConfig"));

Essayez-le pour la taille. :)

[Edit] Corrigé pour le commentaire de redsquare.

0 votes

J'enlèverais les ids avant de lancer l'append, sinon vous dupliquez encore les ids dans le dom, ce qui pourrait avoir des effets désagréables.

0 votes

C'est essentiellement ce que fait Salty dans son exemple, je pense. Je vais essayer, mais je préférerais utiliser une recherche globale pour tous les enfants au cas où le balisage changerait et que d'autres éléments du parent seraient dupliqués.

0 votes

Pas de problème. Merci d'avoir repéré mon erreur =]

6voto

J'utilise quelque chose comme ceci : $("#details").clone().attr('id', 'details_clone').after("h1").show() ;

3 votes

Oh, c'est encore plus court : var i=$('#itemBase'); i.clone(true).attr('id','item'+nextItemId++) .removeClass('hidden').addClass('item').insertAfter(i);

4voto

Dario Novoa Points 65

Cette réponse est basée sur celle de Russell, mais elle est un peu plus esthétique et fonctionnelle pour les formes. jQuery :

$(document).ready(function(){
   var cur_num = 1;    // Counter

    $('#btnClone').click(function(){

          var whatToClone = $("#MainConfig"); 
          var whereToPutIt = $("#smallConfig");

          var cloned = whatToClone.clone(true, true).get(0);
          ++cur_num;
          cloned.id = whatToClone.attr('id') + "_" + cur_num;                  // Change the div itself.

        $(cloned).find("*").each(function(index, element) {   // And all inner elements.
          if(element.id)
          {
              var matches = element.id.match(/(.+)_\d+/);
              if(matches && matches.length >= 2)            // Captures start at [1].
                  element.id = matches[1] + "_" + cur_num;
          }
          if(element.name)
          {
              var matches = element.name.match(/(.+)_\d+/);
              if(matches && matches.length >= 2)            // Captures start at [1].
                  element.name = matches[1] + "_" + cur_num;
          }

         });

       $(cloned).appendTo( whereToPutIt );

    });
});

Le balisage :

<div id="smallConfig">
    <div id="MainConfig">
        <ul>
            <li id="red_1">red</li>
            <li id="blue_1">blue</li>
        </ul>
      <input id="purple" type="text" value="I'm a text box" name="textboxIsaid_1" />
    </div>
</div>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X