I have a form with several text inputs and I need to get the name and value of the input to generate an object. I don’t know if this would be possible, but so far this is my code:

function getData(){
 const test = document.querySelectorAll('input')
 test.forEach((item) => {
   console.log('item:', item.name + item.value)
   //example
    {
     item.name = item.value
     ....
    }
   //example
    
 })
}

My intention is that item.name is the object’s key name and item.value is the value.

This will do:

function getData(){
 const test = document.querySelectorAll('input')
 const result = {}
 test.forEach((item) => {
   console.log('item:', item.name + item.value)
   result[item.name] = item.value    
 })
 return result
}

You could achieve the same result with (barely) less code using test.reduce()

function getData(){
 const test = document.querySelectorAll('input')
 return test.reduce((result, item) => {
   console.log('item:', item.name + item.value)
   result[item.name] = item.value
   return result 
 }, {})
}

You need create a new object add data to it from fromEachthen return it:

function getData(){
 const test = document.querySelectorAll('input');
 const returnObj = {};
 test.forEach((item) => {
   returnObj[item.name] = item.value;
 })
 return returnObj;
}

console.log(getData());
<input name="test1" value="blah1">
<input name="test2" value="blah2a">
<input name="test3" value="blah3b">
<input name="test4" value="blah4c">
<input name="test6" value="blah6">

You can turn your results into an Array by passing your query results into Array.fromthen map() the array into a shape that Object.fromEntries() is looking for to achieve this result:

function getData(){
  const elements = document.querySelectorAll('input');
  return Object.fromEntries(
    Array.from(elements).map(
      el => ([el.name, el.value])
    )
  );
}

console.log(getData());
<input name="test1" value="blah1">
<input name="test2" value="blah2a">
<input name="test3" value="blah3b">
<input name="test4" value="blah4c">
<input name="test6" value="blah6">

2

Use HTMLFormElement and HTMLFormControlsCollection interfaces to reference any and all form controls and <form>.

Form controls are: <button>, <fieldset>, <input> , <object>, <output>, <select>and <textarea>

Details are commented in example

// Reference the <form>
const form = document.forms.data;

/*
Reference all form controls within <form>. 
Form controls includes <input>, <select>, <textarea>, etc.
*/
const IO = form.elements;

/*
Pass in one or more DOM objects (as a 
NodeList, array, etc.
*/
/**
 *  Run the DOM objects/nodes through .flatMap()
 *  Check each node...
 *    if it's a radio button AND it isn't checked...
 *    OR node doesn't have a .value...
 *    Return an empty array [] 
 *    (in .flatMap() returning an empty array results in
 *    nothing as if node was skipped.)
 */
/**
 *  Return an object literal with a key/value of:
 *   "name": node.name,
 *   "value": node.value
 */
const getData = (nodes) => {
  return [...nodes].flatMap(node => {
    if (node.type === 'radio' && !node.checked || node.value === '') {
      return [];
    }
    return Object.assign({}, {
      ['name']: node.name,
      ['value']: node.value
    })
  });
};

console.log(getData(IO));
<form id='data'>
  <input name="A" value="Alpha">
  <input name="B" value="Beta">
  <input name="C" value="Gamma">
  <input name="D" value="Delta">
  <input name="rad" type="radio" value="1">
  <input name="rad" type="radio" value="2">
  <input name="rad" type="radio" value="3" checked>
  <input name="rad" type="radio" value="4">
  <select id='sel' name="sel">
    <option disabled></option>
    <option value="1">I</option>
    <option value="2">II</option>
    <option value="3">III</option>
    <option selected value="4">IV</option>
  </select>
  <textarea name="text"></textarea>
</form>

Here’s a non-naive solution that properly encodes a <form> elements –

  • <input>
  • <input type="checkbox"> – includes only checked elements
  • <input type="radio"> – includes only the checked element
  • <select> – includes only the selected element
  • <textarea>

Note all disabled Inputs are ignored. Some corner cases like <input type="file"> and <select multiple> have not been taken into account –

function formData(f) {
  return Object.fromEntries(
    Array.from(f.elements)
      .filter(item => {
        switch (item.type) {
          case "checkbox": return item.checked
          default: return !item.disabled
        }
      })
      .map(item => [item.name, item.value])
  )
}

console.log(formData(document.forms.foo))
<form id="foo">
  <p>hello world</p>
  <input name="a" value="A" />
  <input name="b" value="B" disabled />
  <textarea name="c" value="C">Ctext</textarea>
  <select name="e">
    <option value="E1">E1</option>
    <option value="E2" selected>E2</option>
  </select>
  <input type="checkbox" name="f1" value="F1" checked />
  <input type="checkbox" name="f2" value="F2" />
  <input type="radio" name="g" value="G1" />
  <input type="radio" name="g" value="G2" />
  <input type="radio" name="g" value="G3" checked />
</form>
{
  "a": "A",
  "c": "Ctext",
  "e": "E2",
  "f1": "F1",
  "g": "G3"
}

If I understand your question properly, what you need to use is the map function of an array. This w3schools tutorial explains pretty much how to apply this in your case: https://www.w3schools.com/jsref/jsref_map.asp

1

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