2010-05-05 14 views
6

J'essaye de cloner un div et de changer les noms des champs d'entrée dans ce div. Cela fonctionne très bien pour la plupart des navigateurs, mais IE 7 ne modifie pas l'attribut name des champs de saisie.Problème jQuery clone

Démo: 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); 

Résultats:

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

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

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

Comme vous voyez le nom de IE7 ne change pas test2.

Y at-il une raison évidente ou un problème?

+1

Voir cette question connexe: http://stackoverflow.com/questions/2094618/changing-name-attr-of-cloned-input-element-in-jquery-doesnt-work-in-ie6-7 –

Répondre

2

Je pourrais le réparer pour l'instant. Tant qu'un champ de saisie n'est pas attaché au dom, vous pouvez changer le nom et les boutons radio fonctionneront de nouveau correctement. Pour réduire la durée d'exécution, seuls les événements jQuery, le nom de classe et l'attribut de type sont copiés.

fixCloneBug Méthode:

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

Peut-être que vous pensez $newElem.attr('name', this.name); est inutile mais il me permet d'utiliser une fonction jQuery 1.4:

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

0

Si vous effectuez un panoramique en accédant à ceux-ci en tant qu'ensemble lorsque le formulaire est publié, il n'est pas nécessaire de changer le nom - ne mettez pas de valeur entre parenthèses et il sera incrémenté pour vous lorsque vous saisissez le tableau. côté serveur:

<input name="test[]" />

Si vous devez être en mesure d'accéder à chacun par l'indice de js vous pouvez simplement utiliser get sur la collecte appropriée renvoyée par un sélecteur. Vous pouvez également attribuer des attributs d'ID tels que test_1.

+2

J'essaie de cloner une rangée de boutons radio. Toutefois, comme la modification du nom ne fonctionne pas, l'utilisateur peut uniquement choisir un bouton radio pour les deux lignes au lieu de deux. – jantimon

+0

@prodigtalson +1. J'ai essayé cela en courant dans la même solution et résolu mon problème. Je n'ai utilisé que des entrées de texte et des instructions select, donc les problèmes de radio mentionnés ci-dessus peuvent toujours se produire. – canadiancreed

+0

Informations utiles, mais -1 car cela ne répond pas à la question posée. – RMorrisey

0

La solution simple pour le bouton radio est:

$("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 + " />"); 
    } 
}); 

Cela modifie le outerHTML de l'élément afin que le code HTML de l'élément (bouton radio) soit remplacé. La même solution peut être appliquée pour: find ("input")/find ("checkbox") pour les autres contrôles aussi.

1

essayer (code brut)

$(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); 
}); 

vérifier quand i = 50 puis pause/sortie

mieux: nom d'utilisation en tant que tableau comme name=picture[]

Refernece