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>