使用jQuery将复杂表单序列化为JSON对象

时间:2010-09-09 00:39:16

标签: jquery json forms serialization

我一直在寻找这个时间,但没有找到答案。 火焰之前请仔细阅读整个问题! :)

我有一个类似的表格:

<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

提前感谢大家。

6 个答案:

答案 0 :(得分:19)

试试这个我为你写的代码......对我来说很好,只需使用你的数据结果。你可以使用它并制作一个简单的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...');
            }
        }
    }
}

答案 1 :(得分:6)

答案 2 :(得分:2)

这对我来说非常有效。这不需要有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

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

答案 3 :(得分:1)

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

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

逻辑很简单,秘诀就是eval像动态命令一样运行Strings。 我试图让它变得越来越容易,几乎所有的行都被评论过了。

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

答案 4 :(得分:0)

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

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

您可以在$ .post和$ .get中使用

的nJoy!

答案 5 :(得分:0)

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