使用Django和JS在formset中添加表单

时间:2018-11-08 10:13:51

标签: javascript jquery ajax django formset

我希望能够通过django forms按钮在formset中动态添加Add

我试图写出不同的东西,但我并没有克服,直到现在为止仍能获得预期的结果。

我在 forms.py 文件中定义了一个formset

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>

我花了很多时间来获得预期的结果,但是我并没有克服。所以,如果您能帮助我,我需要您的帮助。

我不想使用其他库,但我接受JSAJAXJQuerydjango的答案!

先谢谢您

编辑:

问题是:

它显示第一个表单,但是当我想通过单击Add button添加第二个表单时,它不会创建第二个表单。

所以我认为我的Django部分不错,但JS部分却没有?

1 个答案:

答案 0 :(得分:1)

我正在解决相同的问题,发现这很有帮助post

基本上,我们可以使用表单集的empty_form属性,并在每次添加表单时对其进行克隆。表单集中的每个表单都有form-<index>前缀,而empty_form属性具有form-__prefix__,我们在克隆表单时应将其替换为表单的下一个索引。

别忘了增加form-TOTAL_FORMS隐藏输入的值,以便Django知道提交的表单集中有多少个表单。

formset_wrapperemptyform_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>

请尝试使用snippet作为上面的Django模板的渲染示例