2011-02-09 43 views
0

我有一个表单。在这种形式下,用户可以填写一些字段,然后点击“添加”。数据变成一个HTML元素,然后表单得到(部分)清除,以便他可以键入更多的数据。如何在表单中保存“添加另一个”数据?

我想弄清楚如何存储数据,当他点击“添加”,以便它可以稍后提交。我应该序列化(JSON?还是有更紧凑的表示形式 - 不需要人类可读),并将其存储在隐藏域中?如果是这样,当他添加第二个对象时会发生什么?我对旧数据进行反序列化,然后将这两个对象重新组合在一起?似乎效率低下。

难道我会以某种方式克隆表单,隐藏它,并更新所有name属性,以免它们发生冲突,然后杀死自己试图将这些愚蠢的东西解析到数组中?

什么是最好的方法?

+0

您是否必须提交表单或可以使用Ajax调用来发布数据? –

+0

@K Ivanov:我宁愿按照正常的方式提交表单,不用JS。 – mpen

回答

2

在名称的某个位置创建一个带有增量数字后缀的隐藏字段。

var fields = $('input[type=hidden][name^=foo_]', form).length; 
$('<input type="hidden" name="foo_' + (fields + 1) + '">').val(val).appendTo(form); 

提交它通常的方式,jQuery.serialize()等。

最后在服务器端截取它(半伪)。

for (var i = 0; i < Integer.MAX_VALUE; i++) { 
    var value = request.getParameter("foo_" + i); 
    if (value == null) break; 
    // ... 
} 

注意,与多个同名的隐藏字段也被允许的,但你是依赖于使用它们是否会从请求相同的顺序收集,因为它们出现在查询字符串中的服务器端技术(HTTP/HTML规范已经要求它们必须在HTTP查询字符串中以与它们各自的HTML输入元素出现在DOM树中相同的顺序出现)。据我所知,PHP和Servlet正确地做到了这一点(即值在参数值数组中出现的顺序与它们出现在HTTP查询字符串中的顺序相同)。

+0

另一个有趣的部分是我想让用户也删除它们。那么我将不得不循环所有这些隐藏的表单并对它们重新编号? – mpen

+1

@Mark:我会添加另一个表示Integer.MAX_VALUE的隐藏字段,并在每次添加时增加它,并将其用作隐藏字段的名称后缀,并在服务器端用作循环的结束条件。如果value为null/empty,那么它已被删除,但您可以忽略它并继续。 – BalusC

+0

@BalusC:听起来不那么痛苦。 – mpen

0

这在某种程度上取决于您的服务器如何预期数据,而这又取决于您使用的是服务器端的语言/框架。如果您的服务器可以轻松处理具有相同名称的多个字段,则非常简单。 (这个例子用jQuery进行简化。)

function onAddMore() { 
    var $form = $("#myForm"); 
    var $foo = $form.find("[name=foo]").eq(0); // the first (original) foo 

    $form.append($foo.clone()) 
    $foo.val(""); 
} 

当用户提交表单通常情况下,您的查询看起来像foo=bar&foo=baz&foo=quux

下面是如何遍历Python CGI中的值的示例。

form = cgi.FieldStorage() 

for foo in form.getlist("foo"): 
    # do something with foo 

还是在PHP(请注意,PHP,the field must be named foo[])。

for ($_GET["foo"] as $foo) { // $_POST would work the same way, of course 
    // do something with $foo 
} 
+0

正如我向Yads解释,这是行不通的。它不适用于复选框或单选按钮,以及任何服务器端语言。 – mpen

相关问题