我想动态地向Django表单集添加新表单,这样当用户点击“添加”按钮时,它就会运行JavaScript,向页面添加新表单(这是表单集的一部分)。
当前回答
克隆莫尔函数有一个小问题。因为它也会清除django自动生成的隐藏字段的值,如果你试图保存一个包含多个空表单的表单集,它会导致django报错。
这里有一个解决方案:
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;
if ($(this).attr('type') != 'hidden') {
$(this).val('');
}
$(this).attr({'name': name, 'id': id}).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);
}
其他回答
对于那些正在寻找资源以更好地理解上述解决方案的程序员:
Django动态表单
读完上面的链接后,Django文档和以前的解决方案应该更有意义了。
Django Formset文档
作为对我所困惑的内容的快速总结:管理表单包含其中表单的概述。你必须保证这些信息的准确性,这样Django才能知道你添加的表单。(社区,如果我的一些措辞不正确,请给我建议。我刚接触Django。)
克隆莫尔函数有一个小问题。因为它也会清除django自动生成的隐藏字段的值,如果你试图保存一个包含多个空表单的表单集,它会导致django报错。
这里有一个解决方案:
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;
if ($(this).attr('type') != 'hidden') {
$(this).val('');
}
$(this).attr({'name': name, 'id': id}).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);
}
Paolo的答案的简化版本,使用empty_form作为模板。
<h3>My Services</h3>
{{ serviceFormset.management_form }}
<div id="form_set">
{% for form in serviceFormset.forms %}
<table class='no_error'>
{{ form.as_table }}
</table>
{% endfor %}
</div>
<input type="button" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
{{ serviceFormset.empty_form.as_table }}
</table>
</div>
<script>
$('#add_more').click(function() {
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
});
</script>
我可以向每个正在寻找开箱即用解决方案的人推荐django-dynamic-formsets。
它取代了我从提出的解决方案中派生的所有代码,并提供了一些额外的功能,例如删除表单或对相关按钮进行风格化。
Paolo的建议很好用,但有一点需要注意——浏览器的后退/前进按钮。
如果用户使用后退/前进按钮返回到表单集,那么用Paolo的脚本创建的动态元素将不会被呈现。对一些人来说,这个问题可能是交易的破坏者。
例子:
1)用户使用“add-more”按钮向表单集中添加两个新表单
2)用户填充表单并提交表单集
3)用户在浏览器中点击后退按钮
4)形式集现在减少到原来的形式,所有动态添加的形式不存在
这根本不是保罗剧本的缺陷;但是dom操作和浏览器缓存是一个现实。
我认为可以在会话中存储表单的值,并在表单集加载时再次创建元素并从会话中重新加载值;但这取决于你想要的相同用户和表单的多个实例,这可能会变得非常复杂。
有人有好的建议吗?
谢谢!
推荐文章
- 如何用Django进行“批量更新”?
- 将模板变量呈现为HTML
- Django TemplateDoesNotExist吗?
- Django模型表单对象的自动创建日期
- 错误:“字典更新序列元素#0的长度为1;2是必需的”
- 改变Django的SECRET_KEY的效果
- 当Django只启动一次时执行代码?
- Django设置“SECRET_KEY”的目的是什么?
- 以编程方式将图像保存到Django ImageField中
- 嵌入YouTube视频-拒绝在帧中显示,因为它将“X-Frame-Options”设置为“SAMEORIGIN”
- django test app error -在创建测试数据库时出现错误:创建数据库的权限被拒绝
- django MultiValueDictKeyError错误,我如何处理它
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块
- Django - makemigrations -未检测到任何更改