jQuery序列化HTML5数据属性

10

没有找到相关资料,也许有人知道或者可以提供建议。

我有一个表单,里面有很多<input>元素。我想使用jQuery $.ajax功能来发送这个表单,所以我使用了$('#myform').serialize() 并将其作为json发送。

现在我的表单更加高级,并且拥有HTML5 data-属性。我也想发送它们,但是.serialize()无法识别它们。

我尝试将它们放入<form>标记和<input>标记中,但都不起作用。

最佳实践是什么,如何获取并发送所有的<form>标签上附加的data-属性?我知道.serializeArray(),但是如何序列化我<form>标签上附加的所有data-属性?


1
你需要定义你期望这些属性被序列化的方式。你只是想让 data-foo="bar" 被映射到 foo=bar 吗?此外,它们不能放入 hidden 输入标签中吗? - Alnitak
由于数据属性可以被称为任何名称,因此您还需要指定要序列化的属性。 - Mike Robinson
2
@Alnitak的想法使用隐藏输入似乎是我认为正确的方法。 - sissonb
@sissonb 这是一个非常常见的解决方案,已经使用了多年,但这不是问题的重点。 - Sergey Telshevsky
1
可能是重复的问题:https://dev59.com/T2035IYBdhLWcg3wNdLg - Nope
显示剩余6条评论
3个回答

9

以下是如何完成的。这可能不是最好的方法,但它能按照应有的方式工作。

http://jsfiddle.net/Bvzqe/12/

HTML:

<form id="frm" data-id="123" data-list[one]="first" data-list[two]="second">

序列化:
    var form = $('#frm');
    var dataarr = new Array();
    for(var i in form.data()) {
        var subarr = new Array();
        subarr['name'] = i;
        subarr['value'] = form.data()[i];
        dataarr.push(subarr);
    }
    var serialized = $.param(form.serializeArray().concat(dataarr));

它甚至允许您拥有data-属性的数组,例如

data-list[one]="first" data-list[two]="second"

URL编码可能看起来有些不对,因为它转义了方括号,但我已在服务器端进行了测试-它解析的一切都是正确的。

这仅适用于那些不想使用<input type="hidden">的人。


这个方法可行,是正确的做法。我在几个辅助方法中使用了这种代码。一个新的“serializeDataArray()”jQuery扩展和一个包含三个部分的AJAX回传方法...原始表单序列化数组,然后序列化表单和源/回传控件的数据属性。不确定HTML 5对此的规定是什么,但我认为大多数情况下需要来自(更全局的)表单和(上下文的)源元素的数据属性。 - Tony Wall
谢谢提醒,你可以使用隐藏输入框哈哈 - twan
你好,如何将JSON反序列化为数据属性的方式? - aggie

6
如果可能的话,您应该将额外的值存储为hidden输入字段(每个值一个),而不是作为其他输入字段上的元数据。然后它们将自动作为表单的一部分进行序列化。
我不会为您编写序列化程序,因为我认为这是一个坏主意。如果您坚持要将值作为data-字段发送到浏览器,您可以使用以下方式将这些data-字段转换为hidden输入字段。
$('#myform:input').each(function() {
    var input = this;
    $.each($(input).data(), function(key, value) {
        $('<input>', {type: hidden, name: key, value: value}).insertAfter(input);
    });
});

咦,神奇的隐藏输入字段会自动序列化!

请注意,jQuery也使用.data()来存储事件等内容。为了避免迭代这些对象,您必须使用原生DOM函数检索data- 属性,而不是已经存储在元素上的任何数据相关 属性


这只是我的问题的一个解决方法,而不是解决方案。我知道这是标准方式,但我问的是如何序列化“data-”属性,而不是“如何隐藏数据以防止在屏幕上显示”。隐藏输入框只是因为以前没有js和ajax。对于高负载项目,写<input type="hidden" name="key" value="value">而不是data-key="value"会使用更多的带宽,加载时间更长。我甚至没有提到在JS中操作这些数据的便捷性。 - Sergey Telshevsky
4
@Vlakarados,没错,这就是我所说的一个变通方法。您发明了一种方案来存储额外的信息在表单中(因为对页面加载时间有轻微的担忧),但这种方案并不被W3C的<form>标签支持,然后当序列化该数据的手段不存在时抱怨?!隐藏字段的发明并不是“因为没有AJAX”,而是因为这是在表单中提供额外信息的方法! - Alnitak
2
我必须支持@Alnitak的观点,额外输入引入的带宽非常微不足道。隐藏的输入也可以工作,无论JavaScript是否启用(或损坏)。 - Mike Robinson
1
@Vlakarados 你应该注意到我已经达到了每日限制,所以我不会因此获得任何声望。但我还是付出了很多努力,因为我认为你目前的实现方式是错误的。 - Alnitak
1
我要支持 Sergey。我现在也面临同样的挑战。虽然使用隐藏输入元素被认为是将附加数据添加到表单的标准做法,但该方法固有的一个大问题是,不能再将 data-* 值与特定的表单元素关联起来。也就是说,一旦序列化,您最终会得到一个扁平映射,其结构不表示关联。我最终可能会做的是编写自己的序列化器,创建表单的 JSON 树。 - Aquarelle
显示剩余10条评论

0
这是我的函数,获取元素的所有data-*并支持忽略数组。
Data2Params: function (el, ignoredAtt) {
    ignoredAtt = typeof ignoredAtt !== 'undefined' ? ignoredAtt : [];

    var data = {};
    for (var key in el.data()) {
        if (ignoredAtt.indexOf(key) === -1)
            data[key] = el.data(key);
    }
    return data;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接