如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
所以我使用了公认的答案,发现了一个主要缺陷。它不支持以下输入数组:
<input type="checkbox" name="array[]" value="1"/>
<input type="checkbox" name="array[]" value="2"/>
<input type="checkbox" name="array[]" value="3"/>
这一小改动应该可以解决以下问题:
function objectifyForm(inp){
var rObject = {};
for (var i = 0; i < inp.length; i++){
if(inp[i]['name'].substr(inp[i]['name'].length - 2) == "[]"){
var tmp = inp[i]['name'].substr(0, inp[i]['name'].length-2);
if(Array.isArray(rObject[tmp])){
rObject[tmp].push(inp[i]['value']);
} else{
rObject[tmp] = [];
rObject[tmp].push(inp[i]['value']);
}
} else{
rObject[inp[i]['name']] = inp[i]['value'];
}
}
return rObject;
}
记住将$(this).serializeArray()的输出传递给它;否则它不会起作用。
其他回答
这使用foreach方法迭代serializArray返回的名称和值对,然后使用名称作为键返回对象。
let formData = $(this).serializeArray();
let formObject = {}
formData.forEach(
x=>formObject.hasOwnProperty(x.name)?formObject[x.name]=[formObject[x.name],x.value].flat():formObject[x.name]=x.value
);
我更喜欢这种方法,因为:您不必遍历2个集合,如果需要,您可以获取除“name”和“value”之外的其他内容,并且可以在将值存储在对象中之前对其进行清理(例如,如果您有不希望存储的默认值)。
$.formObject = function($o) {
var o = {},
real_value = function($field) {
var val = $field.val() || "";
// additional cleaning here, if needed
return val;
};
if (typeof o != "object") {
$o = $(o);
}
$(":input[name]", $o).each(function(i, field) {
var $field = $(field),
name = $field.attr("name"),
value = real_value($field);
if (o[name]) {
if (!$.isArray(o[name])) {
o[name] = [o[name]];
}
o[name].push(value);
}
else {
o[name] = value;
}
});
return o;
}
使用方式如下:
var obj = $.formObject($("#someForm"));
仅在Firefox中测试。
这是对Tobias Cohen函数的改进,该函数在多维数组中运行良好:
http://jsfiddle.net/BNnwF/2/
然而,这不是一个jQuery插件,但如果您想这样使用它,只需几秒钟就可以将它变成一个:只需替换函数声明包装器:
function serializeFormObject(form)
{
...
}
具有:
$.fn.serializeFormObject = function()
{
var form = this;
...
};
我想这与梅斯克的解决方案相似,因为它做了相同的事情,但我认为这有点干净和简单。我还将macek的测试用例输入添加到小提琴中,并添加了一些额外的输入。到目前为止,这对我来说很好。
function serializeFormObject(form)
{
function trim(str)
{
return str.replace(/^\s+|\s+$/g,"");
}
var o = {};
var a = $(form).serializeArray();
$.each(a, function() {
var nameParts = this.name.split('[');
if (nameParts.length == 1) {
// New value is not an array - so we simply add the new
// value to the result object
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 || '';
}
}
else {
// New value is an array - we need to merge it into the
// existing result object
$.each(nameParts, function (index) {
nameParts[index] = this.replace(/\]$/, '');
});
// This $.each merges the new value in, part by part
var arrItem = this;
var temp = o;
$.each(nameParts, function (index) {
var next;
var nextNamePart;
if (index >= nameParts.length - 1)
next = arrItem.value || '';
else {
nextNamePart = nameParts[index + 1];
if (trim(this) != '' && temp[this] !== undefined)
next = temp[this];
else {
if (trim(nextNamePart) == '')
next = [];
else
next = {};
}
}
if (trim(this) == '') {
temp.push(next);
} else
temp[this] = next;
temp = next;
});
}
});
return o;
}
这种解决方案更好。这里的一些更流行的选项在未选中复选框时不会更正句柄复选框。
getData: function(element){
//@todo may need additional logic for radio buttons
var select = $(element).find('select');
var input = $(element).find('input');
var inputs = $.merge(select,input);
var data = {};
//console.log(input,'input');
$.each(inputs,function(){
if($(this).attr('type') != undefined){
switch($(this).attr('type')){
case 'checkbox':
data[$(this).attr('name')] = ( ($(this).attr('checked') == 'checked') ? $(this).val():0 );
break;
default:
data[$(this).attr('name')] = $(this).val();
break;
}
}
else {
data[$(this).attr('name')] = $(this).val();
}
})
return data;
}
此函数应处理多维数组以及多个同名元素。
到目前为止,我已经使用了几年:
jQuery.fn.serializeJSON=function() {
var json = {};
jQuery.map(jQuery(this).serializeArray(), function(n, i) {
var _ = n.name.indexOf('[');
if (_ > -1) {
var o = json;
_name = n.name.replace(/\]/gi, '').split('[');
for (var i=0, len=_name.length; i<len; i++) {
if (i == len-1) {
if (o[_name[i]]) {
if (typeof o[_name[i]] == 'string') {
o[_name[i]] = [o[_name[i]]];
}
o[_name[i]].push(n.value);
}
else o[_name[i]] = n.value || '';
}
else o = o[_name[i]] = o[_name[i]] || {};
}
}
else {
if (json[n.name] !== undefined) {
if (!json[n.name].push) {
json[n.name] = [json[n.name]];
}
json[n.name].push(n.value || '');
}
else json[n.name] = n.value || '';
}
});
return json;
};