Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I from a JSON object convert to form of elements?

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?

like image 361
Jasper Avatar asked Jan 01 '26 05:01

Jasper


2 Answers

These should do it:

with jQuery

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.


jQuery reworked

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


with native DOM API

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.


native API reworked to shorten

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

like image 77
RightSaidFred Avatar answered Jan 03 '26 09:01

RightSaidFred


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

like image 45
Trevor Avatar answered Jan 03 '26 08:01

Trevor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!