I designed a inline formset as follows:
class EventForm(ModelForm):
class Meta:
model = Event
exclude = ['created']
class GalleryForm(ModelForm):
class Meta:
model= Gallery
exclude = ['pub_date']
GalleryFormSet = inlineformset_factory(Event, Gallery, extra=0, min_num=1, fields=('title','image' ))
It worked correctly when used 'extra = some number' and saved gallery form data correctly. But when I used javascript handler to add additional gallery form below the main Event form, it creates two Gallery form instead of 1 and data and photo not saved from the newly added form.
Here is my event handler:
<script type="text/html" id="gallery-template">
<div id="gallery-__prefix__">
{{ formset.empty_form }}
</div>
</script>
<script>
$(function() {
$('.add-photo').click(function(ev){
ev.preventDefault();
var count = parseInt($('#id_gallery_set-TOTAL_FORMS').attr('value'), 10);
var tmplMarkup = $('#gallery-template').html();
var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count)
console.log(compiledTmpl);
$('div.gallery').append(compiledTmpl);
$('#id_gallery_set-TOTAL_FORMS').attr('value', count);
});
});
</script>
My formset template:
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{{ formset.management_form }}
{% csrf_token %}
<legend>Events</legend>
<div class="author">
{{ form.as_p}}
</div>
<legend>
<div class="pull-right"><a href="#" class="btn btn-inverse add-photo"><i class="icon-plus icon-white"></i> Add Photo</a></div>
Gallery
</legend>
<div class="gallery form-inline">
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
</div>
<div class="form-group">
<div class="col-sm-offset-6 col-sm-6">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
For your information, when I edit this formset then data and image saved correctly.
Can anyone indicates the error of my event handler?
I think scripts has error,
$('#id_gallery_set-TOTAL_FORMS').attr('value', count);
line should be:
$('#id_gallery_set-TOTAL_FORMS').attr('value', count + 1);
Here is workable scripts and template for this problem:
$(function() {
$('.add-photo').click(function(ev){
ev.preventDefault();
var count = parseInt($('#id_gallery_set-TOTAL_FORMS').attr('value'), 10);
var tmplMarkup = $('#gallery-template').html();
var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count)
console.log(compiledTmpl);
$('div.gallery').append(compiledTmpl);
$('#id_gallery_set-TOTAL_FORMS').attr('value', count + 1);
});
});
Templates:
<form action="." method="post" enctype="multipart/form-data">
{{ formset.management_form }}
{% csrf_token %}
<legend>Event</legend>
<div class="event">
{{ form}}
</div>
<legend>
<div class="pull-right"><a href="#" class="btn btn-inverse add-photo"><i class="icon-plus icon-white"></i> Add Photo</a></div>
Photo Gallery
</legend>
<div class="gallery form-inline">
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
Hope this help to solve related problems.