I've been searching for hours for this and haven't found an answer. Please read through the whole question before flaming! :)
I have a form similar to this:
<form id="sample">
<input name="name" type="text" value="name value" />
<input name="phone[0][type]" type="text" value="cell" />
<input name="phone[0][number]" type="text" value="000" />
<input name="phone[1][type]" type="text" value="home" />
<input name="phone[1][number]" type="text" value="111" />
</form>
And need to开发者_运维知识库 be able to serialize it to this:
{
name: 'name value',
phone: [
{
type: 'cell',
number: '000'
},
{
type: 'home',
number: '111'
}
]
}
I have tried most answers on SO including jquery-json libraries and most of them return something like this:
{
'name': 'name value',
'phone[0][type]': 'cell',
'phone[0][number]': '000',
'phone[1][type]': 'home',
'phone[1][number]': '111',
}
This is something I cannot use! :P
Thanks everyone in advance.
Try this code I wrote for you... Works fine for me, just using your data result. You can work on it and make a simple jQuery plugin...
The sample need JSON.stringify to work fully.
var d = {
'name': 'name value',
'phone[0][type]': 'cell',
'phone[0][number]': '000',
'phone[1][type]': 'home',
'phone[1][number]': '111',
};
$(document).ready(function(){
arrangeJson(d);
alert(JSON.stringify(d));
});
function arrangeJson(data){
var initMatch = /^([a-z0-9]+?)\[/i;
var first = /^\[[a-z0-9]+?\]/i;
var isNumber = /^[0-9]$/;
var bracers = /[\[\]]/g;
var splitter = /\]\[|\[|\]/g;
for(var key in data) {
if(initMatch.test(key)){
data[key.replace(initMatch,'[$1][')] = data[key];
}
else{
data[key.replace(/^(.+)$/,'[$1]')] = data[key];
}
delete data[key];
}
for (var key in data) {
processExpression(data, key, data[key]);
delete data[key];
}
function processExpression(dataNode, key, value){
var e = key.split(splitter);
if(e){
var e2 =[];
for (var i = 0; i < e.length; i++) {
if(e[i]!==''){e2.push(e[i]);}
}
e = e2;
if(e.length > 1){
var x = e[0];
var target = dataNode[x];
if(!target){
if(isNumber.test(e[1])){
dataNode[x] = [];
}
else{
dataNode[x] ={}
}
}
processExpression(dataNode[x], key.replace(first,''), value);
}
else if(e.length == 1){
dataNode[e[0]] = value;
}
else{
alert('This should not happen...');
}
}
}
}
There is also the following library
http://code.google.com/p/form2js/
This worked very well for me. This doesn't need to have the form2js library.
$.fn.serializeObject = function serializeObject() {
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;
};
To serialise the form data I used this code then.
JSON.stringify($(this).serializeObject());//'this' points to the form
If you have any doubts please feel free to add comment.
With this structure, I don't think any JSON library can do all the work. So, I think that is more easy to write our own conversion loop.
Here is the code to your serialization: http://jsfiddle.net/7MAUv/1/
The logic is pretty simple, the secret is the eval
to run Strings like dynamic commands.
I tried to make it as easier as possible, almost all lines are commented.
BTW, feels free to make questions.
Its not exactly what you asked for, but if you are using jQuery library and need your complex form serialized for a purpose of sending it in ajax, you can use sth like this
ajaxRunning = $.ajax(
"?"+$('#yourForm').serialize(),
{
data: {
anotherData: 'worksFine',
etc: 'still works'
},
success: function(result) {
doSth();
},
dataType: "json"
});
you can use in $.post and $.get as well
nJoy!
Another library that solves this issue is jquery.serializeJSON by Mario Izquierdo. It works and extends jQuery.
精彩评论