当表单包含多个输入数组字段时,是否有更好的解决方案来转换已由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"}
]
}
答案 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扩展:
它基本上是两行代码,但它需要_.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"]
答案 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
}, {})