我想使用Ajax自动将新表单添加到Django表单集中,这样当用户单击"添加"按钮时,它会运行JavaScript,向页面添加一个新表单(它是表单集的一部分).
我是这样做的,使用jQuery:
我的模板:
My Services
{{ serviceFormset.management_form }} {% for form in serviceFormset.forms %}{% endfor %}{{ form.as_table }}
在javascript文件中:
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
作为第一个参数,type
formset作为第二个参数.什么是selector
应该做的是把它传递它应该复制.在这种情况下,我传递它,div.table:last
以便jQuery查找具有类的最后一个表table
.它的:last
一部分很重要,因为selector
它也用于确定之后插入新表格的内容.很可能你会在其余表格结束时想要它.这个type
论点是我们可以更新management_form
字段,特别是TOTAL_FORMS
实际的表单字段.如果你有一个表单集完整的,也就是说,Client
车型,管理领域将有标识id_clients-TOTAL_FORMS
和id_clients-INITIAL_FORMS
,而表单字段将在格式id_clients-N-fieldname
与N
为发票号,开始0
.所以与type
参数cloneMore
函数着眼于如何多种形式当前有,并通过新的形式,从像更换所有的字段名/ IDS内的每个输入和标签去id_clients-(N)-name
对id_clients-(N+1)-name
等.完成后,它会更新TOTAL_FORMS
字段以反映新表单并将其添加到集合的末尾.
这个函数对我特别有用,因为它的设置方式允许我在整个应用程序中使用它,当我想在formset中提供更多的表单时,并不需要我有一个隐藏的"模板"表单来复制只要我传递formset名称和表单的格式.希望能帮助到你.
Paolo使用empty_form
模板作为模板的简化版本.
My Services
{{ serviceFormset.management_form }}{% for form in serviceFormset.forms %}{{ form.as_table }}
{% endfor %}{{ serviceFormset.empty_form.as_table }}
我已经发布了一段我曾经工作的应用程序的代码片段.与Paolo相似,但也允许您删除表格.
Paolo的建议很好地解决了一个问题 - 浏览器的后退/前进按钮.
如果用户使用后退/前进按钮返回到formset,则不会呈现使用Paolo脚本创建的动态元素.对某些人来说可能是一个交易破坏者的问题.
例:
1)用户使用"添加更多"按钮向表单集添加两个新表单
2)用户填充表单并提交表单集
3)用户单击浏览器中的后退按钮
4)Formset现在缩减为原始形式,所有动态添加的形式都不存在
这根本不是Paolo脚本的缺陷; 但dom操作和浏览器缓存是生活中的事实.
我想可以在会话中存储表单的值,并且当formset加载以再次创建元素并从会话重新加载值时,可以使用一些ajax魔法; 但取决于你想要关于同一个用户和表单的多个实例的肛门,这可能会变得非常复杂.
任何人都有一个很好的建议处理这个?
谢谢!
查看动态django表单的以下解决方案:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
他们都使用jQuery并且是特定于django的.第一个似乎更精致,并提供了一个非常好的演示下载.
模拟和模仿:
在单击"添加"按钮之前创建与该情况对应的表单集.
加载页面,查看源并记下所有字段.
单击"添加"按钮(更改额外字段的数量)后,修改formset以对应于该情况.
加载页面,查看源并记下字段的更改方式.
创建一些JavaScript,以适当的方式修改DOM,将其从before状态移动到after状态.
将JavaScript附加到"添加"按钮.
虽然我知道formsets使用特殊的隐藏字段并且大致知道脚本必须做什么,但我不记得我头脑中的细节.我上面描述的是我在你的情况下会做的.
有一个jquery插件,我使用它与Django 1.3中设置的inline_form,它完美地工作,包括预填充,客户端表单添加,删除和多个inline_formsets.