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

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


当前回答

此代码转换并保存输入类型,而不是全部转换为字符串:

jQuery.fn.serializeForm = function () {
    var form = this.get(0);
    var i = [];
    var ret = {};
    for (i = form.elements.length - 1; i >= 0; i = i - 1) {
        if (form.elements[i].name === "") {
            continue;
        }
        var name = form.elements[i].name;
        switch (form.elements[i].nodeName) {
            case 'INPUT':
                switch (form.elements[i].type) {
                    case 'text':
                    case 'tel':
                    case 'email':
                    case 'hidden':
                    case 'password':
                        ret[name] = encodeURIComponent(form.elements[i].value);
                        break;
                    case 'checkbox':
                    case 'radio':
                        ret[name] = form.elements[i].checked;
                        break;
                    case 'number':
                        ret[name] = parseFloat(form.elements[i].value);
                        break;
                }
                break;
            case 'SELECT':
            case 'TEXTAREA':
                ret[name] = encodeURIComponent(form.elements[i].value);
                break;
        }
    }
    return ret;
};

例如,这是输出:

Day: 13
Key: ""
Month: 5
OnlyPayed: true
SearchMode: "0"
Year: 2021

而不是

Day: "13"
Key: ""
Month: "5"
OnlyPayed: "true"
SearchMode: "0"
Year: "2021"

其他回答

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

jQuery中有一个插件jQuery.serializeJSON。我已经在几个项目中成功地使用了它。它就像一个符咒。

我更喜欢这种方法,因为:您不必遍历2个集合,如果需要,您可以获取除“name”和“value”之外的其他内容,并且可以在将值存储在对象中之前对其进行清理(例如,如果您有不希望存储的默认值)。

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

我喜欢塞缪尔的版本,但我相信它有一个小错误。通常JSON发送为

{“coreSKU”:“PCGUYJS”,“name_de”:“whatever”,。。。

不作为

〔{“coreSKU”:“PCGUYJS”},{“name_de”:“whatever”},。。。

因此,功能IMO应为:

App.toJson = function( selector ) {
    var o = {};
    $.map( $( selector ), function( n,i )
    {
        o[n.name] = $(n).val();
    });     
    return o;
}

并将其包装在数据数组中(正如通常预期的那样),最后将其作为跨页发送App.stringify({data:App.toJson(“#cropform:input”)})

对于精简版本,请参见问题3593046,对于所有可能的版本,请参阅json2.js。这应该涵盖了所有内容:)

这种解决方案更好。这里的一些更流行的选项在未选中复选框时不会更正句柄复选框。

getData: function(element){
//@todo may need additional logic for radio buttons
var select = $(element).find('select');
var input = $(element).find('input');
var inputs = $.merge(select,input);
var data = {};
//console.log(input,'input');
$.each(inputs,function(){
  if($(this).attr('type') != undefined){
    switch($(this).attr('type')){
     case 'checkbox':
        data[$(this).attr('name')] = ( ($(this).attr('checked') == 'checked') ? $(this).val():0 );
        break;
      default:
        data[$(this).attr('name')] = $(this).val();
        break;
    }
  } 
  else {
    data[$(this).attr('name')] = $(this).val();
  }
})
  return data;
}