【问题标题】:Dynamically Add Form to Django Formset将表单动态添加到 Django Formset
【发布时间】:2019-07-26 22:30:30
【问题描述】:

我想动态地将一个表单添加到我的Django 表单集。但是,单击按钮时没有任何反应。我正在使用表单模型,但我在模板中定义了大多数元素。我知道这不是正确的做法,但这是我最初创建表单的方式,我没有时间迁移到完整的表单模型。但是,这会导致我的问题吗?我以前从未使用过表单集,因此将不胜感激任何提示!我使用了 Dave 的解决方案 here,但我不确定为什么我的实现没有相应地转换。

模板.html

<div class="container">
    <div id="form_set">
        <form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="presalesForm"method="post" name="presalesForm">
            <div class="field">
                <label class="label is-large">High Level Task List</label>
            </div>
            {% csrf_token %}

            {{ presales_formset.management_form }}

            {% for presales_form in presales_formset %}
                <div class="section">
                    <div class="field">
                        <label class="label">Opportunity</label>
                        <div class="select">
                            <select id="select_opportunity" name="select_opportunity">
                                <option value="">Opportunity</option>
                                {% for opportunity in my_opportunities %}
                                    <option id="selected_opportunity" name="selected_opportunity" value="{{ opportunity.name }}">{{ opportunity.name }}</option>
                                {% endfor %}
                            </select>
                        </div>
                    </div>
                    <label class="label">Task Description:</label>
                    <div class="field">
                        <div class="control">
                            <input class="input" id="task_description" name="task_description" placeholder="Task Description">
                        </div>
                    </div>
                    <label class="label">Hours</label>
                    <div class="field">
                        <div class="control">
                            <input class="input" id="hours" name="hours" placeholder="Hours">
                        </div>
                    </div>
                    <label class="label">Engineer Level:</label>
                    <div class="field">
                        <div class="select">
                            <select id="select_engineer_level" name="select_engineer_level">
                                <option value="">Engineer Level</option>
                                <option value="PM">PM</option>
                                <option value="Solutions Technician">Solutions Technician</option>
                                <option value="Solutions Engineer">Solutions Engineer</option>
                                <option value="Senior Solutions Engineer">Senior Solutions Engineer</option>
                                <option value="Solutions Architect">Solutions Architect</option>
                            </select>
                        </div>
                    </div>
                </div>
            {% endfor %}
        </form>
    </div>
    <div id="empty_form" style="display: none;">
        <form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="emptyPresalesForm" method="post" name="presalesForm">
            {% csrf_token %}

            {{ presales_formset.empty_form }}

            <div class="section">
                <div class="field">
                    <label class="label">Opportunity</label>
                    <div class="select">
                        <select id="empty_select_opportunity" name="select_opportunity">
                            <option value="">Opportunity</option>
                            {% for opportunity in my_opportunities %}
                                <option id="empty_selected_opportunity" name="selected_opportunity" value="{{ opportunity.name }}">{{ opportunity.name }}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>
                <label class="label">Task Description:</label>
                <div class="field">
                    <div class="control">
                        <input class="input" id="empty_task_description" name="task_description" placeholder="Task Description">
                    </div>
                </div>
                <label class="label">Hours</label>
                <div class="field">
                    <div class="control">
                        <input class="input" id="empty_hours" name="hours" placeholder="Hours">
                    </div>
                </div>
                <label class="label">Engineer Level:</label>
                <div class="field">
                    <div class="select">
                        <select id="empty_select_engineer_level" name="select_engineer_level">
                            <option value="">Engineer Level</option>
                            <option value="PM">PM</option>
                            <option value="Solutions Technician">Solutions Technician</option>
                            <option value="Solutions Engineer">Solutions Engineer</option>
                            <option value="Senior Solutions Engineer">Senior Solutions Engineer</option>
                            <option value="Solutions Architect">Solutions Architect</option>
                        </select>
                    </div>
                </div>
            </div>
        </form>
    </div>

    <div class="field is-inline-flex">
        <div class="control">
            <button class="button is-success" id="add_more" type="button">+</button>
        </div>
    </div>

script.js

<script>
    $('#add_more').click(function () {
        var form_idx = $('#presalesForm-TOTAL_FORMS').val();
        $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
        $('#presalesForm-TOTAL_FORMS').val(parseInt(form_idx) + 1);
    });
</script>

forms.py

# special field names
TOTAL_FORM_COUNT = 'TOTAL_FORMS'
INITIAL_FORM_COUNT = 'INITIAL_FORMS'
MIN_NUM_FORM_COUNT = 'MIN_NUM_FORMS'
MAX_NUM_FORM_COUNT = 'MAX_NUM_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'

# default minimum number of forms in a formset
DEFAULT_MIN_NUM = 0

# default maximum number of forms in a formset, to prevent memory exhaustion
DEFAULT_MAX_NUM = 1000


class PresalesForm(forms.Form):
    class Meta:
        model = Presales
        fields = ('selected_opportunity', 'task_description', 'hours', 'selected_engineer_level', 'total_price')

【问题讨论】:

  • 我可能遗漏了一些东西,但您的模板中没有 ID 为 presalesForm-TOTAL_FORMS 的元素。
  • @BoobyTrap 抱歉,我添加了我的表单模型

标签: python html django forms


【解决方案1】:

看到这似乎是注入现有页面的 html 代码,并且 JavaScript 似乎没有与它一起注入,我怀疑问题在于 JavaScript 代码没有找到该按钮。

试试下面的代码:

<script>
    $(document).ready(function () {
        $('body').on('click', '#add_more', function () {
            var form_idx = $('#presalesForm-TOTAL_FORMS').val();
            $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
            $('#presalesForm-TOTAL_FORMS').val(parseInt(form_idx) + 1);
        });
    });
</script>

这里发生的事情是我将一个点击监听器附加到正文标签(我认为它是容器 div 的父级),并添加一个选择器,该选择器将是触发此事件的选择器。

.on 可用于加载脚本时不存在的动态添加元素,而不是 .click

For further reading regarding .on function.
Differences between .on('click') and .click().

【讨论】:

  • 你可以尝试在on 监听器中添加一个consoloe.log('test print'); 并查看它是否被点击触发?
  • 是的,它不会在点击时触发
  • 检查页面并检查脚本代码是否在页面上。当按钮存在时不触发它是没有意义的。
  • 我看到此错误ReferenceError: $ is not defined 脚本在页面上,但显示为灰色。当我查看脚本时,它说没有选择任何元素。
  • 它现在可以工作了,我在加载 jQuery 之前加载了我的脚本。谢谢!
猜你喜欢
  • 2019-11-27
  • 2018-09-21
  • 2014-02-11
  • 2020-07-22
  • 2014-03-24
  • 2015-02-14
  • 2012-08-17
  • 2020-01-22
  • 2016-07-17
相关资源
最近更新 更多