Добавить формы в formset с Django и JS - PullRequest
0 голосов
/ 08 ноября 2018

Я хотел бы иметь возможность динамически добавлять django forms в мой formset с помощью кнопки Add.

Я пытался писать разные вещи, но до сих пор не могу достичь ожидаемого результата.

У меня есть formset, определенный в моем файле forms.py :

AnimalFormSet = inlineformset_factory(Elevage, Animal, form=AnimalForm, extra=1)

Затем я создал в своем файле views.py эту функцию:

class ElevageCreateView(CreateView):

    model = Elevage
    template_name = 'elevage_form.html'

    def get_context_data(self, **kwargs):
        context = super(ElevageCreateView, self).get_context_data(**kwargs)
        context['AnimalFormSet'] = AnimalFormSet(self.request.POST or None, self.request.FILES or None)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        animal = context['AnimalFormSet']
        if animal.is_valid():
            self.object = form.save()
            animal.instance = self.object
            animal.save()
        return super(ElevageCreateView, self).form_valid(form)

    def get_success_url(self):
        return reverse('animal-list')

Наконец, я пытаюсь написать свой файл шаблона :

<fieldset>
    <legend class="title"><span class="name">{% trans 'Animal form' %}</span></legend>
    {{ AnimalFormSet.management_form }}
      {% for form in AnimalFormSet.forms %}
        <div class='table'>
           <table class='no_error'>
             {{ form.as_table }}
           </table>
        </div>
      {% endfor %}
    <input type="button" class="btn btn-default" value="Add More" id="add_more">
    <script>
      $('#add_more').click(function () {
        cloneMore('div.table:last', 'service');
      });
    </script>
  </fieldset>

И у меня есть функция JavaScript :

 <script>
  function cloneMore(selector, type) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + type + '-TOTAL_FORMS').val();
    newElement.find(':input').each(function() {
        var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
        var id = 'id_' + name;
        $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
    });
    newElement.find('label').each(function() {
        var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
        $(this).attr('for', newFor);
    });
    total++;
    $('#id_' + type + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
}
  </script>

Я потратил много времени, чтобы получить ожидаемый результат, но я не побеждаю его получить. Так что мне нужна ваша помощь, если вы могли бы помочь мне.

Я не хочу использовать другую библиотеку, но я принимаю JS, AJAX, JQuery или django ответы!

Заранее спасибо

РЕДАКТИРОВАТЬ:

Проблема:

Отображает первую форму, но когда я хочу добавить вторую, нажав Add button, она не создает вторую.

Итак, я полагаю, что моя часть Django хороша, но не часть JS?

1 Ответ

0 голосов
/ 17 июня 2019

Я занимался той же проблемой и нашел это полезным post .

По сути, мы можем использовать атрибут empty_form набора форм и клонировать его каждый раз, когда мы хотим добавить форму. В то время как у каждой формы в наборе форм есть префикс form-<index>, атрибут empty_form имеет form-__prefix__, который мы должны заменить следующим индексом формы при клонировании.

И не забывайте увеличивать значение form-TOTAL_FORMS скрытого ввода, чтобы Django знал, сколько форм в представленном наборе форм.

formset_wrapper и emptyform_wrapper предназначены для более простого внедрения элемента jQuery.

<fieldset>
  <legend class="title"><span class="name">{% trans 'Animal form' %}</span></legend>
  {{ AnimalFormSet.management_form }}
  <div id="formset_wrapper">
    {% for form in AnimalFormSet.forms %}
    <div class='table'>
      <table class='no_error'>
        {{ form.as_table }}
      </table>
    </div>
    {% endfor %}
  </div>
  <div id="emptyform_wrapper" style="display: none">
    <div class='table'>
      <table class='no_error'>
        {{ AnimalFormSet.empty_form.as_table }}
      </table>
    </div>
  </div>

  <input type="button" class="btn btn-default" value="Add More" id="add_more">
</fieldset>
<script>
  $('#add_more').click(function () {
    let total_form = $('#id_form-TOTAL_FORMS');
    let form_idx = total_form.val();

    $('#formset_wrapper').append($('#emptyform_wrapper').html().replace(/__prefix__/g, form_idx));
    total_form.val(parseInt(form_idx)+1);
  });
</script>

Попробуйте этот фрагмент для приведенного примера шаблона Django выше

...