如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
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上面的解决方案是正确的,但是正如评论者@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;
};
要获得快速、现代的解决方案,请使用JSONify jQuery插件。下面的示例是从GitHub README中逐字摘录的。这一切都归功于插件作者Kushal Pandya。
鉴于:
<form id="myform">
<label>Name:</label>
<input type="text" name="name"/>
<label>Email</label>
<input type="text" name="email"/>
<label>Password</label>
<input type="password" name="password"/>
</form>
正在运行:
$('#myform').jsonify();
生产:
{"name":"Joe User","email":"joe@example.com","password":"mypass"}
如果要使用此JSON对象执行jQuery POST:
$('#mybutton').click(function() {
$.post('/api/user', JSON.stringify($('#myform').jsonify()));
}
使用lodash#set
let serialized = [
{ key: 'data[model][id]', value: 1 },
{ key: 'data[model][name]', value: 'product' },
{ key: 'sid', value: 'dh0un1hr4d' }
];
serialized.reduce(function(res, item) {
_.set(res, item.key, item.value);
return res;
}, {});
// returns
{
"data": {
"model": {
"id": 1,
"name": "product"
}
},
"sid": "dh0un1hr4d"
}
创建地图并循环所有字段,保存其值。
var params = {};
$("#form").find("*[name]").each(function(){
params[this.getAttribute("name")] = this.value;
});
这使用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
);