如何将jQuery.serialize()数据转换为JSON对象?

时间:2010-07-18 23:20:29

标签: javascript jquery json serialization

当表单包含多个输入数组字段时,是否有更好的解决方案来转换已由jQuery函数serialize()序列化的表单数据。我希望能够将表单数据转换为JSON对象以重新创建一些其他信息表。所以告诉我一个更好的方法来将序列化字符串转换为JSON对象。

<form id='sampleform'>
    <input name='MyName' type='text' /> // Raf

    <!--array input fields below-->
    <input name='friendname[]' type='text' /> // Bily
    <input name='fiendemail[]' type='text' /> // bily@someemail.com

    <!--duplicated fields below to add more friends -->
    <input name='friendname[]' type='text' /> // Andy
    <input name='fiendemail[]' type='text' /> // Andy@somwhere.com

    <input name='friendname[]' type='text' /> // Adam
    <input name='fiendemail[]' type='text' /> // Adam@herenthere.com
</form>

用于获取数据的jquery方法

var MyForm = $("#sampleform").serialize();
/** result : MyName=Raf&friendname[]=Billy&fiendemail[]=bily@someemail.com&friendname[]=Andy&fiendemail[]=Andy@somwhere.com&friendname[]=Adam&fiendemail[]=Adam@herenthere.com
*/

如何将此数据输入JSON对象? 它应具有以上表格中的以下示例JSON数据。

{
    "MyName":"raf",
    "friendname":[
        {"0":"Bily"},
        {"1":"Andy"},
        {"2":"Adam"}
    ],
    "friendemail":[
        {"0":"bily@someemail.com"},
        {"1":"Andy@somwhere.com"},
        {"2":"Adam@herenthere.com"}
    ]
}

12 个答案:

答案 0 :(得分:45)

var formdata = $("#myform").serializeArray();
var data = {};
$(formdata ).each(function(index, obj){
    data[obj.name] = obj.value;
});

简单快速;)

答案 1 :(得分:12)

我最近遇到了这个问题。最初,我们使用jQuery的serializeArray()方法,但不包括禁用的表单元素。我们经常会禁用与页面上其他来源“同步”的表单元素,但我们仍然需要将数据包含在序列化对象中。所以serializeArray()已经出局了。我们使用:input选择器获取给定容器中的所有输入元素(启用和禁用),然后$.map()创建我们的对象。

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);

请注意,要使其正常工作,您的每个输入都需要name属性,该属性将是生成对象的属性名称。

这实际上与我们使用的内容略有不同。我们需要创建一个结构为.NET IDictionary的对象,所以我们使用了这个:(我在这里提供它以防它有用)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);

我喜欢这两种解决方案,因为它们是$.map()函数的简单用法,并且您可以完全控制选择器(因此,最终包含在结果对象中的元素)。此外,不需要额外的插件。简单的旧jQuery。

答案 2 :(得分:7)

使用jQuery.serializeJSON插件。 它使用与Rails参数对象相同的格式转换表单,这是非常标准和经过充分测试的。

答案 3 :(得分:5)

我正在使用这个非常小的jQuery插件,我已从DocumentCloud扩展:

https://github.com/documentcloud/documentcloud/blob/master/public/javascripts/lib/jquery_extensions.js

它基本上是两行代码,但它需要_.js(Underscore.js),因为它基于reduce函数。

$.fn.extend({
  serializeJSON: function(exclude) {
    exclude || (exclude = []);
    return _.reduce(this.serializeArray(), function(hash, pair) {
      pair.value && !(pair.name in exclude) && (hash[pair.name] = pair.value);
      return hash;
    }, {});
  }
});

扩展:

  • 如果输入值为null,则不会序列化输入值
  • 它可以通过将输入名称数组传递给exclude参数i.e. ["password_confirm"]
  • 来排除某些输入

答案 4 :(得分:4)

Danilo Colasso's的等效解决方案,具有.serializeArray()的优点和缺点(基本上它使用.reduce代替$.each)。

只需付出很少的努力,就可以在不需要扩展的情况下实现S.C.答案中的额外功能。

$(selector).serializeArray()
    .reduce(function(accum, item) {
        // This 'if' allows ignoring some values
        if (-1 === [ 'ignoreThis', 'andThat' ].indexOf(item.name)) {
            // This allows ignoring NULL values
            if (item.value !== null) {
                accum[item.name] = item.value;
            }
        }
        return accum;
    },
    {
        // By supplying some initial values, we can add defaults
        // for, say, disabled form controls.
        preFilledName:  preFilledValue, // optional
        defaultName  :  defaultValue    // optional
    }
);

