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

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


当前回答

从一些旧的答案来看:

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

其他回答

将任何东西变成对象(未经单元测试)

<script type="text/javascript">
string = {};

string.repeat = function(string, count)
{
    return new Array(count+1).join(string);
}

string.count = function(string)
{
    var count = 0;

    for (var i=1; i<arguments.length; i++)
    {
        var results = string.match(new RegExp(arguments[i], 'g'));
        count += results ? results.length : 0;
    }

    return count;
}

array = {};

array.merge = function(arr1, arr2)
{
    for (var i in arr2)
    {
        if (arr1[i] && typeof arr1[i] == 'object' && typeof arr2[i] == 'object')
            arr1[i] = array.merge(arr1[i], arr2[i]);
        else
            arr1[i] = arr2[i]
    }

    return arr1;
}

array.print = function(obj)
{
    var arr = [];
    $.each(obj, function(key, val) {
        var next = key + ": ";
        next += $.isPlainObject(val) ? array.print(val) : val;
        arr.push( next );
      });

    return "{ " +  arr.join(", ") + " }";
}

node = {};

node.objectify = function(node, params)
{
    if (!params)
        params = {};

    if (!params.selector)
        params.selector = "*";

    if (!params.key)
        params.key = "name";

    if (!params.value)
        params.value = "value";

    var o = {};
    var indexes = {};

    $(node).find(params.selector+"["+params.key+"]").each(function()
    {
        var name = $(this).attr(params.key),
            value = $(this).attr(params.value);

        var obj = $.parseJSON("{"+name.replace(/([^\[]*)/, function()
        {
            return '"'+arguments[1]+'"';
        }).replace(/\[(.*?)\]/gi, function()
        {
            if (arguments[1].length == 0)
            {
                var index = arguments[3].substring(0, arguments[2]);
                indexes[index] = indexes[index] !== undefined ? indexes[index]+1 : 0;

                return ':{"'+indexes[index]+'"';
            }
            else
                return ':{"'+escape(arguments[1])+'"';
        })+':"'+value.replace(/[\\"]/gi, function()
        {
            return "\\"+arguments[0]; 
        })+'"'+string.repeat('}', string.count(name, ']'))+"}");

        o = array.merge(o, obj);
    });

    return o;
}
</script>

测试输出:

$(document).ready(function()
{
    console.log(array.print(node.objectify($("form"), {})));
    console.log(array.print(node.objectify($("form"), {selector: "select"})));
});

on

<form>
    <input name='input[a]' type='text' value='text'/>
    <select name='input[b]'>
        <option>select</option>
    </select>

    <input name='otherinput[c][a]' value='a'/>
    <input name='otherinput[c][]' value='b'/>
    <input name='otherinput[d][b]' value='c'/>
    <input name='otherinput[c][]' value='d'/>

    <input type='hidden' name='anotherinput' value='hidden'/>
    <input type='hidden' name='anotherinput' value='1'/>

    <input type='submit' value='submit'/>
</form>

将产生:

{ input: { a: text, b: select }, otherinput: { c: { a: a, 0: b, 1: d }, d: { b: c } }, anotherinput: 1 }
{ input: { b: select } }
function serializedArray2Object(array){
    let obj = {};
    array.forEach(function(item){
        if(obj[item['name']] === undefined){
            obj[item['name']] = item['value'];
        }else if(Array.isArray(obj[item['name']])){
            obj[item['name']] = [...obj[item['name']],item['value']]
        }else{
            obj[item['name']] = [obj[item['name']],item['value']];
        }
    });
    return obj;
}

使用

serializedArray2Object($('#form').serializeArray())

我刚刚从jQuery中发现了这个函数,并编写了一个到对象的转换器,这样数组就变成了一个对象。

这会把一切都考虑在内

函数formToObject(表单){let data=新FormData(表单);let queryString=新URLSearchParams(data).toString();var obj={};var params=queryString.split(“&”);对于(var i=0;i<params.length;i++){var param=params[i].split(“=”);var key=param[0].replace(“[]”,“”);var key=密钥.替换(“%5B%5 D”,“”);var值=参数[1];if(obj[key]==未定义){obj[key]=值;}else if(数组的obj[key]实例){obj[key].push(值);}其他{obj[key]=[obj[key],值];}}控制台日志(obj)返回obj;}<!DOCTYPE html><html><head><title>表单示例</title></head><body style=“height:800px;溢出:滚动”><form id=“test”onchange=“formToObject(this)”><div><h3>水果</h3><input type=“checkbox”name=“fruit”value=“apple”id=“apple“><label for=“apple”>Apfel</label><input-type=“checkbox”name=“fruit”value=“banana”id=“banana“><label for=“banana”>Banane</label><input type=“checkbox”name=“fruit”value=“cherry”id=“cherr”><label for=“cherry”>Kirsche</label><input type=“checkbox”name=“fruit”value=“葡萄”id=“葡萄”><label for=“葡萄”>Traube</label><input type=“checkbox”name=“fruit”value=“pear”id=“pear“><label for=“pear”>Birne</label></div><div><h3>多个选项</h3><select multiple name=“manyOptions[]”><option value=“选项1”>选项1</option><option value=“option 2”>选项2</option><option value=“选项3”>选项3</option></选择></div><div><h3>检查选项</h3><input type=“radio”name=“onceOption”value=“Option 1”>选项1<br><input type=“radio”name=“onceOption”value=“Option 2”>选项2<br><input type=“radio”name=“onceOption”value=“Option 3”>选项3<br></div></form></body></html>

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

所以我使用了公认的答案,发现了一个主要缺陷。它不支持以下输入数组:

<input type="checkbox" name="array[]" value="1"/>
<input type="checkbox" name="array[]" value="2"/>
<input type="checkbox" name="array[]" value="3"/>

这一小改动应该可以解决以下问题:

function objectifyForm(inp){
    var rObject = {};
    for (var i = 0; i < inp.length; i++){
        if(inp[i]['name'].substr(inp[i]['name'].length - 2) == "[]"){
            var tmp = inp[i]['name'].substr(0, inp[i]['name'].length-2);
            if(Array.isArray(rObject[tmp])){
                rObject[tmp].push(inp[i]['value']);
            } else{
                rObject[tmp] = [];
                rObject[tmp].push(inp[i]['value']);
            }
        } else{
            rObject[inp[i]['name']] = inp[i]['value'];
        }
    }
    return rObject;
}

记住将$(this).serializeArray()的输出传递给它;否则它不会起作用。