如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
像boss一样将表单转换为JSON
目前的来源是GitHub和Bower。
$bower安装jquery序列化对象
以下代码现已弃用。
以下代码可以处理所有类型的输入名称;按照你的预期处理它们。
例如:
<!-- All of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// Output
{
"honey":{
"badger":"a"
},
"wombat":["b"],
"hello":{
"panda":["c"]
},
"animals":[
{
"name":"d",
"breed":"e"
}
],
"crazy":[
null,
[
{"wonky":"f"}
]
],
"dream":{
"as":{
"vividly":{
"as":{
"you":{
"can":"g"
}
}
}
}
}
}
用法
$('#my-form').serializeObject();
魔法(JavaScript)
(function($){
$.fn.serializeObject = function(){
var self = this,
json = {},
push_counters = {},
patterns = {
"validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
"key": /[a-zA-Z0-9_]+|(?=\[\])/g,
"push": /^$/,
"fixed": /^\d+$/,
"named": /^[a-zA-Z0-9_]+$/
};
this.build = function(base, key, value){
base[key] = value;
return base;
};
this.push_counter = function(key){
if(push_counters[key] === undefined){
push_counters[key] = 0;
}
return push_counters[key]++;
};
$.each($(this).serializeArray(), function(){
// Skip invalid keys
if(!patterns.validate.test(this.name)){
return;
}
var k,
keys = this.name.match(patterns.key),
merge = this.value,
reverse_key = this.name;
while((k = keys.pop()) !== undefined){
// Adjust reverse_key
reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
// Push
if(k.match(patterns.push)){
merge = self.build([], self.push_counter(reverse_key), merge);
}
// Fixed
else if(k.match(patterns.fixed)){
merge = self.build([], k, merge);
}
// Named
else if(k.match(patterns.named)){
merge = self.build({}, k, merge);
}
}
json = $.extend(true, json, merge);
});
return json;
};
})(jQuery);
其他回答
这是一个使用reduce的单行。Reduce是一个函数函数,它获取传递函数的返回值,并在下一次迭代中将其与列表中的第n个值一起传递回传递函数。
$('#formid').serializeArray().reduce((o,p) => ({...o, [p.name]: p.value}))
我们必须使用一些技巧来实现这一点:
…o(扩展语法)插入o中的所有键:值对包装我们在()中返回的对象,以将其与表示函数的{}区分开来将密钥(p.name)换行为[]
这里最简单。我用一个简单的字符串替换了一个正则表达式,到目前为止,它们就像一个符咒。我不是正则表达式专家,但我打赌您甚至可以填充非常复杂的对象。
var values = $(this).serialize(),
attributes = {};
values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
attributes[name] = value;
});
我检查了所有其他答案是否存在问题,如果输入名称是数组,例如name[key],那么应该这样生成:
名称:{key:value}
例如:如果您的HTML表单与下面的表单类似:
<form>
<input name="name" value="value" >
<input name="name1[key1]" value="value1" >
<input name="name2[key2]" value="value2" >
<input name="name3[key3]" value="value3" >
</form>
但是它应该像下面的JSON一样生成,而不是像下面这样的对象和所有其他答案。因此,如果有人想带来类似以下JSON的内容,请尝试下面的JS代码。
{
name : 'value',
name1 : { key1 : 'value1' },
name2 : { key2 : 'value2' },
name3 : { key2 : 'value2' }
}
$.fn.getForm2obj=函数(){var_={};$.map(this.serializeArray(),函数(n){常量键=n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g);如果(按键长度>1){让tmp=_;pop=keys.pop();for(设i=0;i<keys.length,j=keys[i];i++){tmp[j]=(!tmp[j]?(pop=='')?[]:{}:tmp[j]),tmp=tmp[j];}如果(pop=='')tmp=(!Array.isArray(tmp)?[]:tmp)、tmp.push(n.value);否则tmp[pop]=n.value;}else_[keys.pop()]=n.value;});返回_;}console.log($('form').getForm2obj());$('form input').change(函数(){console.clear();console.log($('form').getForm2obj());});<script src=“https://code.jquery.com/jquery-3.2.1.min.js“></script><表单><input name=“name”value=“value”><input type=“checkbox”name=“name1[]”value=“1”checked=“checked”>1<input type=“checkbox”name=“name1[]”value=“2”>2<input-type=“checkbox”name=“name1[]”value=“3”>3<br><input-type=“radio”name=“gender”value=“male”checked=“checked”>男性<input-type=“radio”name=“gender”value=“female”>女性<input name=“name2[key1]”value=“value1”><input name=“一个[另一个][另一个]”value=“value4”><input name=“name3[1][name]”value=“value4”><input name=“name3[2][name]”value=“value4”><input name=“[]”value=“value5”></form>
在不检查每个元素的情况下,确实无法做到这一点。您真正想知道的是“是否有其他人已经编写了一个将表单转换为JSON对象的方法?”类似于下面的内容应该可以工作——请注意,它只会为您提供通过POST返回的表单元素(必须有名称)。这是未测试的。
function formToJSON( selector )
{
var form = {};
$(selector).find(':input[name]:enabled').each( function() {
var self = $(this);
var name = self.attr('name');
if (form[name]) {
form[name] = form[name] + ',' + self.val();
}
else {
form[name] = self.val();
}
});
return form;
}
我喜欢使用Array.prototype.reduce,因为它是一个单行程序,并且不依赖Undercore.js或类似工具:
$('#formid').serializeArray()
.reduce(function(a, x) { a[x.name] = x.value; return a; }, {});
这与使用Array.prototype.map的答案类似,但不需要使用额外的对象变量来扰乱作用域。一站式购物。
重要提示:输入具有重复名称属性的表单是有效的HTML,实际上是一种常见的方法。在这种情况下,使用此线程中的任何答案都是不合适的(因为对象键必须是唯一的)。