如何从自动增长到POST的列表中获取所有独特元素?

时间:2012-07-17 22:49:38

标签: javascript jquery python html pyramid

我创建了一个在添加新内容时自动增长的列表。这是我学习的一个简单例子,它允许人们添加他们的兄弟姐妹和他们的年龄(这里是:http://jsfiddle.net/j08691/bhamU)。我在代码中添加了一个提交按钮,并将其发送到要处理的URL。

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");
})

问题是,如果我输入:

 Bob - 25 
 Cindy - 24 
 Greg - 26  

我得到的结果是:

 Greg - 26
 Greg - 26
 Greg - 26

结果的数量始终与我输入的兄弟姐妹的数量相同,但实际结果始终是重复的最后一个条目。 (我正在使用Pyramid并使用request.POST命令查看正在发布的内容。

我想知道这是因为我正在克隆这两个输入并且他们的名字正在被重复?克隆后,我是否应该采取措施使表格可识别?

我用它来获取数据:

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

输出正确数量的输入,但所有项目都是最后一个条目的副本。

3 个答案:

答案 0 :(得分: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("")
})

DEMO

答案 1 :(得分:4)

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

然后,在服务器上,您需要以某种方式在POST中找到所有“name_1”,“name_2”,...“name_n”参数...我不知道如何以某种方式执行此操作不是......错误......没有吸引力。也许你需要在表格中传递隐藏的变量和总行数?这会简化这个问题。

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

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

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

  3. 当您访问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 Simpler 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
    },
    
    ]
    

答案 2 :(得分: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);

})
    ​