2

I created a list that auto-grows as new content is added. It's a simple example for me to learn with that allows people to add their siblings and their age (here it is: http://jsfiddle.net/j08691/bhamU). I added a submit button to the code and am sending it to a url to be processed.

Html:

<form>
<div class="family">
    <input name="age" value=0>  <input name="sibling" value="name?">
    <hr />
</div>
</form>

Javascript:

$("form").on('keydown',"input[name='age']:last", function() {
    $('.family:last').clone().insertAfter(".family:last");
})

The problem is, if I enter:

 Bob - 25 
 Cindy - 24 
 Greg - 26  

The results I get are:

 Greg - 26
 Greg - 26
 Greg - 26

The number of results are always the same as the number of siblings I enter but the actual results are always the last entry repeated. (I'm using Pyramid and using the request.POST command to see what's being posted).

I'm wondering if this is because I'm cloning the two inputs and their names are being repeated? Is there something I should be doing to make the forms identifiable after cloning?

I am using this to get the data:

def submitchange(request):
    for x in request.POST:
        print x, ' = ', request.POST[x]

It outputs the correct number of inputs but all items are a duplicate of the last entry.

4

3 回答 3

4

好吧,您的原始代码非常非常接近功能,我很遗憾地说接受的答案不是最佳的。我的意思是,它现在可以工作了,但是想象一下你决定添加删除和重新排序项目的能力——你需要在每次操作之后在表单中重新编号元素,这会增加很多复杂性客户端。

然后,在服务器上,您需要以某种方式在 POST 中找到所有“name_1”、“name_2”、...“name_n”参数......我不确定如何以一种不是的方式执行此操作。 .. 错误... 没有吸引力。也许您需要在表单中传递一个包含总行数的隐藏变量?那会稍微简化一下事情。

无论如何,这里是真正的忍者如何做到这一点:

  1. 提交表单时,如果表单中存在多个同名控件,则将它们全部发送到服务器。HTTP 规范仅明确地为复选框指定了这一点,但如果您阅读规范的其余部分,它也隐含地允许其他控件这样做。无论如何,每个浏览器都会为多个控件发送多个名称-值对 - 您可以使用 Firebug 或仅通过将表单方法更改为 GET 来验证这一点 - URL 看起来像?name=John+Smith&name=Joann+Smith&name=Bob+Smith. 这些元素也保证按照它们在表单中出现的顺序发送。Pyramid 的deform表单库在很大程度上依赖于这一事实(通过peppercorn库,但这绝不是您的任务所必需的)。

  2. Pyramid 请求的 POST 和 GET 属性可能看起来像字典,但实际上它们是MultiDict类的实例 - 这是一个类似字典的东西,可以包含给定键的多个值。

当您访问 request.POST['param_name'] 时,MultiDict 返回添加到列表中的最后一个“标量”值 - 如果在表单中遇到多个值,它会自动返回一个列表,但这也是容易出错,因为如果只有一个元素,该值要么是一个标量,要么会神奇地变成一个包含多个元素的列表。

因此,如果您知道应该为表单中的给定键传递多个值,则可以使用 getall(key)方法检索它们。在您的示例中:

def submitchange(request):
    for x in request.POST:
        print x, ' = ', request.POST.getall(x)

应该就是这样!

此外,这里有一篇来自 Chris McDonough 的精彩文章,详细解释了所有内容:Peppercorn: A Simpleer Way to Decode Form Submission Data - 如果您决定再进一步,而不是在服务器上获取两个列表:

name = ["a", "b", "c"]
age = ["10, "20, "30"] 

有一个记录列表:

[
{'name': 'a',
 'age': 10
},
{'name': 'b',
 'age': 20
},
{'name': 'c',
 'age': 30
},

]
于 2012-07-19T01:25:50.460 回答
4

那是因为它们具有相似的属性,您应该在克隆后name更改它们的属性。name尝试这个:

<form>
<div class="family">
    <input name="age_1" value=0>  <input name="sibling1" value="name?">
    <hr />
</div>
</form>

$("form").on('blur',"input[name^='age']:last", function() {
    var name = parseInt(this.name.slice(-1), 10)
    $('.family:last').clone().insertAfter(".family:last");
    $('.family:last').find('input[name^="age"]').attr('name', 'age_'+(name+1)).val("")
})

演示

于 2012-07-17T22:55:30.617 回答
0

我想知道这是否是因为我正在克隆两个输入并且它们的名称被重复?克隆后我应该做些什么来使表格可识别?

是的你应该。

var i = 1;
$("form").on('keydown',"input[name='age']:last", function() {
    var a = $('.family:last').clone();
    a.insertAfter(".family:last");
    i++;
    $($('.family:last input')[0]).attr('name', 'age'+i);
    $($('.family:last input')[1]).attr('name', 'sibling'+i);

})
    ​
于 2012-07-17T23:17:16.340 回答