0

I have a collection of inputs

<input type="text" name="item" id="item" value="Name">  
<input type="number" name="unit_price" id="unit_price" value="100">
<input type="number" name="qty" id="qty" value="2">
<input type="number" name="discount" id="discount" value="0">
<input type="text" name="item" id="item" value="Name 2">  
<input type="number" name="unit_price" id="unit_price" value="200">
<input type="number" name="qty" id="qty" value="5">
<input type="number" name="discount" id="discount" value="10">

I'm trying to loop through all of these inputs to create an object with keys exactly the same as names in my inputs and add those values as values. So my steps are:

let arr = []
inputs.forEach((elem) => {
  console.log(elem.value)
  arr.push({
    'item': elem.value,
    'unit_price': elem.value,
    'qty': elem.value,
    'discount': elem.value
  });
})

EDITED the expected output should look like this:

arr = [{
    'item': 'Name',
    'unit_price': '100',
    'qty': '2',
    'discount': '0',
  },
  {
    'item': 'Name 2',
    'unit_price': '200',
    'qty': '5',
    'discount': '10'
  }
]
1
  • 2
    Aside: you can't have elements with the same ids. Ids must be unique (just one per page). Commented Apr 19, 2022 at 21:49

3 Answers 3

1

You can iterate over the input elements in chunks of 4.

let inputs = document.querySelectorAll('input');
let res = [];
let names = ['item', 'unit_price', 'qty', 'discount'];
for (let i = 0; i < inputs.length; i += names.length)
  res.push(names.reduce((acc, curr, j) => (acc[curr] = inputs[i + j].value, acc), {}));
console.log(res);
<input type="text" name="item" id="item" value="Name">
<input type="number" name="unit_price" id="unit_price" value="100">
<input type="number" name="qty" id="qty" value="2">
<input type="number" name="discount" id="discount" value="0">
<input type="text" name="item" id="item" value="Name 2">
<input type="number" name="unit_price" id="unit_price" value="200">
<input type="number" name="qty" id="qty" value="5">
<input type="number" name="discount" id="discount" value="10">

Sign up to request clarification or add additional context in comments.

2 Comments

Really close to want I need. Two objects should look like this res = [{ 'item': 'Name', 'unit_price': '100', 'qty': '2', 'discount':'0' }, { 'item': 'Name 2', 'unit_price': '200', 'qty': '5', 'discount':'10' }]
@StanislavShokarev I've updated my answer.
0

Well, maybe you can wrap your inputs inside divs, and then find each block of values and map the values into two objects. Like:

  <div id="first">
    <input type="text" name="item" id="item" value="Name">  
    <input type="number" name="unit_price" id="unit_price" value="100">
    <input type="number" name="qty" id="qty" value="2">
    <input type="number" name="discount" id="discount" value="0">
  </div>

  <div id="second">
    <input type="text" name="item" id="item" value="Name 2">  
    <input type="number" name="unit_price" id="unit_price" value="200">
    <input type="number" name="qty" id="qty" value="5">
    <input type="number" name="discount" id="discount" value="10">
  </div>

And in JS

      const first = {}
      const second = {}
      document.querySelectorAll('input').forEach( input => {
        if (input.parentElement.id === 'first') {
          first[input.name] = input.value;
        } else {
          second[input.name] = input.value;
        }
      });
      console.log(first, second);

Comments

0

If you want two separate objects, you can add a class to the inputs to group them like so.

<input class="item1" type="text" name="item" id="item" value="Name">  
<input class="item1" type="number" name="unit_price" id="unit_price" value="100">
<input class="item1" type="number" name="qty" id="qty" value="2">
<input class="item1" type="number" name="discount" id="discount" value="0">

<input class="item2" type="text" name="item" id="item2" value="Name 2">  
<input class="item2" type="number" name="unit_price" id="unit_price2" value="200">
<input class="item2" type="number" name="qty" id="qty2" value="5">
<input class="item2" type="number" name="discount" id="discount2" value="10">

Then, for the javascript, because you are wanting to turn an array of items into a single object, this is a good candidate to use a reduce!

function aggrigateInputs(className) {
  const elements = document.getElementsByClassName(className)

  return elements.reduce((acc, elem) => {
    acc[elem.name] = elem.value;

    return acc;
  }, {})
}

const item1 = aggrigateInputs('item1');
const item2 = aggrigateInputs('item2');

console.log(item1, item2);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.