1

In my project I use django inline formsets. I got the jquery to clone the formsets but unfortunately the cloned forms have the same names and ids and so data entered in the last one overwrites the data from the first form. What could I be doing wrong?

Here is the script:

<script type="text/javascript">>
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);
}

</script>
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Wedava
  • 1,211
  • 2
  • 16
  • 30
  • Have you tried putting in some debugging statements? eg using `console.log()` to show the values of `total` and `name`/`id` each time through the loop. – Daniel Roseman May 30 '12 at 10:08
  • lemme try that and post what I get. – Wedava May 30 '12 at 10:30
  • when I add console.log(total), the value returned in 'undefined'. Then the cloned elements remain with the same ids and names as the previous element. – Wedava May 30 '12 at 10:39

2 Answers2

1

Each form in a django formset is supplied with unique name attribute which acts as a sort of id to django, which means if you clone a first form in a formset it means you will also clone its ids and hence the clone it will override the first form.

You can use/clone empty_form supplied by Baseformset, {{form.empty_form}}, supply it with appropriate names and update the -TOTAL_FORMS

machaku
  • 1,176
  • 8
  • 7
  • `cloneMore.js` is actually designed to increment the names and ids of the formset forms as well as the `TOTAL_FORMS` in the management form. However, it would be worth inspecting the new forms to make sure that the values are actually changing. – j_syk May 30 '12 at 16:28
1

I use the CloneMore.js script for the same purpose (my version is modifed at this point). I don't know if this is the case for you, but if you have any field that is being modified by javascript, you need to reinitialize that field. For example, uniform.js selectors, datepickers, or any autocomplete field may need to be reset.

Here is a snippet of my code for dealing with some of these issues when I hit the clone button. Also notice that these are within live()

// #add_more is my button to add a formset
$('#add_more').live('click',function() { 
    cloneMore('div.line_item:last', 'lineitem');
    $(".line_item:last").find('.hasDatepicker').each(function() {
        // remove then initialize datepicker
        $(this).removeClass("hasDatepicker").datepicker( {dateFormat:'mm/dd/yy'} );
    });
    $(".line_item:last").find('.autocomplete_field').each(function() {
        // remove then initialize autocomplete
        $(this).autocomplete('destroy');
        // enable_autocomplete is a custom function, but it's basically just 
        // $(this).autocomplete({ options... })
        enable_autocomplete($(this), cust_part_url);
    });
});

Edit: I think this SO Answer is the origin of the cloneMore script

Community
  • 1
  • 1
j_syk
  • 6,511
  • 2
  • 39
  • 56