简体   繁体   中英

Convert a JSON object to nested form fields?

Anyone know of a good way to convert a JSON object to nested form fields.

For example: consider a JSON object:

{'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}}

I should get:

{'a[b][c]':'1200', 'z':'foo', 'bar[baz]':'1', 'bar[id]':2};

Any ideas?

I am currently using jquery and it feels like something like this already exists, if not I can simply roll my own with a crazy algorithm, but I'd rather use something with a proven track record.

So, I have no clue why you want to do what you say you want to do, and I hope you will fill us all in, but this code should be close enough for you to be able to tweak it (this is based on some code of mine that I use to find differences in JavaScript object graphs ):

function doStrangeThing(obj) {
   var propertyChanges = [];
    var objectGraphPath = [];
    (function(obj, refObj) {
        if ( obj.constructor == Object || (obj.constructor != Number &&
             obj.constructor != String && obj.constructor != Date && obj.constructor != Boolean &&
             obj.constructor != RegExp && obj.constructor != Function)) {
            for (var property in obj) {
                objectGraphPath.push((objectGraphPath.length > 0) ? "[" + property + "]" : property);
                if (obj[property].constructor != Function) {
                    if (!refObj[property]) refObj[property] = {};
                    arguments.callee(obj[property], refObj[property]);
                }
                objectGraphPath.pop();
            }
        } else if (obj.constructor != Function) {
            if (obj != refObj) {
                propertyChanges.push("\"" + objectGraphPath.join("") + "\":\"" + obj.toString() + "\"");
            }
        }
    })(obj, {});
    return "{" + propertyChanges.join(",") + "}";
}

Here is what I did to test it:

doStrangeThing({'a':{'b':{'c':'1200'}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}});

Which results in this value:

{"a[b][c]":"1200","z":"foo","bar[baz]":"1","bar[id]":"2"}

Hope that is useful to you in some way...

obj = {'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}}

is internally equivalent to

{['a']['b']['c']:'1200', ['z']:'foo', ['bar']['baz']:'1', ['bar']['id']:2}

Please note that this is not JSON object anymore.

You already can refer first object properties in this way:

var z = obj['a']['b']['c']   // 1200

Is it enough for your needs? Do you really want to convert property names to variables?

I would actually recommend a function that takes a nested JSON object and turns it into a HTTP POST string. jQuery will accept that for all of its arguments that require HTTP parameters.

I have written and used the function below in several production apps (use at your own risk):

$.httpSerialize = function(items, parentName) {
    var serializedItems = [], serialize = arguments.callee, encodeItem =     function(key, value) {
        if (value === null || typeof value == 'undefined') return value;
        if (value.constructor == Array) {return serialize(value, key);}
        return (value.constructor == Object)
            ? serialize(value, key)
            : (value === true || value === false)
                ? key+"="+new Number(value)
                : key+"="+encodeURIComponent(value);
    };

    if (items.constructor == Array) {
        parentName = parentName || 'item';
        for (var i = 0; i < items.length; i++) {
            var key = parentName+'['+i+']', value = items[i];
            serializedItems.push(encodeItem(key, value));
        }
    } else {
        parentName = parentName || '';
        for (var key in items) {
            var value = items[key];
            if (parentName) {
                serializedItems.push(encodeItem(parentName+'['+encodeURIComponent(key)+']', value));
            } else {
                serializedItems.push(encodeItem(encodeURIComponent(key), value));
            }
        }
    }
    return serializedItems.join("&");
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM