【问题标题】:Serialize complex form to JSON object using jQuery使用 jQuery 将复杂表单序列化为 JSON 对象
【发布时间】:2011-04-10 00:51:22
【问题描述】:

我已经为此搜索了几个小时,但没有找到答案。 请在燃烧之前通读整个问题! :)

我有一个类似这样的表格:

<form id="sample">
 <input name="name" type="text" value="name value" />

 <input name="phone[0][type]" type="text" value="cell" />
 <input name="phone[0][number]" type="text" value="000" />

 <input name="phone[1][type]" type="text" value="home" />
 <input name="phone[1][number]" type="text" value="111" />
</form>

并且需要能够将其序列化为:

{
 name: 'name value',

 phone: [
  {
   type: 'cell',
   number: '000'
  },
  {
   type: 'home',
   number: '111'
  }
 ]
}

我已经尝试了大多数关于 SO 的答案,包括 jquery-json 库,其中大多数都返回如下内容:

{
 'name': 'name value',
 'phone[0][type]': 'cell',
 'phone[0][number]': '000',
 'phone[1][type]': 'home',
 'phone[1][number]': '111',
}

这是我不能使用的东西! :P

提前感谢大家。

【问题讨论】:

标签: jquery json forms serialization


【解决方案1】:

试试我为你写的这段代码……对我来说很好,只需使用你的数据结果。你可以使用它并制作一个简单的 jQuery 插件...

示例需要 JSON.stringify 才能完全工作。

var d = {
    'name': 'name value',
    'phone[0][type]': 'cell',
    'phone[0][number]': '000',
    'phone[1][type]': 'home',
    'phone[1][number]': '111',
};

$(document).ready(function(){

    arrangeJson(d);
    alert(JSON.stringify(d));
});

function arrangeJson(data){
    var initMatch = /^([a-z0-9]+?)\[/i;
    var first = /^\[[a-z0-9]+?\]/i;
    var isNumber = /^[0-9]$/;
    var bracers = /[\[\]]/g;
    var splitter = /\]\[|\[|\]/g;

    for(var key in data) {
        if(initMatch.test(key)){
            data[key.replace(initMatch,'[$1][')] = data[key];
        }
        else{
            data[key.replace(/^(.+)$/,'[$1]')] = data[key];
        }
        delete data[key];
    }


    for (var key in data) {
        processExpression(data, key, data[key]);
        delete data[key];
    }

    function processExpression(dataNode, key, value){
        var e = key.split(splitter);
        if(e){
            var e2 =[];
            for (var i = 0; i < e.length; i++) {
                    if(e[i]!==''){e2.push(e[i]);} 
            }
            e = e2;
            if(e.length > 1){
                var x = e[0];
                var target = dataNode[x];
                if(!target){
                    if(isNumber.test(e[1])){
                        dataNode[x] = [];
                    }
                    else{
                        dataNode[x] ={}
                    }
                }
                processExpression(dataNode[x], key.replace(first,''), value);
            }
            else if(e.length == 1){
                dataNode[e[0]] = value;
            }
            else{
                alert('This should not happen...');
            }
        }
    }
}

【讨论】:

  • 非常感谢朱利亚诺!这是完美的解决方案! :D
  • 像魔术一样工作。对其进行了一些修改以处理您的列表格式为 var d = { 'name': 'name value', 'phone[0].type': 'cell', 'phone[0].number ': '000', 'phone[1].type': 'home', 'phone[1].number': '111', };结果有 (.) in from 内部列表 Key,所以我在 processExpression() 函数的第一个 for 循环之后添加了 .
  • key 在函数中被声明了两次。
【解决方案2】:

还有下面这个库

http://code.google.com/p/form2js/

【讨论】:

    【解决方案3】:

    这对我来说效果很好。这不需要 form2js 库。

    $.fn.serializeObject = function serializeObject() {
            var o = {};
            var a = this.serializeArray();
            $.each(a, function () {
                if (o[this.name] !== undefined) {
                    if (!o[this.name].push) {
                        o[this.name] = [o[this.name]];
                    }
                    o[this.name].push(this.value || '');
                } else {
                    o[this.name] = this.value || '';
                }
            });
            return o;
        };
    

    为了序列化表单数据,我使用了这段代码。

    JSON.stringify($(this).serializeObject());//'this' points to the form
    

    如果您有任何疑问,请随时添加评论。

    【讨论】:

    • 你的表单是什么样子才能让它工作?
    【解决方案4】:

    使用这种结构,我认为任何 JSON 库都无法完成所有工作。 所以,我认为编写我们自己的转换循环更容易。

    这是您的序列化代码:http://jsfiddle.net/7MAUv/1/

    逻辑很简单,秘诀是eval 可以像动态命令一样运行字符串。 我试图让它尽可能简单,几乎所有的行都被注释了。

    顺便说一句,请随时提出问题。

    【讨论】:

    • 您的代码完美运行 Erick。非常感谢您发布它。我会尝试看看是否可以在没有 eval 部分的情况下完成,但现在应该很棒。
    【解决方案5】:

    这并不完全符合您的要求,但如果您使用的是 jQuery 库并且需要序列化复杂的表单以便在 ajax 中发送它,您可以像这样使用 sth

    ajaxRunning = $.ajax(
       "?"+$('#yourForm').serialize(),
        {
           data: {
               anotherData: 'worksFine',
               etc: 'still works'
           },
           success: function(result) {
               doSth();
           },
           dataType: "json"
    });
    

    你也可以在 $.post 和 $.get 中使用

    开心!

    【讨论】:

      【解决方案6】:

      另一个解决此问题的库是 Mario Izquierdo 的 jquery.serializeJSON。它可以工作并扩展 jQuery。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-08
        • 2017-11-25
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多