1👍
This is how I did it
JS:
let container = document.querySelector("#form-container")
let birdForm = document.querySelectorAll(".ingredient-form")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_recipeingredients_set-TOTAL_FORMS")
let formNum = birdForm.length-1
function addForm(e){
let newForm = birdForm[0].cloneNode(true)
let formRegex = RegExp(`recipeingredients_set-(\\d){1}-`,'g')
formNum++
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `recipeingredients_set-${formNum}-`)
let deleteButton = document.createElement('input')
deleteButton.type = "button"
deleteButton.value = "Delete"
deleteButton.className = "delete-btn"
newForm.appendChild(deleteButton)
deleteButton.addEventListener('click', deleteForm)
container.insertBefore(newForm, addButton)
totalForms.setAttribute('value', `${formNum+1}`)
}
function deleteForm(e){
formNum--
e.target.parentNode.remove()
totalForms.setAttribute('value', `${formNum+1}`)
}
Python:
class RecipeCreateView(LoginRequiredMixin, CreateView):
template_name = 'recipes/create.html'
form_class = RecipeModelForm
queryset = Recipe.objects.all()
success_url = reverse_lazy('recipes:main-recipe-view')
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
ingredient_form = IngredientFormSet()
for n in ingredient_form:
n.fields['unit'].queryset = FoodWeight.objects.none()
return self.render_to_response(self.get_context_data(form=form,
ingredient_form=ingredient_form))
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
ingredient_form = IngredientFormSet(self.request.POST)
if form.is_valid() and ingredient_form.is_valid():
return self.form_valid(form, ingredient_form)
else:
return self.form_invalid(form, ingredient_form)
def form_valid(self, form, ingredient_form):
self.object = form.save(commit=False)
self.object.author = self.request.user.profile
self.object.save()
form.save_m2m()
if self.object.published:
create_action(self.request.user, 'Added new recipe.', self.object)
ingredient_form.instance = self.object
ingredient_form.save()
return HttpResponseRedirect(self.get_success_url())
Template:
<form id="form-container" data-unit-url={% url 'recipes:load_weights' %} method='POST' enctype="multipart/form-data">
{% csrf_token %}
{{ ingredient_form.management_form }}
{{ form.as_p }}
{% for form in ingredient_form %}
<div class="ingredient-form">
{{form}}
</div>
{% endfor %}
<button id="add-form" type="button">Add another ingredient</button>
<input type="submit" value="Post recipe">
</form>
Source:stackexchange.com