2009-01-06 5 views
50

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

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

Le problème, cependant, est que les ID et ont clone les listes reproduisant l'ensemble des et leurs éléments de liste associés. Existe-t-il un moyen facile de remplacer tous ces ID en double en utilisant jQuery avant de l'ajouter?

+4

@Adam Naylor être flagorneur est pas utile. –

Répondre

38

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

Si vous traitez avec du code existant ou quelque chose 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 que vous n'avez plus aucun moyen de référencer des éléments individuels.

+1

Est-il possible de faire quelque chose de similaire mais de remplacer les identifiants? – Sheff

+1

Ensuite, vous devez suivre la façon dont les identifiants ont été modifiés (c'est-à-dire, préfixe, suffixe) et utiliser la concaténation de chaîne pour reconstruire les identifiants corrects lors du référencement des éléments clonés. Ennuyeux. Utilisez simplement des classes. –

+0

Cloner et modifier l'identifiant: "http://stackoverflow.com/questions/10126395/how-to-jquery-clone-and-change-id" –

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

Essayez-le pour la taille. :)

[Éditer] Correction pour le commentaire de redsquare.

+0

Je voudrais supprimer l'ID avant d'exécuter l'append sinon votre duplication de l'ID dans le dom qui pourrait avoir des effets désagréables – redsquare

+0

Ce «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 d'autres éléments dans le parent seraient dupés – Sheff

+0

Aucun problème. Merci d'avoir attrapé mon erreur =] – Salty

0

Si vous avez plusieurs éléments similaires sur une page, il est préférable d'utiliser des classes, pas des identifiants. De cette façon, vous pouvez appliquer des styles à ul dans différents identifiants de conteneur.

5

J'utilise quelque chose comme ceci: $ ("# details"). Clone(). Attr ('id', 'details_clone'). Après ("h1"). Show();

+3

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

18

Depuis que l'OP a demandé un moyen de remplacer tous les ID en double avant de les ajouter, peut-être que quelque chose comme ça fonctionnerait. En supposant que vous vouliez cloner MainConfig_1 dans un bloc 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> 

Le code pourrait être quelque chose comme ce qui suit, pour trouver tous les éléments enfants (et descendants) du bloc cloné, et modifier leur carte d'identité de l'aide d'un contre:

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 ceci:

<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> 
3

Ceci est basé sur la réponse de Russell, mais un peu plus esthétique et fonctionnelle des 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> 
2

FWIW, j'utilise la fonction de Dario, mais nécessaire pour prendre forme des étiquettes aussi bien.

Ajouter une autre instruction if comme celui-ci à faire:

if(element.htmlFor){ 
var matches = element.htmlFor.match(/(.+)_\d+/); 
if(matches && matches.length >= 2)   // Captures start at [1]. 
    element.htmlFor = matches[1] + "_" + cur_num; 
} 
0

Je crois que c'est la meilleure façon

var $clone = $("#MainConfig").clone(false); 
$clone.removeAttr('id'); // remove id="MainConfig" 
$clone.find('[id]').removeAttr('id'); // remove all other id attributes 
$clone.appendTo($("#smallConfig")); // add to DOM.