答案 5 :(得分:2)

使用下划线&amp; jQuery

var formdata = $("#myform").serializeArray();
var data = {};
_.each(formdata, function(element){
// Return all of the values of the object's properties.
  var value = _.values(element);
// name : value 
  data[value[0]] = value[1];
});
console.log(data); //Example => {name:"alex",lastname:"amador"}

答案 6 :(得分:2)

我认为这里有很多好的答案,我根据这些答案制定了自己的功能。

function formToJSON(f) {
    var fd = $(f).serializeArray();
    var d = {};
    $(fd).each(function() {
        if (d[this.name] !== undefined){
            if (!Array.isArray(d[this.name])) {
                d[this.name] = [d[this.name]];
            }
            d[this.name].push(this.value);
        }else{
            d[this.name] = this.value;
        }
    });
    return d;
}

//The way to use it :
$('#myForm').submit(function(){
    var datas = formToJSON(this);
    return false;
});

让我解释为什么我更喜欢这个解决方案...... 如果您有多个输入具有相同的名称,则所有值都将存储在数组中,但如果不是,则该值将直接存储为JSON中的索引值...这与 Danilo不同Colasso的回答 JSON返回的地方仅基于数组值...

因此,如果你的表格有一个名为 content 的textarea和多个作者,那么这个函数将返回给你:

{
    content : 'This is The Content',
    authors : 
        [
            0: 'me',
            1: 'you',
            2: 'him',
        ]
}

答案 7 :(得分:1)

var formdata = $("#myform").serializeArray();

var data = {};

$(formdata ).each(function(index, obj){

         if(data[obj.name] === undefined)
              data[obj.name] = [];

          data[obj.name].push(obj.value);

});

答案 8 :(得分:0)

如果您使用的是ajax请求,则无需使其json-object$('#sampleform').serialize()可以很好地工作,或者如果您还有其他目的,这是我的解决方案:

var formserializeArray = $("#sampleform").serializeArray();   
var jsonObj = {};
jQuery.map(formserializeArray , function (n, i) {
    jsonObj[n.name] = n.value;
});

答案 9 :(得分:0)

  

有了所有给出的答案,有一些问题是...

如果将名称输入为数组,例如name[key],则它将像这样生成

 name:{
   key : value
 }

例如: 如果我有这样的表格。

    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
    </form>

然后它将使用所有给定的答案生成这样的对象。

Object {
    name : 'value',
    name1[key1] : 'value1',
    name2[key2] : 'value2',
    name3[key3] : 'value3', 
}

但是它必须像下面那样生成,任何人都想像下面这样。

Object {
    name : 'value',
    name1 : {
        key1 : 'value1'
    },
    name2 : {
        key2 : 'value2'
    },
    name3 : {
        key2 : 'value2'
    }
}
  

然后在js代码下面尝试。

(function($){
    $.fn.getForm2obj = function(){
        var _ = {},_t=this;
        this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
        this.b = function(k,v,a = 0){ if(a) eval(k+".push("+v+");"); else eval(k+"="+v+";"); };
        $.map(this.serializeArray(),function(n){
            if(n.name.indexOf('[') > -1 ){
                var keys = n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g),le = Object.keys(keys).length,tmp = '_';
                $.map(keys,function(key,i){
                    if(key == ''){
                        eval("ale = Object.keys("+tmp+").length;");
                        if(!ale) _t.b(tmp,'[]');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'",1);
                        else _t.b(tmp += "["+ale+"]",'{}');
                    }else{
                        _t.c(tmp += "['"+key+"']",'{}');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'");
                    }
                });
            }else _t.b("_['"+n['name']+"']","'"+n['value']+"'");
        });
        return _;
    }
})(jQuery);
console.log($('form').getForm2obj());
<!DOCTYPE html><html><head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <title>Convert form data to JavaScript object with jQuery</title>
</head>
<body>
    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
        <input type="checkbox" name="name4[]" value="1" checked="checked">
        <input type="checkbox" name="name4[]" value="2">
        <input type="checkbox" name="name4[]" value="3">
    </form>
</body></html>

答案 10 :(得分:0)

如果可以使用ES6,则可以

const obj = arr.reduce((acc, {name, value}) => ({...acc, [name]: value}), {})

对于序列化数组非常有效。

答案 11 :(得分:0)

利用归约功能!

$(form).serializeArray().reduce(function (output, value) {
        output[value.name] = value.value

        return output
}, {})