使用jQuery将表单数据转换为JavaScript对象

如何将表单的所有元素转换为JavaScript对象?

我希望有一些方法可以自动从表单中构建JavaScript对象,而不必遍历每个元素。我不想要由返回的字符串,$('#formid').serialize();也不希望由返回的映射$('#formid').serializeArray();

Pro逆天猿2020/03/09 20:25:19
const formData = new FormData(form);

let formDataJSON = {};

for (const [key, value] of formData.entries()) {

    formDataJSON[key] = value;
}
小卤蛋Pro2020/03/09 20:25:18

我自己将表单编码为多维JavaScript对象,以在生产中使用它。结果是https://github.com/serbanghita/formToObject.js

布雷西2020/03/09 20:25:18

我更喜欢这种方法,因为:您不必重复两个集合,如果需要,可以使用除“名称”和“值”之外的其他东西,并且可以在将值存储到对象中之前清理它们(例如,如果您有不想存储的默认值)。

$.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中测试过。

Pro小卤蛋2020/03/09 20:25:18

我发现所选解决方案有问题。

当使用具有基于数组名称的表单时,jQuery serializeArray()函数实际上消失了。

我有一个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;
            }
        });

请注意:这也可以在表单commit()之外使用,因此,如果在其余代码中发生错误,则如果您将链接放置在“保存更改”按钮上,则表单将不会提交。

还要注意,永远不要仅使用此函数来验证表单,以收集要发送到服务器端的数据以进行验证。使用此类弱且大量分配的代码将导致XSS等。

小宇宙米亚猿2020/03/09 20:25:18

对于jQuery,有一个插件可以做到这一点jquery.serializeJSON我现在已经在一些项目上成功使用了它。它像一种魅力。

神无JimEva2020/03/09 20:25:18

使用maček的解决方案,我对其进行了修改,使其可以与ASP.NET MVC以相同形式处理其嵌套/复杂对象的方式一起使用。您要做的就是将验证部分修改为:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

这将匹配并正确映射具有以下名称的元素:

<input type="text" name="zooName" />

<input type="text" name="zooAnimals[0].name" />
JinJin猪猪2020/03/09 20:25:18

我发现这个问题的最简单,最准确的方法是使用烧烤插件或这一个(大约是0.5K字节大小)。

它也适用于多维数组。

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};

Pro逆天猿2020/03/09 20:25:18

我发现Tobias Cohen的代码有问题(我没有足够的要点直接对其进行评论),否则对我有用。如果您有两个具有相同名称的选择选项,且都具有value =“”,则原始代码将产生“ name”:“”而不是“ name”:[“”,“”]

我认为可以通过在第一个if条件上添加“ || o [this.name] ==”来解决此问题:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};
HarryL2020/03/09 20:25:18

这里最简单。我已经用一个简单的字符串替换了一个正则表达式,到目前为止,它们的作用就像是一种魅力。我不是正则表达式专家,但我敢打赌,您甚至可以填充非常复杂的对象。

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});
JimHarry2020/03/09 20:25:18

采用:

function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;
}

输出:

{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}
小宇宙猪猪2020/03/09 20:25:18

你可以这样做:

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeArray());

参见JSON

Harry路易2020/03/09 20:25:18

好的,我知道这已经得到了很高的评价,但是最近又提出了另一个类似的问题,我也直接针对这个问题。我也想提供我的解决方案,因为它比公认的解决方案具有优势:您可以包含禁用的表单元素(这有时很重要,具体取决于您的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。

十三Jim2020/03/09 20:25:18

Tobias Cohen解决方案的固定版本。此代码可以正确处理诸如0和的虚假值''

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

还有一个CoffeeScript版本,以方便您进行编码:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData
宝儿Harry2020/03/09 20:25:18

有什么问题:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;});