2009-01-06 18 views
50

Tengo un elemento HTML con una gran colección de listas desordenadas contenidas en él. Necesito clonar este elemento para colocarlo en otro lugar de la página con diferentes estilos agregados (esto es bastante simple usando jQuery).jQuery clon duplicate IDs

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

El problema, sin embargo, es que todas las listas y sus elementos de lista asociados tienen ID y clone ellos duplicados. ¿Hay alguna manera fácil de reemplazar todos estos ID duplicados con jQuery antes de agregarlos?

+4

@ Adam Naylor Ser smarmy no es útil. –

Respuesta

38

Si necesita una forma de hacer referencia a los elementos de la lista después de haberlos clonado, debe usar clases, no ID. Cambiar todos id = "..." a clase = "..."

Si está tratando con código heredado o algo así y no puede cambiar los ID a clases, debe eliminar los atributos de id. Antes de anexar.

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

Tenga en cuenta que ya no tiene forma de referenciar los artículos individuales.

+1

¿No se puede lograr algo similar pero se reemplazan los ids? – Sheff

+1

Luego debe hacer un seguimiento de cómo se cambiaron los ids (es decir, prefijo, postfijo) y utilizar la concatenación de cadenas para reconstruir los identificadores correctos al hacer referencia a los elementos clonados. Molesto. Solo usa clases. –

+0

Clonar y cambiar la identificación: "http://stackoverflow.com/questions/10126395/how-to-jquery-clone-and-change-id" –

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

Pruébalo para el tamaño. :)

[Editar] Reparado para el comentario de redsquare.

+0

Quitaría el id antes de ejecutar el complemento; de lo contrario, duplicaría el ID en el dom todavía, lo que podría tener efectos desagradables. – redsquare

+0

Eso es básicamente lo que Salty está haciendo en su ejemplo, creo. Lo intentaré, pero preferiría usar un descubrimiento global para todos los niños en caso de que el marcado cambie y otros elementos dentro del padre sean engañados – Sheff

+0

No hay problema. Gracias por captar mi error =] – Salty

0

Si tiene varios elementos similares en una página, es mejor usar clases, no identificadores. De esta forma puede aplicar estilos a uls dentro de diferentes identificadores de contenedor.

5

Uso algo como esto: $ ("# details"). Clone(). Attr ('id', 'details_clone'). After ("h1"). Show();

+3

Ah, eso es aún más corto: 'var i = $ ('# itemBase') ; i.clone (true) .attr ('id', 'item' + nextItemId ++) .removeClass ('hidden'). addClass ('item'). insertAfter (i); ' – dlamblin

18

Dado que OP solicitó una forma de reemplazar todas las identificaciones duplicadas antes de anexarlas, quizás algo como esto funcionaría. Suponiendo que quería clonar MainConfig_1 en un bloque de HTML como este:

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

El código podría ser algo como lo siguiente, para encontrar todos los elementos secundarios (y descendientes) del bloque clonado, y modificar su ID de usar una contador:

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")); 

para crear nuevas HTML así:

<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

esto se basa en la respuesta de Russell, pero un poco más estético y funcional para las formas. 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); 

    }); 
}); 

El marcado:

<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, que utiliza la función de Darío, pero necesitaba recuperar las etiquetas de formulario también.

Añadir otra sentencia if como esta para hacerlo:

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

Creo que esta es la mejor manera

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.