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

我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;


当前回答

这是对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;
}

其他回答

此函数应处理多维数组以及多个同名元素。

到目前为止,我已经使用了几年:

jQuery.fn.serializeJSON=function() {
  var json = {};
  jQuery.map(jQuery(this).serializeArray(), function(n, i) {
    var _ = n.name.indexOf('[');
    if (_ > -1) {
      var o = json;
      _name = n.name.replace(/\]/gi, '').split('[');
      for (var i=0, len=_name.length; i<len; i++) {
        if (i == len-1) {
          if (o[_name[i]]) {
            if (typeof o[_name[i]] == 'string') {
              o[_name[i]] = [o[_name[i]]];
            }
            o[_name[i]].push(n.value);
          }
          else o[_name[i]] = n.value || '';
        }
        else o = o[_name[i]] = o[_name[i]] || {};
      }
    }
    else {
      if (json[n.name] !== undefined) {
        if (!json[n.name].push) {
          json[n.name] = [json[n.name]];
        }
        json[n.name].push(n.value || '');
      }
      else json[n.name] = n.value || '';      
    }
  });
  return json;
};

一行(除了jQuery之外没有依赖项)使用传递给map方法的函数的固定对象绑定。

$('form').serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]

它做什么?

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

适用于渐进式web应用程序(可以轻松支持常规表单提交操作和ajax请求)

从一些旧的答案来看:

$('form input, form select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})

像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);

所有这些答案对我来说似乎都太过头了。为了简单起见,有些话要说。只要您的所有表单输入都设置了name属性,这应该只适用于jimdandy。

$('form.myform').submit(函数(){var$this=$(this),viewArr=$this.serializeArray(),视图={};for(viewArr中的var i){view[viewArr[i].name]=viewArr[i].value;}//在这里使用视图对象(例如JSON.stringify?)});