使用javascript以正确的方式将动态表单添加到django formset

xwi*_*ild 11 javascript python django django-templates django-forms

如何在模板中添加动态表单到django formset而不需要烦人的html模板输出副本?

我有一个包含未知结果表单的formset,我需要通过按下按钮直接在模板中添加一些表单.

xwi*_*ild 38

这个自我回答是基于Nick Lang的这篇文章,但我们将简化这种方式,我们不再需要复制/粘贴整个表单html了.

我们有一个内联formset,它在这样的视图中创建:

items_formset = inlineformset_factory(Parent, Item, form=ItemForm, extra=1)
item_forms = items_formset()  
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要为formset表单创建一个模板,我们可以使用empty_formformset实例的属性来创建它,它生成一个html表单模板,其中表单的每个"id"号都被__prefix__字符串替换,例如:

<!--
{{ item_forms.empty_form }}

{# <!-- or for crispy forms --> {% crispy item_forms.empty_form item_forms.form.helper %} #}
-->  
Run Code Online (Sandbox Code Playgroud)

因此,首先我们需要用__prefix__id 替换它,并使用此模板添加表单.
这是一个表单模板代码片段,我们可以用它来创建新元素:

<script type="text/html" id="item-template">
<div id="item-__prefix__">
    {{ item_forms.empty_form }}
    <!-- crispy: {% crispy item_forms.empty_form item_forms.form.helper %} -->
</div>
</script>
Run Code Online (Sandbox Code Playgroud)

然后我们需要显示表单的主要部分:

<form action="" method="post">
{% csrf_token %}
{{ item_forms.management_form }}
<div id="items-form-container">
    {% for item_form in item_forms %}
        <div id="item-{{ forloop.counter0 }}">
            {{ item_form.id }}
            {{ item_form.as_p }}
            {# <!-- or for crispy forms --> {% crispy item_form %} #}
        </div>
    {% endfor %}
</div>
<a href="#" id="add-item-button" class="btn btn-info add-item">Add Item</a>
</form>
Run Code Online (Sandbox Code Playgroud)

最后,我们需要添加一些JS(jquery,用1.9.1和2.1.0测试)来添加下一个formset表单.注意我们不会使用underscore.js,因为在这种情况下它是不需要的:只需str.replace替换__prefix__为下一个"id"数字)

<script>
$(document).ready(function() {
    $('.add-item').click(function(ev) {
        ev.preventDefault();
        var count = $('#items-form-container').children().length;
        var tmplMarkup = $('#item-template').html();
        var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count);
        $('div#items-form-container').append(compiledTmpl);

        // update form count
        $('#id_item_items-TOTAL_FORMS').attr('value', count+1);

        // some animate to scroll to view our new form
        $('html, body').animate({
                scrollTop: $("#add-item-button").position().top-200
            }, 800);
    });
});
</script>
Run Code Online (Sandbox Code Playgroud)

这就是全部,只需单击"添加项目"按钮,就会出现一个新的表单集项.

请务必使用app_name/model_name替换此示例.

  • 很好的答案,展示它如何端到端工作. (3认同)