Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have the problem converting HTML input array into Javascript Object.

I have the form:

<form>
    <input name="element[el11][el21]" value="a">
    <input name="element[el11][el22]" value="b">
    <input name="element[el12][el21]" value="c">
    <input name="element[el12][el22]" value="d">
</form>

And i want to have object:

 {
        el11: 
        {
            el21: a
            el22: b
        },
        el22:
        {
            el21: c
            el22: d
        }
 }

Is there any way to simply do this?

share|improve this question

put on hold as off-topic by Quentin, smnbbrv, Web_Designer, Jonathan Argentiero, tomahh 4 hours ago

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – smnbbrv, Jonathan Argentiero, tomahh
If this question can be reworded to fit the rules in the help center, please edit the question.

1  
You maybe can use regex to get the elements names and then lexicographically sort it. Here is the regex I tried: name=".*?\[(.*)\]\[(.*)\]" regex101.com/r/9WgiRj/1 – LeCintas 9 hours ago

You can use Array#reduce method twice to achieve the result.

var res =
  // get all iput elements in the form and convert into array
  // for iterating easily, use [].slice.call() for older browser
  Array.from(document.querySelectorAll('form input'))
  // iterate over the element, you can use forEach with an object defined
  .reduce(function(obj, ele) {
    // cache input value and name
    var val = ele.value,
      name = ele.name;

    // get the content within the square bracket and split 
    name.slice(name.indexOf('[') + 1, name.lastIndexOf(']'))
      .split('][')
      // iterate over the splitted array to generate the nested property  
      .reduce(function(o, k, i, arr) {
        // check current value is last elemnt, then assin the input value as property value
        if (arr.length - 1 == i)
          return o[k] = val;
        // else create a nested object if not defined and return the nested object
        return o[k] = o[k] || {};
        // set initial value as the object
      }, obj)
      // return the object reference
    return obj;
    // set the initial value as an empty object
  }, {});

console.log(res);
<form>
  <input name="element[el11][el21]" value="a">
  <input name="element[el11][el22]" value="b">
  <input name="element[el12][el21]" value="c">
  <input name="element[el12][el22]" value="d">
</form>

share|improve this answer

You can loop over elements and create objects based on values in [...]

var inputs = document.querySelectorAll('input[name^="element"]');
var output = {};
// regex to match `[...]`
const regex = /(?!^|\[)\w+(?=\]|$)/g

// Loop over inputs
for(var i = 0; i< inputs.length; i++){
  // Get name and matching attrs.
  var attr = inputs[i].getAttribute('name').match(regex);
  // Create a temp variable to store value of last refered object.
  var t = output;
  for(var j = 0; j< attr.length; j++){
    // Initialize values
    if(t[attr[j]] === undefined){
      t[attr[j]] = {}
    }
    // If last value, assign value to leaf node
    if(j === attr.length - 1) 
      t[attr[j]] = inputs[i].value;
    // Set temp to point to current node
    else
      t = t[attr[j]]
  }
}

console.log(output)
<form>
  <input name="element[el11][el21]" value="a">
  <input name="element[el11][el22]" value="b">
  <input name="element[el12][el21]" value="c">
  <input name="element[el12][el22]" value="d">
</form>

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.