如何为用户创建相同形式的倍数

时间:2015-06-09 18:22:47

标签: javascript jquery html django forms

我有一个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)

3 个答案:

答案 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);
  });
});

http://plnkr.co/edit/jAyl2EkSkMUPWQa4gwRg?p=preview

答案 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/