如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').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
);
其他回答
serialize函数将JSON对象作为参数并返回serialize String。
function serialize(object) {
var _SPECIAL_CHARS = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, _CHARS = {
'\b' : '\\b',
'\t' : '\\t',
'\n' : '\\n',
'\f' : '\\f',
'\r' : '\\r',
'"' : '\\"',
'\\' : '\\\\'
}, EMPTY = '', OPEN_O = '{', CLOSE_O = '}', OPEN_A = '[', CLOSE_A = ']', COMMA = ',', COMMA_CR = ",\n", CR = "\n", COLON = ':', space = "", COLON_SP = ': ', stack = [], QUOTE = '"';
function _char(c) {
if (!_CHARS[c]) {
_CHARS[c] = '\\u' + ('0000' + (+(c.charCodeAt(0))).toString(16))
.slice(-4);
}
return _CHARS[c];
}
function _string(s) {
return QUOTE + s.replace(_SPECIAL_CHARS, _char) + QUOTE;
// return str.replace('\"','').replace('\"','');
}
function serialize(h, key) {
var value = h[key], a = [], colon = ":", arr, i, keys, t, k, v;
arr = value instanceof Array;
stack.push(value);
keys = value;
i = 0;
t = typeof value;
switch (t) {
case "object" :
if(value==null){
return null;
}
break;
case "string" :
return _string(value);
case "number" :
return isFinite(value) ? value + EMPTY : NULL;
case "boolean" :
return value + EMPTY;
case "null" :
return null;
default :
return undefined;
}
arr = value.length === undefined ? false : true;
if (arr) { // Array
for (i = value.length - 1; i >= 0; --i) {
a[i] = serialize(value, i) || NULL;
}
}
else { // Object
i = 0;
for (k in keys) {
if (keys.hasOwnProperty(k)) {
v = serialize(value, k);
if (v) {
a[i++] = _string(k) + colon + v;
}
}
}
}
stack.pop();
if (space && a.length) {
return arr
? "[" + _indent(a.join(COMMA_CR), space) + "\n]"
: "{\n" + _indent(a.join(COMMA_CR), space) + "\n}";
}
else {
return arr ? "[" + a.join(COMMA) + "]" : "{" + a.join(COMMA)
+ "}";
}
}
return serialize({
"" : object
}, "");
}
Tobias Cohen解决方案的固定版本。此函数正确处理0和“”等错误值。
jQuery.fn.serializeObject = function() {
var arrayData, objectData;
arrayData = this.serializeArray();
objectData = {};
$.each(arrayData, function() {
var value;
if (this.value != null) {
value = this.value;
} else {
value = '';
}
if (objectData[this.name] != null) {
if (!objectData[this.name].push) {
objectData[this.name] = [objectData[this.name]];
}
objectData[this.name].push(value);
} else {
objectData[this.name] = value;
}
});
return objectData;
};
以及一个CoffeeScript版本,方便您编写代码:
jQuery.fn.serializeObject = ->
arrayData = @serializeArray()
objectData = {}
$.each arrayData, ->
if @value?
value = @value
else
value = ''
if objectData[@name]?
unless objectData[@name].push
objectData[@name] = [objectData[@name]]
objectData[@name].push value
else
objectData[@name] = value
return objectData
Tobias上面的解决方案是正确的,但是正如评论者@macek所指出的,它不处理foo[bar]类型的输入并将其拆分为子对象。
这是一个PHP独有的特性,但我仍然觉得能够在JavaScript中生成相同的结构非常有用。
我只是修改了上面托拜厄斯的代码,所以所有的功劳都归于他。这可能会变得更干净,但我只是在五分钟内把它搅拌起来,并认为它可能有用。
此时它不处理多维数组或数字索引数组。也就是说,它只能使用foo[bar]而不能使用foo[]。
jQuery.fn.serializeObjectPHP = function()
{
var o = {};
var re = /^(.+)\[(.*)\]$/;
var a = this.serializeArray();
var n;
jQuery.each(a, function() {
var name = this.name;
if ((n = re.exec(this.name)) && n[2]) {
if (o[n[1]] === undefined) {
o[n[1]] = {};
o[n[1]][n[2]] = this.value || '';
} else if (o[n[1]][n[2]] === undefined) {
o[n[1]][n[2]] = this.value || '';
} else {
if(!o[n[1]][n[2]].push) {
o[n[1]][n[2]] = [ o[n[1]][n[2]] ];
}
o[n[1]][n[2]].push(this.value || '');
}
} else {
if (n && !n[2]) {
name = n[1];
}
if (o[name] !== undefined) {
if (!o[name].push) {
o[name] = [o[name]];
}
o[name].push(this.value || '');
} else {
o[name] = this.value || '';
}
}
});
return o;
};
不使用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;
从一些旧的答案来看:
$('form input, form select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})