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

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


当前回答

这将处理具有相同名称的多个select或偶数元素:

$.fn.formToJSON = function(){
    pairStr=this.serialize();
    let rObj={};
    pairStr.split(`&`).forEach((vp)=> {
        prop=vp.split(`=`)[0];
        val=vp.split(`=`)[1];
        if(rObj.hasOwnProperty(prop)) {
            if (Array.isArray(rObj[prop])) {
                rObj[prop].push(val);
            } else {
                rObj[prop]=[rObj[prop]];
                rObj[prop].push(val);
            }
        } else {
            rObj[prop]=val;
        }
    });
    return JSON.stringify(rObj);
}

其他回答

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

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;
}

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

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"

如果使用Undercore.js,可以使用相对简洁的:

_.object(_.map($('#myform').serializeArray(), _.values))

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

当使用具有基于数组的名称的表单时,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等。

创建地图并循环所有字段,保存其值。

var params = {};
$("#form").find("*[name]").each(function(){
    params[this.getAttribute("name")] = this.value;
});