Django smart selects не работает с клонированием JS
Я пытаюсь создать страницу с возможностью добавления любого количества форм-копий. Я использую django-smart-selects, чтобы сделать поля моей формы цепочкой. Это работает хорошо, если у меня только 1 форма на странице.
Затем я использую javascript, чтобы сделать функцию для клонирования экземпляра формы по нажатию кнопки и добавить идентификаторы новых форм к этим клонам.
Проблема в том, что когда я нажимаю кнопку "+", я получаю новую клонированную форму на странице, но цепной выбор больше не работает (работает только первый), и кажется, что этот клон копирует все мои выборы из первой формы и запоминает это состояние.
В терминале я вижу такой ответ каждый раз, когда я выбираю любой выбор в цепочке полей:
[31/Oct/2022 16:42:27] "GET /chaining/filter/cash_table/LevelOne/flowtype/cash_table/CashFlowPattern/level_one/1/ HTTP/1.1" 200 115
[31/Oct/2022 16:42:29] "GET /chaining/filter/cash_table/LevelOne/flowtype/cash_table/CashFlowPattern/level_one/2/ HTTP/1.1" 200 105
Но в клонированных формах этого не происходит.
Мой набор форм:
forms.py
from django import forms
from .models import CashFlowPattern
from django.forms import modelformset_factory
class CashFlowForm(forms.ModelForm):
class Meta:
model = CashFlowPattern
fields = '__all__'
CashFowFormSet = modelformset_factory(
CashFlowPattern,
fields=(
'flow_type',
'level_one',
'level_two',
'eom',
'amount',
'comment'
),
extra=1
)
views.py
class FormAddView(TemplateView):
template_name = 'cash_table/index.html'
def get(self, *args, **kwargs):
formset = CashFowFormSet(queryset=CashFlowPattern.objects.none())
return self.render_to_response({'formset': formset})
def post(self, *args, **kwargs):
end_of_month = (datetime.datetime.now() + relativedelta(day=31)).strftime('%Y-%m-%d')
formset = CashFowFormSet(data=self.request.POST)
if formset.is_valid():
forms = formset.save(commit=False)
for form in forms:
form.eom = end_of_month
form.user = self.request.user
form.save()
# return redirect(reverse_lazy("bird_list"))
return self.render_to_response({'formset': formset})
template:
<form id="form-container" method="POST">
{% csrf_token %}
{{ formset.management_form }}
<div class="empty-form">
{% for form in formset %}
{{ form.media.js }}
<p>{{ form }}</p>
{% endfor %}
</div>
<button id="add-form" type="button">+</button>
<button type="submit" class="btn btn-primary">Отправить</button>
</form>
<script>
let emptyForm = document.querySelectorAll(".empty-form")
let container = document.querySelector("#form-container")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_form-TOTAL_FORMS")
let formNum = emptyForm.length-1
addButton.addEventListener('click', addForm)
function addForm(e) {
e.preventDefault()
let newForm = emptyForm[0].cloneNode(true) //Clone the form
let formRegex = RegExp(`form-(\\d){1}-`,'g') //Regex to find all instances of the form number
formNum++ //Increment the form number
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`) //Update the new form to have the correct form number
container.insertBefore(newForm, addButton) //Insert the new form at the end of the list of forms
totalForms.setAttribute('value', `${formNum+1}`) //Increment the number of total forms in the management form
}
</script>