David Rodrigues
David Rodrigues

Reputation: 12532

Convert complex input names to array

I have some complex input names like: this[is][][a][complex][name] and I need convert it to an array/object. Like:

{ "this": { "is": [ { "a": { "complex": { "name": true } } } ] } }

How can I do that with pure javascript or jquery?

REASON

I need send it with jQuery.ajax() method like:

jQuery.ajax({
    "data": {
        "complex": complex_names,
        "time": Date.now()
     }, ...
});

If I just serialize data like this[is][][a][complex][name]=true, it broke the HTTP request, and sends it like data[this[is][][a][complex][name]] instead of data[this][is][][a][complex][name].

EXAMPLE

I did this example to help you. Well, suppose that I have this:

<input type="text" name="test1" value="ok" />
<input type="text" name="test2" value="ok" />
<input type="text" name="test3[1]" value="ok" />
<input type="text" name="test4[1][2]" value="ok" />
<input type="text" name="test5[]" value="ok" />

If I send it directly via POST, it'll generate a request like:

test1: ok
test2: ok
test3[1]: ok
test4[1][2]: ok
test5[]: ok

But I need send it via jQuery.ajax() method, inside of a array in data option (like complex_data with some other data). The request will be similar to:

call_time: 1612
call_title: test
complex_data[test1]: ok
complex_data[test2]: ok
complex_data[test3][1]: ok
complex_data[test4][1][2]: ok
complex_data[test5][]: ok

Note that my form input will be set inside complex_data object. But if I just convert my data as an array, like:

{
  "test1": "ok",
  "test2": "ok",
  "test3[1]": "ok",
  "test4[1][2]": "ok",
  "test5[]": "ok",
}

And send it to complex_data, it'll request it, instead:

ta). The request will be similar to:

call_time: 1612
call_title: test
complex_data[test1]: ok
complex_data[test2]: ok
complex_data[test3][1]]: ok
complex_data[test4][1][2]]: ok
complex_data[test5][]]: ok

Simplified case like test1 nad test2 will work fine, but complex cases like test3[1] will not be understand and will broke.

WORKAROUND

Currently I'm using a workaround solution that create an array like: this][is][][a][complex and it is included by HTTP request into data[...] what turn to data[this][is][][a][complex][name].

RESEARCH

It's similar to How to convert input name to JavaScript array question, but it is a bit more complex because the deepness is 0 to infinite (generally to level 3). So, I can't make anything unless I use eval (!).

Upvotes: 2

Views: 794

Answers (1)

Andrew Clark
Andrew Clark

Reputation: 208435

Interesting problem, here is what I came up with:

function convert(s) {
    var names = s.replace(/^\w+/, "$&]").replace(/]$/, "").split("][");
    var result = {};
    var obj = result;
    var last;
    for (var i = 0; i < names.length; i++) {
        var name = names[i];
        if (typeof last !== "undefined") {
            obj[last] = name === "" ? [] : {};
            obj = obj[last];
        }
        last = name === "" ? 0 : name;
    }
    obj[last] = true;
    return result;
}

JSFiddle: http://jsfiddle.net/QdRvz/

Upvotes: 2

Related Questions