http://jsfiddle.net/w4Wqh/1/
Honestly I think there's a way to do this in a regex.. but I couldn't figure it out. So, it's a bit of ugly string manipulation. Either way, this should get you on the right track I think:
function serialize () {
var serialized = {};
$("[name]").each(function () {
var name = $(this).attr('name');
var value = $(this).val();
var nameBits = name.split('[');
var previousRef = serialized;
for(var i = 0, l = nameBits.length; i < l; i++) {
var nameBit = nameBits[i].replace(']', '');
if(!previousRef[nameBit]) {
previousRef[nameBit] = {};
}
if(i != nameBits.length - 1) {
previousRef = previousRef[nameBit];
} else if(i == nameBits.length - 1) {
previousRef[nameBit] = value;
}
}
});
return serialized;
}
console.log(serialize());
Quick explanation. This just grabs anything with a 'name' attribute, and then iterates over them. For each iteration, it grabs the name and splits it on '['. This gets you basically how far into the object you need to put things. So, for Person[addresses][work], you would get Person, addresses], work].
Then, there's the tricky part. Since objects are always passed around by reference, we can see if the serialized variable has 'Person' in it. If not, it adds it, and sets the value to an empty object.. which is generic enough to be used for storing more things, or replaced if necessary. If there are no more levels that we need to go through, it just takes the value of the element and assigns it to the reference it has. Otherwise, the code grabs a reference to whatever it just made, and loops again, performing the same operation. So, for Person[addresses][work]..
- Does serialized.Person exist? No. Setting serialized.Person to {}. This is not the end of the loop, store reference to serialized.Person as previousRef.
- Does previousRef.addresses exist? (serialized.Person.addresses) No. Setting previousRef.addresses to {}. This is not the end of the loop, store reference to previousRef.addresses as previousRef.
- Does previousRef.work exist? (serialized.Person.addresses.work) No. Setting previousRef.work to {}. Wait. This is the end of the loop. Setting previousRef.work to the value in the element.