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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21260987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 20:29:44  来源:igfitidea点击:

Add a dynamic form to a django formset using javascript in a right way

javascriptpythondjangodjango-formsdjango-templates

提问by xwild

How to add a dynamic form to a django formset in templates without annoying copies of html template output?

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

I have a formset with unknown count of result forms, and I need to add a few forms directly in template by pressing on a button.

我有一个结果表单数量未知的表单集,我需要通过按下按钮直接在模板中添加一些表单。

回答by xwild

This self-answer is based on this postby Nick Lang, but we are going to simplify this way and we don't need to copy/paste whole form html anymore.

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

We have an inline formset which is created in a view like this:

我们有一个内联表单集,它是在这样的视图中创建的:

items_formset = inlineformset_factory(Parent, Item, form=ItemForm, extra=1)
item_forms = items_formset()  

Next, we need to create a template for out formset form, we can do it using empty_formproperty of formset instance, which generates a html form template where every "id" number of a form is replaced by __prefix__string, for example:

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

<!--
{{ item_forms.empty_form }}

{# <!-- or for crispy forms --> {% crispy item_forms.empty_form item_forms.form.helper %} #}
-->  

So, first we need to replace this __prefix__by an id and add a form using this template.
Here is a form template code fragment, which we can use to create new elements:

所以,首先我们需要__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>

Then we need to display main part of the form:

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

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

Finally we need to add some JS (jquery, tested with 1.9.1 and 2.1.0) to add a next formset form. Note we will not use underscore.js, since it's unneeded in this case: just str.replace to replace __prefix__by next "id" number)

最后我们需要添加一些 JS(jquery,用 1.9.1 和 2.1.0 测试过)来添加下一个表单集表单。请注意,我们不会使用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>

That's all, just click on "Add Item" button, and a new formset item will appear.

就是这样,只需单击“添加项目”按钮,就会出现一个新的表单集项目。

Be sure to replace this sample by your app_name/model_name.

请务必用您的 app_name/model_name 替换此示例。