如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
如果要发送带有JSON的表单,则必须在发送字符串时删除[]。您可以使用jQuery函数serializeObject()实现这一点:
var frm = $(document.myform);
var data = JSON.stringify(frm.serializeObject());
$.fn.serializeObject = function() {
var o = {};
//var a = this.serializeArray();
$(this).find('input[type="hidden"], input[type="text"], input[type="password"], input[type="checkbox"]:checked, input[type="radio"]:checked, select').each(function() {
if ($(this).attr('type') == 'hidden') { //If checkbox is checked do not take the hidden field
var $parent = $(this).parent();
var $chb = $parent.find('input[type="checkbox"][name="' + this.name.replace(/\[/g, '\[').replace(/\]/g, '\]') + '"]');
if ($chb != null) {
if ($chb.prop('checked')) return;
}
}
if (this.name === null || this.name === undefined || this.name === '')
return;
var elemValue = null;
if ($(this).is('select'))
elemValue = $(this).find('option:selected').val();
else
elemValue = this.value;
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(elemValue || '');
}
else {
o[this.name] = elemValue || '';
}
});
return o;
}
其他回答
我发现所选解决方案有问题。
当使用具有基于数组的名称的表单时,jQueryserializeArray()函数实际上会失效。
我有一个PHP框架,它使用基于数组的字段名,允许在多个视图中将同一表单多次放在同一页面上。这可以方便地将添加、编辑和删除都放在同一页上,而不会出现表单模型冲突。
由于我想在不使用这种绝对基本功能的情况下对表单进行序列化,我决定编写自己的seralizeArray():
var $vals = {};
$("#video_edit_form input").each(function(i){
var name = $(this).attr("name").replace(/editSingleForm\[/i, '');
name = name.replace(/\]/i, '');
switch($(this).attr("type")){
case "text":
$vals[name] = $(this).val();
break;
case "checkbox":
if($(this).attr("checked")){
$vals[name] = $(this).val();
}
break;
case "radio":
if($(this).attr("checked")){
$vals[name] = $(this).val();
}
break;
default:
break;
}
});
请注意:这也适用于表单submit()之外,因此如果在代码的其余部分发生错误,如果您单击“保存更改”的链接按钮,表单将不会提交。
还请注意,此函数不应仅用于验证表单以收集要发送到服务器端进行验证的数据。使用这种弱的和大量分配的代码将导致XSS等。
对于这个问题,我找到的最简单、最准确的方法是使用bbq插件或这个插件(大约0.5K字节大小)。
它也适用于多维阵列。
$.fn.serializeObject=函数(){return$.departam(this.serialize());};
这使用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
);
这是一个使用reduce的单行。Reduce是一个函数函数,它获取传递函数的返回值,并在下一次迭代中将其与列表中的第n个值一起传递回传递函数。
$('#formid').serializeArray().reduce((o,p) => ({...o, [p.name]: p.value}))
我们必须使用一些技巧来实现这一点:
…o(扩展语法)插入o中的所有键:值对包装我们在()中返回的对象,以将其与表示函数的{}区分开来将密钥(p.name)换行为[]
好的,我知道这个问题已经有了一个高票的答案,但最近又有人问了一个类似的问题,我也被导向这个问题。我也想提供我的解决方案,因为它比公认的解决方案有一个优势:可以包含禁用的表单元素(这有时很重要,取决于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。