For this example, assume that I have a list of months in a form, each with a checkbox next to them. I\'m looking for help on doing either of two things:
You can try this
String.prototype.QueryStringToJSON = function () {
href = this;
qStr = href.replace(/(.*?\?)/, '');
qArr = qStr.split('&');
stack = {};
for (var i in qArr) {
var a = qArr[i].split('=');
var name = a[0],
value = isNaN(a[1]) ? a[1] : parseFloat(a[1]);
if (name.match(/(.*?)\[(.*?)]/)) {
name = RegExp.$1;
name2 = RegExp.$2;
//alert(RegExp.$2)
if (name2) {
if (!(name in stack)) {
stack[name] = {};
}
stack[name][name2] = value;
} else {
if (!(name in stack)) {
stack[name] = [];
}
stack[name].push(value);
}
} else {
stack[name] = value;
}
}
return stack;
}
Query String
href="j.html?name=nayan&age=29&salary=20000&interest[]=php&interest[]=jquery&interest[1]=python&interest[2]=Csharp&fan[friend]=rangan&fan[family]=sujan&sports[1]=cricket&sports[2]=football";
usage
alert(href.QueryStringToJSON().toSource())
output
({name:"nayan", age:29, salary:20000, interest:["php", "python", "Csharp"], fan:{friend:"rangan", family:"sujan"}, sports:{1:"cricket", 2:"football"}})
You can traverse an object map using the $.each utility function.
$(function() {
map = [{ January: 'on' },{ March: 'on' },{ September: 'on' }];
$.each(map, function() {
$.each(this, function(key, val) {alert(key + " = " + val);});;
});
});
The first each gets you all array objects. With the second one you can get the key and value of your object.
kgiannakakis's suggestion to traverse the map was a good starting point, though I don't feel that it qualifies as an answer to my original question. After a couple of hours of head banging, I settled for this, which allows you to serialize elements based on a custom attribute (I didn't want to settle for having to use the 'name' attribute on my form elements, which jQuery requires). I have also started using the JSON library from json.org in order to stringify the object I create. The serializeToJSON function of my plugin is what I was looking for as an answer to my question, the rest is just exta.
Note: This is for a client, so the 'CustomXXX' names and attributes were substituted in for what they actually are
jQuery.fn.extend({
serializeCustomPropertyArray: function() {
return this.map(function() {
return this.elements ? jQuery.makeArray(this.elements) : this;
}).filter(function() {
return jQuery(this).attr('CustomAttribute') &&
(this.checked || /select|textarea/i.test(this.nodeName) ||
/text|hidden|password|search/i.test(this.type));
}).map(function(i, elem) {
var val = jQuery(this).val();
return val == null ? null : jQuery.isArray(val) ?
jQuery.map(val, function(val, i) {
return { name: jQuery(elem).attr('CustomAttribute'), value: val };
}) : { name: jQuery(elem).attr('CustomAttribute'), value: val };
}).get();
},
serializeToJSON: function() {
var objectMap = this.serializeCustomPropertyArray();
var objectJson = new Object;
jQuery.each(objectMap, function() {
objectJson[this.name] = (this.value !== null) ? this.value : 'null';
});
return JSON.stringify(objectJson);
}
});
This can be called like:
$('#fields').find(':input[CustomGroup="Months"]').serializeToJSON();
Assuming your document looks something like:
<div id="fields">
<input type="checkbox" CustomGroup="Months" CustomAttribute="January" />January<br />
<input type="checkbox" CustomGroup="Months" CustomAttribute="February" />February<br />
...
</div>
The JSON that's built looks like:
{ January: 'on', February: 'on', ... }
I know you're trying to turn a query-string into a JSON object, but perhaps you might be interested in going directly from an html form to a JSON object (without having to specify really convoluted name attributes). If so, check out JSONForms: http://code.google.com/p/jsonf/
Disclaimer: I started the jsonforms project. It's still young, but personally I think it rocks!
You can also use the parseQuery plugin to create an object from the serialized elements.
var contact = $.parseQuery($("#step1 *").serialize());