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

yzckvree  于 2023-10-17  发布在  jQuery
关注(0)|答案(1)|浏览(111)

我希望能够动态添加django forms在我的formsetAdd按钮。
我试着写不同的东西,但到目前为止,我没有克服获得预期的结果。
我在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部分?

a9wyjsp7

a9wyjsp71#

我正在解决同样的问题,发现这个有用的post
基本上,我们可以使用表单集的empty_form属性,并在每次添加表单时克隆它。虽然formset中的每个表单都有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模板示例

相关问题