2010-05-05 7 views
6

Estoy intentando clonar un div y cambiar los nombres de los campos de entrada en este div. Funciona de maravilla para la mayoría de los navegadores, pero IE 7 no cambia el atributo de nombre de los campos de entrada.Problema de copia de jQuery

Demostración: http://jsbin.com/iduro/7

HTML

<body> 
    <pre></pre> 
    <div><input value="Hello World" name="test"></div> 
</body> 

JS

var lastRow = $("body div:last"), 
    newRow = lastRow.clone(true) 
       .show() 
       .insertAfter(lastRow); 

newRow.find('input').attr("name","test2"); 

$("pre").text(newRow[0].innerHTML); 

Resultados:

Firefox: (obras) <input value="Hello World" name="test2">

IE8 (obras) <INPUT value="Hello World" name=test2 jQuery1273063250500="4">

IE7 (bug): <INPUT value="Hello World" name=test jQuery1273063303968="4">

Como se ve el nombre de IE7 no cambia a test2.

¿Hay alguna razón o problema obvio?

+1

Consulte esta pregunta relacionada: http://stackoverflow.com/questions/2094618/changing-name-attr-of-cloned-input-element-in-jquery-doesnt-work-in-ie6-7 –

Respuesta

2

Podría arreglarlo por el momento. Siempre que un campo de entrada no esté conectado al dom, puede cambiar el nombre y los botones de opción vuelven a funcionar correctamente.

// Old Code 
$("div:last").clone(true).children("input").attr("name","newName"); 

// New Code 
$("div:last").clone(true).children("input").fixCloneBug ("newName"); 

Para reducir el tiempo de ejecución, solo se copian los jQuery Events, className y el atributo de tipo.

fixCloneBug Método:

(function($) 
{ 


    if (! $.browser.msie || parseInt($.browser.version) > 7) 
     // NO FIX FOR IE 7+ FF WEBKIT 
     $.fn.fixCloneBug = function(newName){ return this.attr("name", newName) }; 
    else 
     // FIX IE 5-7 
     $.fn.fixCloneBug = function(newName) 
     { 
      var $cloned = $(); 

      this.each(function() 
      { 
        /* -._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._ 

         Create a new element with className and jQuery events of the buggy element 

        */   

        var  $elem = $(this), 

          $newElem = $(document.createElement($elem.attr('tagName'))); 

          // USE SAME TYPE 

        $newElem.attr('type', $elem.attr('type')); 


          // SET NAME 
        $newElem.attr('name', this.name); 
        $newElem.attr('name', newName); 

          // ADD TO DOM 

        $newElem.insertBefore($elem); 

          // CLONE EVENTS 
        $newElem.data("events", $elem.data("events")); 

          // CLASS NAME 
        $newElem.attr('className', this.className); 

        /* -._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._ 

         Delete buggy element 

        */ 

        $elem.remove(); 


        // Add to result 
        $cloned.push($newElem); 
      }) 

      return $cloned; 

     } 

}(jQuery)); 

Tal vez usted piensa $newElem.attr('name', this.name); es sin embargo inútil que me permite utilizar una función de jQuery 1.4:

.fixCloneBug (function(i,oldname){ return oldname+"_new" })

0

Si realiza un cambio al acceder a estos como un conjunto cuando se publica el formulario, entonces no hay necesidad de cambiar el nombre; simplemente no coloque un valor entre los corchetes y se incrementará cuando agarre la matriz en el del lado del servidor:

<input name="test[]" />

Si tiene que ser capaz de acceder a cada uno por el índice de js que sólo puede utilizar get en la recogida adecuado devuelto por un selector. O puede asignar atributos de ID como test_1.

+2

Intento clonar una fila de botones de radio. Sin embargo, como el cambio del nombre no funciona, el usuario solo puede elegir un botón de opción para ambas filas en lugar de dos. – jantimon

+0

@prodigtalson +1. Intenté esto cuando me encontré con la misma solución y resolví mi problema. Solo utilicé entradas de texto y sentencias seleccionadas, por lo que los problemas de radio como se mencionó anteriormente pueden seguir ocurriendo. – canadiancreed

+0

Información útil, pero -1 porque esto no responde la pregunta que se hizo. – RMorrisey

0

La solución más sencilla para el botón de radio es:

$("div:last").find("radio").each(function(){ 
    var name="someNewName"; 
    var id="someNewId"; 
    if (!$.browser.msie || parseInt($.browser.version) > 7) { 
     this.name = name; 
     this.id=id; 
    } 
    else { 
     (this).attr("outerHTML", "<input type=radio id=" + id + " name=" + name + " />"); 
    } 
}); 

Esto alterará el outerHTML del elemento para que se sobrescriba el HTML del elemento (botón de opción). Se puede aplicar la misma solución para: find ("input")/find ("checkbox") para los otros controles también.

1

probar este (código sin procesar)

$(some_cloned_element).each(function(i, elem){ 
    var newName = "yay_i_love_my_new_name"; 
    if ($.browser.msie === true){ // evil browser sniffing *cries* 
     $(elem).replaceWith(document.createElement(
      this.outerHTML.replace(/name=\w+/ig, 'name='+newName+'_'+i) 
     )); 
    } else { 
     $(elem).attr('name',newName+'_'+i); 
    } 
    $("body").append(some_cloned_element); 
}); 

cheque cuando i = 50 y luego descanso/salida

mejor manera: nombre uso como matriz como name=picture[]

Refernece