如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
我编写了一个jQuery模块jsForm,即使对于非常复杂的表单(也允许集合和其他更复杂的结构),它也可以实现这种双向。
它使用字段的名称(加上一些用于集合的特殊类)并匹配JSON对象。它允许自动复制用于收集和数据处理的DOM元素:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://raw.github.com/corinis/jsForm/master/src/jquery.jsForm.js"></script>
<script>
$(function(){
// Some JSON data
var jsonData = {
name: "TestName", // Standard inputs
description: "long Description\nMultiline", // Textarea
links: [{href:'http://stackoverflow.com',description:'StackOverflow'}, {href:'http://www.github.com', description:'GitHub'}], // Lists
active: true, // Checkbox
state: "VISIBLE" // Selects (enums)
};
// Initialize the form, prefix is optional and defaults to data
$("#details").jsForm({
data:jsonData
});
$("#show").click(function() {
// Show the JSON data
alert(JSON.stringify($("#details").jsForm("get"), null, " "));
});
});
</script>
</head>
<body>
<h1>Simpel Form Test</h1>
<div id="details">
Name: <input name="data.name"/><br/>
<input type="checkbox" name="data.active"/> active<br/>
<textarea name="data.description"></textarea><br/>
<select name="data.state">
<option value="VISIBLE">visible</option>
<option value="IMPORTANT">important</option>
<option value="HIDDEN">hidden</option>
</select>
<fieldset>
<legend>Links</legend>
<ul class="collection" data-field="data.links">
<li><span class="field">links.description</span> Link: <input name="links.href"/> <button class="delete">x</button></li>
</ul>
</fieldset>
<button class="add" data-field="data.links">add a link</button><br/>
Additional field: <input name="data.addedField"/>
</div>
<button id="show">Show Object</button>
</body>
</html>
其他回答
serializeArray已经做到了这一点。您只需将数据转换为所需格式:
function objectifyForm(formArray) {
//serialize data function
var returnArray = {};
for (var i = 0; i < formArray.length; i++){
returnArray[formArray[i]['name']] = formArray[i]['value'];
}
return returnArray;
}
注意与实际输入同名的隐藏字段,因为它们会被覆盖。
const formData = new FormData(form);
let formDataJSON = {};
for (const [key, value] of formData.entries()) {
formDataJSON[key] = value;
}
在一个内衬中充分利用ES6的优点:
$("form").serializeArray().reduce((o, {name: n, value: v}) => Object.assign(o, { [n]: v }), {});
从一些旧的答案来看:
$('form input, form select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})
这是对Tobias Cohen函数的改进,该函数在多维数组中运行良好:
http://jsfiddle.net/BNnwF/2/
然而,这不是一个jQuery插件,但如果您想这样使用它,只需几秒钟就可以将它变成一个:只需替换函数声明包装器:
function serializeFormObject(form)
{
...
}
具有:
$.fn.serializeFormObject = function()
{
var form = this;
...
};
我想这与梅斯克的解决方案相似,因为它做了相同的事情,但我认为这有点干净和简单。我还将macek的测试用例输入添加到小提琴中,并添加了一些额外的输入。到目前为止,这对我来说很好。
function serializeFormObject(form)
{
function trim(str)
{
return str.replace(/^\s+|\s+$/g,"");
}
var o = {};
var a = $(form).serializeArray();
$.each(a, function() {
var nameParts = this.name.split('[');
if (nameParts.length == 1) {
// New value is not an array - so we simply add the new
// value to the result object
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
}
else {
// New value is an array - we need to merge it into the
// existing result object
$.each(nameParts, function (index) {
nameParts[index] = this.replace(/\]$/, '');
});
// This $.each merges the new value in, part by part
var arrItem = this;
var temp = o;
$.each(nameParts, function (index) {
var next;
var nextNamePart;
if (index >= nameParts.length - 1)
next = arrItem.value || '';
else {
nextNamePart = nameParts[index + 1];
if (trim(this) != '' && temp[this] !== undefined)
next = temp[this];
else {
if (trim(nextNamePart) == '')
next = [];
else
next = {};
}
}
if (trim(this) == '') {
temp.push(next);
} else
temp[this] = next;
temp = next;
});
}
});
return o;
}