【问题标题】:Add a dynamic form to a django formset using javascript in a right way以正确的方式使用 javascript 将动态表单添加到 django formset
【发布时间】:2014-02-11 05:10:42
【问题描述】:

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

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

【问题讨论】:

    标签: javascript python django django-forms django-templates


    【解决方案1】:

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

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

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

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

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

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

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

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

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

    最后我们需要添加一些 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>
    

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

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

    【讨论】:

    • 如果我有一个包含两个字段的现有表单,我需要添加额外的字段怎么办?
    • user1919:在这种情况下,您必须通过在 python 中发布数据来重新创建表单结构,您可以在客户端以 __init__() 形式将字段添加到“self.fields”字典中创建具有不同名称的字段。我使用 knockout.js 创建字段架构,您可以查看此示例 knockoutjs.com/examples/contactsEditor.html
    猜你喜欢
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2018-09-21
    • 2023-01-31
    • 2020-07-22
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多