Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is how I do it, using <a href="http://www.jquery.com" rel="noreferrer">jQuery</a>:</p> <p>My template:</p> <pre><code>&lt;h3&gt;My Services&lt;/h3&gt; {{ serviceFormset.management_form }} {% for form in serviceFormset.forms %} &lt;div class='table'&gt; &lt;table class='no_error'&gt; {{ form.as_table }} &lt;/table&gt; &lt;/div&gt; {% endfor %} &lt;input type="button" value="Add More" id="add_more"&gt; &lt;script&gt; $('#add_more').click(function() { cloneMore('div.table:last', 'service'); }); &lt;/script&gt; </code></pre> <p>In a javascript file:</p> <pre><code>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); } </code></pre> <p>What it does:</p> <p><code>cloneMore</code> accepts <code>selector</code> as the first argument, and the <code>type</code> of formset as the 2nd one. What the <code>selector</code> should do is pass it what it should duplicate. In this case, I pass it <code>div.table:last</code> so that jQuery looks for the last table with a class of <code>table</code>. The <code>:last</code> part of it is important because the <code>selector</code> is also used to determine what the new form will be inserted after. More than likely you'd want it at the end of the rest of the forms. The <code>type</code> argument is so that we can update the <code>management_form</code> field, notably <code>TOTAL_FORMS</code>, as well as the actual form fields. If you have a formset full of, say, <code>Client</code> models, the management fields will have IDs of <code>id_clients-TOTAL_FORMS</code> and <code>id_clients-INITIAL_FORMS</code>, while the form fields will be in a format of <code>id_clients-N-fieldname</code> with <code>N</code> being the form number, starting with <code>0</code>. So with the <code>type</code> argument the <code>cloneMore</code> function looks at how many forms there currently are, and goes through every input and label inside the new form replacing all the field names/ids from something like <code>id_clients-(N)-name</code> to <code>id_clients-(N+1)-name</code> and so on. After it is finished, it updates the <code>TOTAL_FORMS</code> field to reflect the new form and adds it to the end of the set.</p> <p>This function is particularly helpful to me because the way it is setup it allows me to use it throughout the app when I want to provide more forms in a formset, and doesn't make me need to have a hidden "template" form to duplicate as long as I pass it the formset name and the format in which the forms are laid out. Hope it helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload