Home > front end >  Convert dynamic HTML tabular form to JSON
Convert dynamic HTML tabular form to JSON

Time:09-21

I have a simple form with dynamic number of rows, each row having the same fields.

<table  id="recordsTable">
   <thead>
      <tr>
         <th >#</th>
         <th >Name</th>
         <th >Email</th>
         <th >Action</th>
         <th></th>
      </tr>
   </thead>
   <tbody id="tbody">
      <tr id="R1" name="record">
         <td >
            <p>1</p>
         </td>
         <td>
            <input type="text" name="facultyName" />
         </td>
         <td>
            <input type="text" name="facultyEmail" />
         </td>
         <td>
            <select name="actionType">
               <option value="default">--None--</option>
               <option value="a1">Action 1</option>
               <option value="a2">Action 2/Withdraw</option>
               <option value="a3">Action 3</option>
            </select>
         </td>
      </tr>
      <!-- Dynamic rows appear here -->
   </tbody>
</table>

Form is present as a table, but it's not a strict requirement, so can be flexible here. On form submission I need this form data to be converted to JSON. I have this function to convert form into JSON:

function convertFormToJSON(form) {
  const array = $(form).serializeArray();
  const json = {};
  $.each(array, function () {
    json[this.name] = this.value || "";
  });
  return json;
}

But every row overwrites previous one, so I end up having only last row data in this JSON. I realize I need to have a loop and append each new row data into final JSON, but I struggle finding the criterion for this loop. Table rows? Or better not to use table and switch to a different form presentation?

CodePudding user response:

Here is a simple non-jQuery way of collecting all the input data from this form with a variable number of input elements:

document.querySelector("button").onclick=ev=>{
 let res=[...document.getElementById("tbody").children].map(tr=>
  Object.fromEntries([...tr.querySelectorAll("input,select")].map(el=>
   [el.name,el.value])));
 console.log(res);
}
input,select {width:80px;}
<table  id="recordsTable">
   <thead>
  <tr>
     <th >#</th>
     <th >Name</th>
     <th >Email</th>
     <th >Action</th>
     <th></th>
  </tr>
   </thead>
   <tbody id="tbody">
  <tr id="R1" name="record">
     <td >1</td>
     <td>
        <input type="text" name="facultyName" />
     </td>
     <td>
        <input type="text" name="facultyEmail" />
     </td>
     <td>
        <select name="actionType">
           <option value="default">--None--</option>
           <option value="a1">Action 1</option>
           <option value="a2">Action 2/Withdraw</option>
           <option value="a3">Action 3</option>
        </select>
     </td>
  </tr>
<tr id="R2" name="record">
     <td >2</td>
     <td>
        <input type="text" name="facultyName" />
     </td>
     <td>
        <input type="text" name="facultyEmail" />
     </td>
     <td>
        <select name="actionType">
           <option value="default">--None--</option>
           <option value="a1">Action 1</option>
           <option value="a2">Action 2/Withdraw</option>
           <option value="a3">Action 3</option>
        </select>
     </td>
  </tr>
<tr id="R3" name="record">
     <td >3</td>
     <td>
        <input type="text" name="facultyName" />
     </td>
     <td>
        <input type="text" name="facultyEmail" />
     </td>
     <td>
        <select name="actionType">
           <option value="default">--None--</option>
           <option value="a1">Action 1</option>
           <option value="a2">Action 2/Withdraw</option>
           <option value="a3">Action 3</option>
        </select>
     </td>
  </tr>
   </tbody>
</table>
<button>collect data</button>

  • Related