使用javascript以正确的方式将动态表单添加到django formset [英] Add a dynamic form to a django formset using javascript in a right way

查看:248
本文介绍了使用javascript以正确的方式将动态表单添加到django formset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在模板中添加动态表单到django formset,而不会使html模板输出的烦恼复制?



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

解决方案

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



我们有一个内置的formset,它是以这样的视图创建的:

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

接下来,我们需要为outformset格式创建一个模板,我们可以使用 empty_form formset实例的属性,它生成一个html表单模板,其中每个id数字的形式i s替换为 __前缀__ 字符串,例如:

 <! -  -  
{{item_forms.empty_form}}

{#<! - 或用于脆性表单 - > {%crispy item_forms.empty_form item_forms.form.helper%}#}
- >

所以,首先我们需要替换这个 __前缀__ 通过id,并使用此模板添加表单。

这是一个表单模板代码片段,可用于创建新元素:

 < script type =text / htmlid =item-template> 
< div id =item -__ prefix __>
{{item_forms.empty_form}}
<! - crispy:{%crispy item_forms.empty_form item_forms.form.helper%} - >
< / div>
< / script>

然后我们需要显示窗体的主要部分:

 < form action =method =post> 
{%csrf_token%}
{{item_forms.management_form}}
< div id =items-form-container>
{item for item_forms%}
< div id =item - {{forloop.counter0}}>
{{item_form.id}}
{{item_form.as_p}}
{#<! - 或用于脆性表单 - > {%crispy item_form%}#}
< / div>
{%endfor%}
< / div>
< a href =#id =add-item-buttonclass =btn btn-info add-item>添加项< / a>
< / form>

最后,我们需要添加一些JS(jquery,使用1.9.1和2.1.0进行测试)添加下一个formset表单。注意,我们不会使用 underscore.js ,因为在这种情况下不需要这样做:只是str.replace替换 __前缀__ 由下一个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(/ __前缀__ / g,计数);
$('div#items-form-container')。append(compiledTmpl);

//更新表单计数
$('#id_item_items -TOTAL_FORMS')。attr('value',count + 1);

//某些动画滚动以查看我们的新表单
$('html,body ').animate({
scrollTop:$(#add-item-button)。position()。top-200
},800);
});
});
< / script>

这就是所有,只需点击添加项按钮,就会出现一个新的formset项。 / p>

请确保用app_name / model_name替换此示例。


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

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.

解决方案

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

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_form property of formset instance, which generates a html form template where every "id" number of a form is replaced by __prefix__ string, for example:

<!--
{{ 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:

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

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

这篇关于使用javascript以正确的方式将动态表单添加到django formset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