如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
我更喜欢这种方法,因为:您不必遍历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中测试。
其他回答
此代码适用于我:
var data = $('#myForm input, #myForm select, #myForm textarea').toArray().reduce(function (m, e) {
m[e.name] = $(e).val();
return m;
}, {});
【2020年更新】
在vanilla js中有一个简单的oneliner,它利用了fromEntries(一如既往,请检查浏览器支持):
Object.fromEntries(new FormData(form))
我更喜欢这种方法,因为:您不必遍历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中测试。
此代码转换并保存输入类型,而不是全部转换为字符串:
jQuery.fn.serializeForm = function () {
var form = this.get(0);
var i = [];
var ret = {};
for (i = form.elements.length - 1; i >= 0; i = i - 1) {
if (form.elements[i].name === "") {
continue;
}
var name = form.elements[i].name;
switch (form.elements[i].nodeName) {
case 'INPUT':
switch (form.elements[i].type) {
case 'text':
case 'tel':
case 'email':
case 'hidden':
case 'password':
ret[name] = encodeURIComponent(form.elements[i].value);
break;
case 'checkbox':
case 'radio':
ret[name] = form.elements[i].checked;
break;
case 'number':
ret[name] = parseFloat(form.elements[i].value);
break;
}
break;
case 'SELECT':
case 'TEXTAREA':
ret[name] = encodeURIComponent(form.elements[i].value);
break;
}
}
return ret;
};
例如,这是输出:
Day: 13
Key: ""
Month: 5
OnlyPayed: true
SearchMode: "0"
Year: 2021
而不是
Day: "13"
Key: ""
Month: "5"
OnlyPayed: "true"
SearchMode: "0"
Year: "2021"
不使用JQuery序列化深度嵌套表单
在花了几天时间寻找这个没有依赖关系的问题的解决方案之后,我决定使用FormDataAPI制作一个非jQuery表单数据序列化程序。
序列化程序中的逻辑很大程度上基于jQuery插件jQueryBBQ中的de-param函数,然而,在这个项目中,所有依赖项都被删除了。
这个项目可以在NPM和Github上找到:
https://github.com/GistApps/deep-serialize-form
https://www.npmjs.com/package/deep-serialize-form
function deepSerializeForm(form) {
var obj = {};
var formData = new FormData(form);
var coerce_types = { 'true': !0, 'false': !1, 'null': null };
/**
* Get the input value from the formData by key
* @return {mixed}
*/
var getValue = function(formData, key) {
var val = formData.get(key);
val = val && !isNaN(val) ? +val // number
: val === 'undefined' ? undefined // undefined
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
: val; // string
return val;
}
for (var key of formData.keys()) {
var val = getValue(formData, key);
var cur = obj;
var i = 0;
var keys = key.split('][');
var keys_last = keys.length - 1;
if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
keys[keys_last] = keys[keys_last].replace(/\]$/, '');
keys = keys.shift().split('[').concat(keys);
keys_last = keys.length - 1;
} else {
keys_last = 0;
}
if ( keys_last ) {
for (; i <= keys_last; i++) {
key = keys[i] === '' ? cur.length : keys[i];
cur = cur[key] = i < keys_last
? cur[key] || (keys[i+1] && isNaN(keys[i+1]) ? {} : [])
: val;
}
} else {
if (Array.isArray(obj[key])) {
obj[key].push( val );
} else if (obj[key] !== undefined) {
obj[key] = [obj[key], val];
} else {
obj[key] = val;
}
}
}
return obj;
}
window.deepSerializeForm = deepSerializeForm;