I have a JSON object as {a: 1, b: 2, c: [4, 5, 6], d: {x: 7, y: 8, z: [9, 0]}}, how do I convert it to a form of elements?
I want to convert to this:
<input type="hidden" name="obj[a]" value="1"/>
<input type="hidden" name="obj[b]" value="2"/>
<input type="hidden" name="obj[c][]" value="4"/>
<input type="hidden" name="obj[c][]" value="5"/>
<input type="hidden" name="obj[c][]" value="6"/>
<input type="hidden" name="obj[d][x]" value="7"/>
<input type="hidden" name="obj[d][y]" value="8"/>
<input type="hidden" name="obj[d][z][]" value="9"/>
<input type="hidden" name="obj[d][z][]" value="0"/>
Any ideas?
These should do it:
var obj = { a: 1, b: 2, c: [4, 5, 6], d: { x: 7, y: 8, z: [9, 0] } };
function analyzer(o, trail) {
if (!trail) trail = 'obj';
for (var n in o) {
var el = $('<input>', { type: 'hidden' });
el.attr('name', trail + '[' + n + ']');
if (typeof o[n] === 'number') {
el.attr('value', o[n]);
$('body').append(el);
} else if (Array.isArray(o[n])) {
el.attr('name',function(i,v) { return v + '[]'; });
for (var i = 0; i < o[n].length; ++i) {
el.clone().attr('value', o[n][i] ).appendTo('body');
}
} else {
analyzer(o[n], trail + '[' + n + ']');
}
}
}
analyzer(obj);
JSFIDDLE DEMO
FYI, you can find a compatibility patch for Array.isArray at MDN.
Or you can use jQuery.isArray() instead.
You may prefer this a bit. It doesn't create an element, then clone it in the Array loop, but rather uses a little redundant code to create the elements.
function analyzer(o, trail) {
if (!trail) trail = 'obj';
for (var n in o) {
if (typeof o[n] === 'number') {
$('<input>', { type: 'hidden', name: trail + '[' + n + ']', value: o[n] })
.appendTo( 'body' );
} else if (Array.isArray(o[n])) {
for (var i = 0; i < o[n].length; ++i) {
$('<input>', { type: 'hidden', name: trail + '[' + n + '][]', value: o[n][i] })
.appendTo( 'body' );
}
} else {
analyzer(o[n], trail + '[' + n + ']');
}
}
}
JSFIDDLE DEMO
If you're having any performance issues, use the native API, and cache the DOM selection.
function analyzer(o, trail) {
var el;
if (!trail) trail = 'obj';
for (var n in o) {
if (typeof o[n] === 'number') {
el = document.createElement('input');
el.type = 'hidden';
el.name = trail + '[' + n + ']';
el.value = o[n];
container.appendChild( el );
} else if (Array.isArray(o[n])) {
for (var i = 0; i < o[n].length; ++i) {
el = document.createElement('input');
el.type = 'hidden';
el.name = trail + '[' + n + '][]';
el.value = o[n][i];
container.appendChild( el );
}
} else {
analyzer(o[n], trail + '[' + n + ']');
}
}
}
JSFIDDLE DEMO
Doesn't require much more code, should work in all typically supported browsers, and should be very fast.
function analyzer(o, trail) {
var el;
if (!trail) trail = 'obj';
for (var n in o) {
(el = document.createElement('input')).type = 'hidden';
el.name = trail + '[' + n + ']';
if (typeof o[n] === 'number') {
container.appendChild( el ).value = o[n];
} else if (Array.isArray(o[n])) {
el.name += '[]';
for (var i = 0; i < o[n].length; ++i) {
container.appendChild( el.cloneNode(false) ).value = o[n][i];
}
} else {
analyzer(o[n], trail + '[' + n + ']');
}
}
}
JSFIDDLE DEMO
For a quick response -
Create a function that loops through objects. Use a for in loop to create a string to concatonate these inputs. Test if the value found for each object contains a primitive value, array or object`.
E.g.
Object.prototype.toString.call(val) === '[object Object]';
If it does, recursively call the function to extract the values from said found object / array
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With