如何将表单的所有元素转换为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;
}

其他回答

serialize函数将JSON对象作为参数并返回serialize String。

function serialize(object) {
            var _SPECIAL_CHARS = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, _CHARS = {
                '\b' : '\\b',
                '\t' : '\\t',
                '\n' : '\\n',
                '\f' : '\\f',
                '\r' : '\\r',
                '"' : '\\"',
                '\\' : '\\\\'
            }, EMPTY = '', OPEN_O = '{', CLOSE_O = '}', OPEN_A = '[', CLOSE_A = ']', COMMA = ',', COMMA_CR = ",\n", CR = "\n", COLON = ':', space = "", COLON_SP = ': ', stack = [], QUOTE = '"';
            function _char(c) {
                if (!_CHARS[c]) {
                    _CHARS[c] = '\\u' + ('0000' + (+(c.charCodeAt(0))).toString(16))
                        .slice(-4);
                }
                return _CHARS[c];
            }
            function _string(s) {
                return QUOTE + s.replace(_SPECIAL_CHARS, _char) + QUOTE;
                // return str.replace('\"','').replace('\"','');
            }

            function serialize(h, key) {
                var value = h[key], a = [], colon = ":", arr, i, keys, t, k, v;
                arr = value instanceof Array;
                stack.push(value);
                keys = value;
                i = 0;
                t = typeof value;
                switch (t) {
                    case "object" :
                        if(value==null){
                            return null;
                        }
                        break;
                    case "string" :
                        return _string(value);
                    case "number" :
                        return isFinite(value) ? value + EMPTY : NULL;
                    case "boolean" :
                        return value + EMPTY;
                    case "null" :
                        return null;
                    default :
                        return undefined;
                }
                arr = value.length === undefined ? false : true;

                if (arr) { // Array
                    for (i = value.length - 1; i >= 0; --i) {
                        a[i] = serialize(value, i) || NULL;
                    }
                }
                else { // Object
                    i = 0;
                    for (k in keys) {
                        if (keys.hasOwnProperty(k)) {
                            v = serialize(value, k);
                            if (v) {
                                a[i++] = _string(k) + colon + v;
                            }
                        }
                    }
                }

                stack.pop();
                if (space && a.length) {

                    return arr
                        ? "[" + _indent(a.join(COMMA_CR), space) + "\n]"
                        : "{\n" + _indent(a.join(COMMA_CR), space) + "\n}";
                }
                else {
                    return arr ? "[" + a.join(COMMA) + "]" : "{" + a.join(COMMA)
                        + "}";
                }
            }
            return serialize({
                "" : object
            }, "");
        }

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

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

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});

由于XSS攻击和可能存在的其他问题,我不会在现场网站上使用此功能,但下面是一个快速示例:

$("#myform").submit(function(){
    var arr = $(this).serializeArray();
    var json = "";
    jQuery.each(arr, function(){
        jQuery.each(this, function(i, val){
            if (i=="name") {
                json += '"' + val + '":';
            } else if (i=="value") {
                json += '"' + val.replace(/"/g, '\\"') + '",';
            }
        });
    });
    json = "{" + json.substring(0, json.length - 1) + "}";
    // do something with json
    return false;
});

此函数返回转换为正确类型的所有值;

bool/string/(integer/floats)可能

虽然您需要jQuery来实现这一点,但由于serializeArray也是jQuery,所以没什么大不了的。

/**
 * serialized a form to a json object
 *
 * @usage: $("#myform").jsonSerialize();
 *
 */

(function($) {
    "use strict";
    $.fn.jsonSerialize = function() {
        var json = {};
        var array = $(this).serializeArray();
        $.each(array, function(key, obj) {
            var value = (obj.value == "") ? false : obj.value;
            if(value) {
                // check if we have a number
                var isNum = /^\d+$/.test(value);
                if(isNum) value = parseFloat(value);
                // check if we have a boolean
                var isBool = /^(false|true)+$/.test(value);
                if(isBool) value = (value!=="false");
            }
            json[obj.name] = value;
        });
        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?)});