In the Django admin interface there is the nice ability to dynamically add new items to foreign key fields and i want to make a similar one using bootstrap modal for popup window and Ajax for form submission and validation.
This is my use case :
This is the Main form for adding Item. Item have a ref and a category.

And this is the second form for adding a new category.

I have no problem with showing the modal and submission the form to add new category. Instead the problem is with the form validation (in case the user submit an empty form), and with refreshing the select content to add the new added category.
This is my code:
forms.py
class ItemForm(forms.ModelForm):
ref = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}),max_length=255)
category = forms.ModelChoiceField(queryset=ItemCategory.objects.all(), empty_label="(choose from the list)")
class ItemCategoryForm(forms.ModelForm):
category = forms.CharField(
max_length=255,
required=True,
help_text='Add a new category')
views.py
def add(request):
if request.method == 'POST':
form = ItemForm(request.POST)
if form.is_valid():
item= Item()
item.ref = form.cleaned_data.get('ref')
item.save()
return redirect('/item_list/')
else:
form = ItemForm()
form1 = ItemCategoryForm()
return render(request, 'item/add.html', {'form': form, 'form1':form1})
def add_category(request):
if request.method == 'POST':
form1 = ItemCategoryForm(request.POST)
if form1.is_valid():
vulnCategory = ItemCategory()
ItemCategory.category = form1.cleaned_data.get('category')
ItemCategory.save()
if request.is_ajax():
#TODO: What Should I redirect
else:
#TODO: What Should I redirect
else:
#TODO: What Sould I do to return errors without reloding the page and to refresh the list of categories
urls.py
url(r'^add/$', 'add', name='add'),
url(r'^add_category/$', 'add_category', name='add_category'),
And I have also added this jQuery function to load the result
$(".add").click(function () {
$.ajax({
url: '/items/add_category/',
data: $("form").serialize(),
cache: false,
type: 'post',
beforeSend: function () {
$("#add_category .modal-body").html("<div style='text-align: center; padding-top: 1em'><img src='/static/img/loading.gif'></div>");
},
success: function (data) {
$("#add_category .modal-body").html(data);
}
});
});
PS: I know that it may be duplicated, but non of the answers get me to the point.