Q:

Serializing form with nested paths and arrays to JSON in javascript

A similar question is addressed here: Convert form data to JavaScript object with jQuery with the following solution:
$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        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 || '';
        }
    });
    return o;
};

However that doesn't work when you want to have JSON with nested objects.  For instance, for this form:
Employee name:      <input type="text" id="employee" name="name"/>
Department name:    <input type="text" id="department" name="department.name"/>
Department chief1:  <input type="text" id="chief1" name="department.chief[0]"/>
Department chief2:  <input type="text" id="chief2" name="department.chief[1]"/>

I am getting: {"name":"John","department.name":"IT" , "department.chief[0]":"Mike" "department.chief[1]":"Lucas"}
but what I do need is {"name":"John","department" : {"name":"IT"}, "chief" : [ "Mike", "Lucas" }
Is there any adaptation of serializeObject that does it this way? 
To provide some background: I need this because I am submitting an AJAX call to a Spring MVC controller and Jackson expects that format to create the nested objects. 

A:

This is my modified version of serializeObject supporting both nested objects and arrays:
$.fn.serializeObject = function() {
    var arrayData, objectData;
    arrayData = this.serializeArray();
    objectData = {};

    $.each(arrayData, function() {
        this.value = ! this.value ? '' :  this.value;
        processObject(objectData, this.name, this.value);
    });

    return objectData;
};

function processObject(obj, key, value){
    if(key.indexOf('.') ! = -1) {
        var attrs = key.split('.'); 
        var tx = obj;
        for (var i = 0; i < attrs.length - 1; i++) {
            var isArray = attrs[i].indexOf('[') ! = -1;
            var isNestedArray = isArray && (i ! = attrs.length-1);
            var nestedArrayIndex = null;
            if(isArray){
                nestedArrayIndex = attrs[i].substring(attrs[i].indexOf('[') +1 , attrs[i].indexOf(']'));
                attrs[i] = attrs[i].substring(0, attrs[i].indexOf('['));
                if (tx[attrs[i]] == undefined){ 
                    tx[attrs[i]] = [];
                }
                tx = tx[attrs[i]];
                if(isNestedArray){
                    if(tx[nestedArrayIndex] == undefined){
                        tx[nestedArrayIndex] = {};
                    }
                    tx = tx[nestedArrayIndex];
                }

            }else{
                if (tx[attrs[i]] == undefined){ 
                    tx[attrs[i]] = {};
                }
                tx = tx[attrs[i]];
            }               
        }
        processObject(tx, attrs[attrs.length - 1], value);
    }else{
        var finalArrayIndex = null;
        if(key.indexOf('[') ! = -1){
            finalArrayIndex = key.substring(key.indexOf('[') +1 , key.indexOf(']'));
            key = key.substring(0, key.indexOf('['));               
        }
        if(finalArrayIndex == null){
            obj[key] = value;
        }else{
            if(obj[key] == undefined){
                obj[key] = [];
            }
            obj[key][finalArrayIndex] = value;
        }           
    }       
}

