问题描述
我想动态地将新表单添加到Django表单集中,以便当用户单击添加"按钮时,按钮,它将运行JavaScript,该JavaScript会将新表单(属于表单集的一部分)添加到页面.
I want to dynamically add new forms to a Django formset, so that when the user clicks an "add" button it runs JavaScript that adds a new form (which is part of the formset) to the page.
推荐答案
这就是我使用 jQuery :
我的模板:
<h3>My Services</h3>
{{ serviceFormset.management_form }}
{% for form in serviceFormset.forms %}
<div class='table'>
<table class='no_error'>
{{ form.as_table }}
</table>
</div>
{% endfor %}
<input type="button" value="Add More" id="add_more">
<script>
$('#add_more').click(function() {
cloneMore('div.table:last', 'service');
});
</script>
在javascript文件中:
In a javascript file:
function cloneMore(selector, type) {
var newElement = $(selector).clone(true);
var total = $('#id_' + type + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
$(this).attr('for', newFor);
});
total++;
$('#id_' + type + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
它的作用:
cloneMore
接受 selector
作为第一个参数,而formset的 type
作为第二个参数.选择器
所要做的就是传递它应该重复的内容.在这种情况下,我将其传递给 div.table:last
,以便jQuery查找具有 table
类的最后一个表.其中的:last
部分很重要,因为 selector
也用于确定将在其后插入新表单的内容.您很可能希望在其余表格的末尾使用它. type
参数是为了使我们可以更新 management_form
字段,尤其是 TOTAL_FORMS
以及实际的表单字段.如果您有一个充满 Client
模型的表单集,则管理字段的ID将为 id_clients-TOTAL_FORMS
和 id_clients-INITIAL_FORMS
表单字段将采用 id_clients-N-fieldname
的格式,其中 N
为表单编号,以 0
开头.因此,使用 type
参数, cloneMore
函数查看当前有多少种表单,并遍历新表单内的每个输入和标签,从而替换了来自类似于 id_clients-(N)-名称
到 id_clients-(N + 1)-名称
等.完成后,它将更新 TOTAL_FORMS
字段以反映新表单并将其添加到集合的末尾.
cloneMore
accepts selector
as the first argument, and the type
of formset as the 2nd one. What the selector
should do is pass it what it should duplicate. In this case, I pass it div.table:last
so that jQuery looks for the last table with a class of table
. The :last
part of it is important because the selector
is also used to determine what the new form will be inserted after. More than likely you'd want it at the end of the rest of the forms. The type
argument is so that we can update the management_form
field, notably TOTAL_FORMS
, as well as the actual form fields. If you have a formset full of, say, Client
models, the management fields will have IDs of id_clients-TOTAL_FORMS
and id_clients-INITIAL_FORMS
, while the form fields will be in a format of id_clients-N-fieldname
with N
being the form number, starting with 0
. So with the type
argument the cloneMore
function looks at how many forms there currently are, and goes through every input and label inside the new form replacing all the field names/ids from something like id_clients-(N)-name
to id_clients-(N+1)-name
and so on. After it is finished, it updates the TOTAL_FORMS
field to reflect the new form and adds it to the end of the set.
此功能对我特别有用,因为它的设置方式使我可以在整个应用程序中使用它,以便我可以在表单集中提供更多表单,而无需让我有一个隐藏的模板"只要我将表单集名称和布局的格式传递给它,就可以复制该表单.希望对您有所帮助.
This function is particularly helpful to me because the way it is setup it allows me to use it throughout the app when I want to provide more forms in a formset, and doesn't make me need to have a hidden "template" form to duplicate as long as I pass it the formset name and the format in which the forms are laid out. Hope it helps.
这篇关于动态将表单添加到Django表单集中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!