views:

1307

answers:

4

Those snippes of code that you will check works fine for FF, Chrome, Safari, but seems to be a problem with IE when running jQuery clone function:

My template:

<form method="post" action="/post/add/">
{{ form.management_form }}
    <div class='table'>
      <table class='no_error'>
        <input id="id_mypost_set-0-title" type="text" name="mypost_set-0-title" />
        <input id="id_mypost_set-0-content" type="text" name="mypost_set-0-content" />
      </table>
    </div>
    <input type="button" value="Add Other" id="add_more">
    <script>
        $('#add_more').click(function() {
            cloneMore('div.table:last', 'mypost_set');
         });
    </script>
</form>

In a javascript file:

function cloneMore(selector, type) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + type + '-TOTAL_FORMS').val();
    newElement.find(':input').each(function() {
        var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
        var id = 'id_' + name;
        $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
    });
    newElement.find('label').each(function() {
        var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
        $(this).attr('for', newFor);
    });
    total++;
    $('#id_' + type + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
 }

The problem is with the selector: "A clone of the original html piece of code works OK", but, A clone from cloned piece of code marks the selector as "undefined", in other words, the second time that I clone the table the selector doesnt work anymore for those cloned items.

Problem only for IE.

What im missing? Any hint is apreciated :)

A: 

perhaps you can use this clone function :

/*
 * Clone method
 * Prevents reference problem
 */
clone: function( obj ){
  if(obj == null || typeof(obj) != 'object')
    return obj;
  var temp = new obj.constructor();
  for(var key in obj)
    temp[key] = clone(obj[key]);
  return temp;
}
FrankBr
thanks, but, how do I use this function?, having count my context?
panchicore
+3  A: 

This is a known jQuery bug, though they claim it is fixed.
One option here is to use .html(), and clone them manually. This will not clone events and saved .data, which may be an issue for you. .live can help if you have events here.

If the only thing you need is to change the names and id, a better option is to use a regular expression (this clones the events from the first element, mind you):

var name = $(this).attr('name').replace(/-\d+-/,'-' + total + '-');

this will search for -number-, and replace it, so it finds the last number on all browsers, or -0- on IE.

Here's a working demo with alerts: http://jsbin.com/evapu

As a side note - your code is a little messy. jQuery code should be inside $(document).ready (the click), you have a table with no body (no <tr>,<td> - the inputs are thrown out), and the code has some duplications.
Although it didn't help in this case, invalid DOM and not using the ready event can cause problems.

Kobi
Hi Kobi, first than all: thanks 4 understandme, im taking all your advices (notes) and fixed messy code, and applying http://jsbin.com/evapu to my code it results this error: $(selector).after(newElement); Node cannot be inserted at the specified point in the hierarchy" code: "3, the element is cloned but when JS run this line, return this error and delete the cloned items.
panchicore
OMG, if I remove the $(selector).after(newElement); line, it now works fine in IE, why Kobi?
panchicore
you are the best Kobi :)
panchicore
Happy to help. The version I posted is a little different, but I guess you figured it out. Thanks!
Kobi
A: 

You code works perfectly on all browsers as stated before Still if you could replace:

var newElement = $(selector).clone(true);

with:

var newElement = $($(selector).html());

and see if it helps.

Also, re-attach the event handler, like so.

newElement.bind(EVENT, function() {});

Or use the appropriate helper.

partoa
doesnt help, it does not attach the event handler :(
panchicore
Yeah, the even handler, you have to re-attach those :)See if this new edit helps
partoa
A: 

you're missing a hidden input with id 'id_' + type + '-TOTAL_FORMS' - you're getting your total from this object and using it to modify the name and id of cloned objects.

I tried your code with this:

<input type="hidden" id="id_mypost_set-TOTAL_FORMS" value="1"/>

added right after

<form method="post" action="/post/add/">

and it works correctly, all new inputs have correct ids. does this really work in FF ??

jab11
im not missing it, it comes here: {{ form.management_form }}
panchicore