Frederick M. Rogers
Frederick M. Rogers

Reputation: 921

JavaScript - Iterate over form inputs and collect values as key value pairs in object

I am trying to collect values from a number of input fields in a form by iterating of the inputs and then storing them as key/value pairs in a array of objects. However i am struggling to find an efficient way of doing this that does not involve a long set if if else or switch statement.

Concept:

<form>
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
</form>

What i would like to avoid:

var inputs = document.querySelectorAll('input');    

for (var i = 0; i < inputs.length; i++) {
  var myObject = {};

  if (i = 0) {
    myObject.val0 = inputs[i];
  } else if (i = 1) {
    myObject.val1 = inputs[i];
  } else if (i = 2) {
    myObject.val2 = inputs[i];
  } else if (i = 3) {
    myObject.val3 = inputs[i];
  } 

}

Any suggestions on how this may be done more efficiently? One idea i have is using bracket notation to dynamically set the key values based on a existing html element attribute maybe id, name or a custom data attribute.

Upvotes: 3

Views: 9440

Answers (9)

DataCure
DataCure

Reputation: 425

Summary It appears you want to populate an array of values This should answer your question if I understood it right

var inputs = document.getElementsByTagName('input'),
    object = [];

function setValues() {
    for (var i = 0; i < inputs.length; i++) {
        object.push("val" + i + ": " + inputs[i].value );
    }
    console.log(object);
}

document.addEventListener("DOMContentLoaded", setValues(), false);
<form onchange="setValues()">
  <input type="text" value="test">
  <input type="text"  value="test22">
  <input type="text"  value="test333">
  <input type="text" value="test444">
</form>

Upvotes: 1

bmceldowney
bmceldowney

Reputation: 2305

This is specifically what the Array.reduce() function was made for:

document.querySelector('button').addEventListener('click', function(e) {
  var inputs = document.querySelectorAll('input');    

  var obj = [].reduce.call(inputs, (accumulator, currentValue, currentIndex) => {
    accumulator[`val${currentIndex}`] = currentValue.value
    return accumulator
  }, {})
  
  console.log(obj)
});
<form>
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <button>Go</button>
</form>

Upvotes: 0

trincot
trincot

Reputation: 350715

You can do it in one expression:

var myObject = Object.assign(...
    Array.from(document.getElementsByTagName('input'), (inp, i) => ({ ['val'+i]: inp }))
);

If you want the values from the inputs (as you say in the text), then you need inp.value instead of inp at the right side of the expression, or with destructuring assingment:

var myObject = Object.assign(...Array.from(
    document.getElementsByTagName('input'), ({value}, i) => ({ ['val'+i]: value })
));

console.log(myObject);
<input value="hello">
<input value="world">

Upvotes: 1

Alejandro G.
Alejandro G.

Reputation: 69

Loop throught the input fields. Something like this maybe:

    let inputList = document.getElementsByTagName('input');
    let val = 'val';

    for (let x in inputList){
       let name = val + x;
       myObj.`${name}`= inputList[x].value;
       number++;
    }

Just one of many options.

Upvotes: 1

Ele
Ele

Reputation: 33726

Loop over your elements and dynamically use the index:

a[`val${i}`] = e.value;

document.querySelector('button').addEventListener('click', function(e) {
  e.preventDefault();
  
  var inputs   = document.querySelectorAll('input'),
      myObject = Array.from(inputs).reduce(function(a, e, i) {
                    a[`val${i}`] = e.value;
                    return a;
                 }, {});
                 
  console.log(myObject)
});
<form>
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <button>Click me!</button>
</form>

Upvotes: 1

Cisco
Cisco

Reputation: 23042

I would write like so using Array.prototype.forEach():

const inputs = document.querySelectorAll('input')
const myObject = {}

inputs.forEach((element, index) => myObject[`val${index}`] = element)

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386670

You could use bracket notation as property accessor for the object and getElementsByTagName for getting the input elements.

var inputs = document.getElementsByTagName('input'),
    object = {};

function setValues() {
    for (var i = 0; i < inputs.length; i++) {
        object['val' + i] = inputs[i].value;
    }
    console.log(object);
}
<form onchange="setValues()">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
</form>

Upvotes: 1

void
void

Reputation: 36703

First of all, you should declare the variable outside the for loop or else you will end up declaring each time the for loop runs.

Also, you can use bracket notation instead of dot notation to achieve this as you have said.

var myObject = {};
for (var i = 0; i < inputs.length; i++) {
  myObject["val"+i] = inputs[i];
}

Upvotes: 1

Lansana Camara
Lansana Camara

Reputation: 9873

Add a unique id to each input field (to give it a key for your object).

<form>
  <input id="firstName" type="text">
  <input id="lastName" type="text">
  <input id="email" type="email">
  <input id="number" type="text">
</form>

Now save the id as the key, and the value as the value:

var inputs = document.querySelectorAll('input');    
var myObject = {};

for (var i = 0; i < inputs.length; i++) {
  myObject[inputs[i].id] = inputs[i].value;
}

console.log(myObject) // {firstName: "", lastName: "", email: "", number: ""}

Turn it all into a function that does it by the form:

function getFormValues(formId) {
    var inputs = document.querySelectorAll('#' + formId + ' input');    
    var formValues = {};

    for (var i = 0; i < inputs.length; i++) {
      formValues[inputs[i].id] = inputs[i].value;
    }

    return formValues;
}

All together:

<form id="registerForm">
  <input id="firstName" type="text">
  <input id="lastName" type="text">
  <input id="email" type="email">
  <input id="number" type="text">
</form>

getFormValues('registerForm'); // {firstName: "", lastName: "", email: "", number: ""}

Now you can expand on the function further so it handles array values, etc.

Upvotes: 5

Related Questions