我有一个HTML格式的表单,它有一个来自我的django ModelForms的表单对象。我想允许用户动态添加或删除相同表单的副本(如果他们选择)。类似的示例(在线演示)将是:https://github.com/laravel/lumen-framework/blob/5.0/src/Routing/UrlGenerator.php#L289
我只是不确定如何开始,因为我对JavaScript几乎没有经验。任何输入将不胜感激。
这是我的HTML代码:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="blockForm" class="original" action="{% url 'inventory:requests' inventory.id %}" method="post">{% csrf_token %}
<a href="#" id="insert-more"> Add New Row </a>
<div class="requestForm">
<div class="container">
<ul><li><input {{form.as_table}} /></li></ul>
</div>
</div>
<input type="submit" name="submit" value="Request Blocks" id="submitButton">
</form>
这是JavaScript:
<script language="javascript" type="text/javascript">
function dupeForm() {
var reqs = document.getElementsByClassName('requestForm'),
btn = document.getElementById('submitButton'),
len = reqs.length,
lastReq = reqs[len - 1],
newReq = lastReq.cloneNode(true),
txtBxs = newReq.getElementsByTagName('ul');
// I am unsure what this for loop does -quanuw
for (var i = 0; i < txtBxs.length; i++) {
txtBxs[i].setAttribute('name', 'txt' + len);
txtBxs[i].setAttribute('id', 'txt' + len);
txtBxs[i].value = 'More Text';
}
lastReq.parentNode.insertBefore(newReq, btn);
}
var submitButton = document.getElementById('submitButton');
var insertLink = document.getElementById('insert-more');
insertLink.addEventListener("click", function(e) { e.preventDefault(); dupeForm(); }, false);
submitButton.addEventListener("click", function(e) { e.preventDefault(); }, false);
</script>
这是我的模型形式:
class Block(models.Model):
class Meta:
verbose_name_plural = "Request Blocks"
inventory = models.ForeignKey(Inventory, null=True)
block_status = models.CharField(max_length=12, default='STATUS')
block_name = models.CharField(max_length=50, default='BLOCKNAME')
block_derivatives = models.CharField(max_length=100, default='DERIVATIVES')
block_subsystems = models.CharField(max_length=32, default='SUBSYSTEMS')
owners = models.CharField(max_length=100, default='OWNERS')
def __str__(self):
return self.block_name
def block_owners(self):
return str(self.owners)
答案 0 :(得分:1)
有几种方法可以做到这一点。
您可以使用JavaScript重新创建表单对象。然后,每次需要添加表单时,只需重新运行JavaScript函数。
或者,您可以使用常规HTML创建表单并将其指定为“隐藏”和类“原始”。然后,每次要添加行时,都运行以下命令:
function(){
var newForm = $('form#blockForm.original').clone().removeClass('original');
newForm.appendTo($('div.container')).show();
}
要运行此功能,您可以将其包装在附加到“添加行”按钮的.click()事件中。不要使用<a href="#" id="insert-more"> Add New Row </a>
。相反,我更愿意使用以下内容:
HTML:
<span id="insert-more">Add New Row</span>
JavaScript的:
$('span#insert-more').click(function(){
var newForm = $('form#blockForm.original').clone().removeClass('original');
newForm.appendTo($('div.container')).show();
});
当然,在加载span之后你需要一些东西来激活这个javascript。我使用$(document).ready(function(){//This is where most of my JavaScript file goes.});
--- --- EDIT
好吧,我想我在顶部并不是很清楚。我建议您使用一种隐藏在视图中的主表单,该类是“原始”。然后当你复制它时,我写的代码会删除该类,但只能从副本中删除。这样您就不会复制任何副本。但是你需要将类“原始”放在你想要复制的原始形式中!您还想要取消表单中的大多数ID,或者根本不使用它们。我更喜欢使用类,然后我对表单做的任何事情通常如下所示。
$('button.formSubmit').click(function(){
var $thisForm = $(this).parent().parent();
//multiple parent functions may be chained together, depending on how far down the button is nested.
//examples of use:
$thisForm.children('input.blah1').doSomething();
var inp2 = $thisForm.children('input.blah2');
//Really, you can do anything at this point.
});
至于为表单提供唯一ID,只要你有办法弄清楚属于哪种表单,这是不必要的,这很简单,$(this)
的功能可识别点击的内容和基于此工作。此外,如果您实际使用标准的“提交表单”功能,则无需担心$(this)
,因为它提交了单击按钮的表单,无论ID或类如何。当你要在与特定形式内的某些东西相关的形式之外放置某些东西时,你只需要担心id。但是,既然你正在制作重复的表格,那么无论如何你都不想这样做。
答案 1 :(得分:0)
我为你创建了一个可以克隆你的html表单的plunker。
$(function(){
$("#insert-more").click(function(){
var form = $("#blockForm").clone();
$(".container").append(form);
});
});
答案 2 :(得分:0)
您确定要在单个表单中克隆表单还是单个行?如果它真的是后者,您可以使用函数复制表单中的字段集并更新输入字段名称以匹配。
function dupeForm() {
var reqs = document.getElementsByClassName('requestForm'),
btn = document.getElementById('submitButton'),
len = reqs.length,
lastReq = reqs[len - 1],
newReq = lastReq.cloneNode(true),
txtBxs = newReq.getElementsByTagName('input');
for (var i = 0; i < txtBxs.length; i++) {
txtBxs[i].setAttribute('name', 'txt' + len);
txtBxs[i].setAttribute('id', 'txt' + len);
txtBxs[i].value = 'More Text';
}
lastReq.parentNode.insertBefore(newReq, btn);
}
请参阅此处的小提琴:http://jsfiddle.net/vp84oodt/