Reputation: 4461
A newbie's question.
There is a django-dynamic-formset.
We can see that the project was last updated 8 month ago: https://github.com/elo80ka/django-dynamic-formset/branches
As far as I can see, this application was well known some time ago. I mean that in the Internet I can find discussions and examples. But all materials are published some of years ago.
And there is a respectable site https://djangopackages.org/grids/g/forms/
There is no mentioning of django-dynamic-formset. This makes me a bit skeptical about the app.
Could you tell me what is the mainstream solution for dynamically adding a form to a Django formset?
By the way Django 1.10.
Upvotes: 0
Views: 2036
Reputation: 1
<script>
var form_num = 0;
$(document).ready(function() {
$("#additemsbutton").on('click',function(event)
{
++form_num;
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_num));
$("#additems").val(form_num + 1);
});
});
</script>
<form action='' method="post">
{% csrf_token %}
<h1>Company details</h1>
{{ company_form.as_p}}
<h1>Project details</h1>
{{ info_formset.management_form }}
<div id="form_set">
{% for form in info_formset %}
{{ form.as_p }}
{% endfor %}
</div>
<div id="empty_form" style="display:none">
{{ info_formset.empty_form.as_p }}
</div>
<input type="hidden" value="1" name="additems" id="additems">
<input type="button" id="additemsbutton" value="Add Project">
<button type="submit" value="Submit" class="btn btn-primary">Submit</button>
</form>
Upvotes: 0
Reputation: 514
I have used the following method. The javascript increments a global variable form_num every time a new form is added to the webpage and in views.py that value is taken from POST data and replaces the form-TOTAL_FORMS value.
I have used empty_form as a template for a new form.
I had to make a copy of POST data because POST itself is immutable.
Template/index.html:
<script>
var form_num = 0;
$(document).ready(function() {
$("#additemsbutton").on('click',function(event)
{
++form_num;
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_num));
$("#additems").val(form_num + 1);
});
});
</script>
<form action='' method="post">
{% csrf_token %}
<h1>Company details</h1>
{{ company_form.as_p}}
<h1>Project details</h1>
{{ info_formset.management_form }}
<div id="form_set">
{% for form in info_formset %}
{{ form.as_p }}
{% endfor %}
</div>
<div id="empty_form" style="display:none">
{{ info_formset.empty_form.as_p }}
</div>
<input type="hidden" value="1" name="additems" id="additems">
<input type="button" id="additemsbutton" value="Add Project">
<button type="submit" value="Submit" class="btn btn-primary">Submit</button>
</form>
Views.py:
def index(request):
extra_forms = 1
InfoFormSet = inlineformset_factory(Company, Info, form=InfoForm, extra=extra_forms)
if request.method == 'POST':
print(request.POST)
formset_dictionary_copy = request.POST.copy()
formset_dictionary_copy['info_set-TOTAL_FORMS'] = int(
formset_dictionary_copy['additems'])
company_form = CompanyForm(formset_dictionary_copy)
if company_form.is_valid():
c = company_form.save()
info_formset = InfoFormSet(formset_dictionary_copy)
if info_formset.is_valid():
formset = info_formset.save(commit=False)
for i in formset:
i.company = c
i.save()
return HttpResponseRedirect(reverse('pform:index'))
Upvotes: 1
Reputation: 3755
You can do it with Ajax, example and excellent explanation in this post. If you're concerned about those packages being maintained, this is the solution I'd suggest using.
Upvotes: 0