Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bradmontgomery/596146 to your computer and use it in GitHub Desktop.
Save bradmontgomery/596146 to your computer and use it in GitHub Desktop.
Use jQuery to add forms to a django formset
/*
Given the following HTML (a form generated by a django formset), I want to be able to
clone the form elements inside the div#book-form-container, omitting any values
<form action="/books/add/" method="post">
<div id="book-form-wrapper"> <input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS" /> <input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS" />
<div class="book-form-container">
<input type="hidden" name="form-0-id" id="id_form-0-id" />
<ul class="bookformset">
<li class="required">
<label for="id_form-0-title">Title</label>
<input id="id_form-0-title" type="text" name="form-0-title" maxlength="255" />
</li>
<li class="required">
<label for="id_form-0-author">Author</label>
<input id="id_form-0-author" type="text" name="form-0-author" maxlength="255" />
</li>
</ul>
</div>
</div>
<p><a href="#" id="add_book">Add Book</a></p>
<p><input type="submit" name="submit" id="submit" value="Submit"/></p>
</form>
*/
$(document).ready(function() {
// Watch for the 'add another book' click
$('#add_book').click(function(e) {
e.preventDefault();
// create a clone of the existing form elements, but with blank fields.
$('div.book-form-container:last').clone().each(function(i) {
$(this).find('input,select').each(function(i) {
// Remove any existing values
$(this).val('');
// update the id attributes, incrementing the form number, e.g.: "id_form-1-field_name"
parts = $(this).attr('id').split('-', 3);
num = parseInt(parts[1]) + 1;
$(this).attr('id', parts[0] + '-' +num + '-' +parts[2]);
// Update the name attribute, e.g.: form-1-field_name
parts = $(this).attr('name').split('-', 3);
num = parseInt(parts[1] + 1);
$(this).attr('name', parts[0] + '-' +num + '-' +parts[2]);
});
// Update the "for" attribute for all labels
$(this).find('label').each(function(i) {
parts = $(this).attr('for').split('-', 3);
num = parseInt(parts[1]) + 1;
$(this).attr('for', parts[0] + '-' +num + '-' +parts[2]);
});
}).appendTo('div#book-form-wrapper');
// Increment the TOTAL_FORMS
$('#id_form-TOTAL_FORMS').val(parseInt($('#id_form-TOTAL_FORMS').val()) + 1);
});
});
@chandu-thoughtwin
Copy link

If I Handel more than two formset like fromset1, fromset2 on same view on single submit button is this possible ?

@typonaut
Copy link

There is a little bug in this script at line 52

num = parseInt(parts[1] + 1);

should be (as similar lines):

num = parseInt(parts[1]) + 1;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment