2010-07-18 38 views
35

当窗体包含多个输入数组字段时,是否有更好的解决方案来转换已被jQuery函数serialize()序列化的表单数据。我希望能够将表单数据转换为JSON对象以重新创建其他一些信息丰富的表格。所以告诉我一个更好的方法来获取序列化字符串转换为JSON对象。如何将jQuery.serialize()数据转换为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' /> // [email protected] 

    <!--duplicated fields below to add more friends --> 
    <input name='friendname[]' type='text' /> // Andy 
    <input name='fiendemail[]' type='text' /> // [email protected] 

    <input name='friendname[]' type='text' /> // Adam 
    <input name='fiendemail[]' type='text' /> // [email protected] 
</form> 

jQuery的方法适用于获取数据

var MyForm = $("#sampleform").serialize(); 
/** result : MyName=Raf&friendname[]=Billy&fiendemail[][email protected]&friendname[]=Andy&fiendemail[][email protected]&friendname[]=Adam&fiendemail[][email protected] 
*/ 

如何使这个数据到一个JSON对象? 它应该从上面的表单中获得以下示例JSON数据。

{ 
    "MyName":"raf", 
    "friendname":[ 
     {"0":"Bily"}, 
     {"1":"Andy"}, 
     {"2":"Adam"} 
    ], 
    "friendemail":[ 
     {"0":"[email protected]"}, 
     {"1":"[email protected]"}, 
     {"2":"[email protected]"} 
    ] 
} 
+1

从技术上讲,这不是基于您的查询字符串格式化JSON对象的方式。具体来说,数组元素不会是具有索引的对象,而只是值。这样说,如果你需要你发布的格式,你可能需要编写一个自定义函数。 – 2010-07-18 23:28:02

+1

可能重复[序列化形式JSON与jQuery](http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery) – SLaks 2010-07-18 23:38:09

+0

谢谢Slaks和杰森,是的,我同意我需要一个功能去做,而Slaks已经为我指出了这一点。 – Raftalks 2010-07-19 00:23:41

回答

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。

+0

尝试过但似乎没有工作。 – Raftalks 2010-07-19 00:24:42

+0

我只注意到你使用'friendname []'作为你的输入元素的名字,来捕获一个值的数组而不是一个值。我不认为'$ .map()'可以很好地工作。 – 2010-07-19 02:37:49

+2

我认为你的地图函数不是很正确......你为每个属性返回一个单独的对象......不要'你想把所有的属性放在一个单一的对象上......所以在函数外声明对象,而不是在里面(并且不要返回任何东西 - 只使用地图作为副作用) – 2011-04-07 19:30:29

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; 
    }, {}); 
    } 
}); 

扩展:

  • ,如果它是空,它不序列化的输入值
  • 它可以通过将输入名称的数组到exclude参数i.e. ["password_confirm"]
排除一些投入
+0

可爱的,完美的工作! – 2015-12-23 17:34:40

2

使用下划线& 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"} 
5

使用jQuery.serializeJSON插件。 它使用与在Rails params对象中找到的格式相同的格式来转换表单,这是非常标准且经过良好测试的。

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

简单和快速;)

+1

这不会生成一个层次化的JS对象 – Epoc 2016-01-22 09:16:41

+2

@Epoc您指的是什么层次结构的概念?表单数据是平坦的。 – John 2016-11-07 20:06:51

+0

var formdata = $(“#myform”)。serializeArray(); formdata = JSON.parse(formdata); // add this line var data = {}; $(formdata).each(function(index,obj){ data [obj.name] = obj.value; }); – 2017-04-30 19:46:56

2

的等效溶液至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 
    } 
); 
0
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); 

}); 
+1

虽然这段代码可能会解决这个问题,但[包括解释](// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高帖子的质量。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性注释来挤占代码,这会降低代码和解释的可读性! – kayess 2017-04-11 13:13:18

0

我觉得这里是有很多很好的答案,我根据这些回答让我自己的功能。

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的指数值...这是它从达尼洛Colasso的回答在JSON返回仅仅基于阵列值的不同...

所以,如果你有一个名为textarea的表单内容和倍数作者,此函数将返回到y ou:

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