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
    
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 25 mins 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. Not filter `""` out.
  var attr = inputs[i].getAttribute('name').match(regex).filter(x=>x);
  // 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

Use JSON.parse('{}'); to convert the array to an object.

PS: your array format needs to be corrected before using JSON.parse()

share|improve this answer
    
Please read question properly of what OP is asking. You can also refer other answers for more clarity – Rajesh 9 mins ago
    
I can't see how JSON.parse can be used to change an array of DOM nodes or a NodeList directly to an object without additional parsing. This answer doesn't solve the question asked. – Brian 8 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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