如何将表单的所有元素转换为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中测试。
其他回答
我喜欢塞缪尔的版本,但我相信它有一个小错误。通常JSON发送为
{“coreSKU”:“PCGUYJS”,“name_de”:“whatever”,。。。
不作为
〔{“coreSKU”:“PCGUYJS”},{“name_de”:“whatever”},。。。
因此,功能IMO应为:
App.toJson = function( selector ) {
var o = {};
$.map( $( selector ), function( n,i )
{
o[n.name] = $(n).val();
});
return o;
}
并将其包装在数据数组中(正如通常预期的那样),最后将其作为跨页发送App.stringify({data:App.toJson(“#cropform:input”)})
对于精简版本,请参见问题3593046,对于所有可能的版本,请参阅json2.js。这应该涵盖了所有内容:)
由于XSS攻击和可能存在的其他问题,我不会在现场网站上使用此功能,但下面是一个快速示例:
$("#myform").submit(function(){
var arr = $(this).serializeArray();
var json = "";
jQuery.each(arr, function(){
jQuery.each(this, function(i, val){
if (i=="name") {
json += '"' + val + '":';
} else if (i=="value") {
json += '"' + val.replace(/"/g, '\\"') + '",';
}
});
});
json = "{" + json.substring(0, json.length - 1) + "}";
// do something with json
return false;
});
这里有一种非jQuery方法:
var getFormData = function(form) {
//Ignore the submit button
var elements = Array.prototype.filter.call(form.elements, function(element) {
var type = element.getAttribute('type');
return !type || type.toLowerCase() !== 'submit';
});
您可以这样使用:
function() {
var getFormData = function(form) {
//Ignore the submit button
var elements = Array.prototype.filter.call(form.elements, function(element) {
var type = element.getAttribute('type');
return !type || type.toLowerCase() !== 'submit';
});
//Make an object out of the form data: {name: value}
var data = elements.reduce(function(data, element) {
data[element.name] = element.value;
return data;
}, {});
return data;
};
var post = function(action, data, callback) {
var request = new XMLHttpRequest();
request.onload = callback;
request.open('post', action);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(data), true);
request.send();
};
var submit = function(e) {
e.preventDefault();
var form = e.target;
var action = form.action;
var data = getFormData(form);
//change the third argument in order to do something
//more intersting with the response than just print it
post(action, data, console.log.bind(console));
}
//change formName below
document.formName.onsubmit = submit;
})();
好的,我知道这个问题已经有了一个高票的答案,但最近又有人问了一个类似的问题,我也被导向这个问题。我也想提供我的解决方案,因为它比公认的解决方案有一个优势:可以包含禁用的表单元素(这有时很重要,取决于UI的功能)
以下是我对另一个SO问题的回答:
最初,我们使用的是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。
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
}, "");
}