1

I have a dynamically generated table like below

enter image description here

this is the code that generate this table

function pullInventory(data) {
 var container = document.getElementById('inventoryContainer')
 
 var index = 0;
 
 
 console.log(index)
 data.forEach(function(awardsSnap) {
 index ++;
 // console.log(awardsSnap, index)
 var awardItem = awardsSnap.val()
 // Attach an asynchronous callback to rea
 var NSNcard = `
 
 <tr>
 <td class="serial">${awardItem.NSN}</td>
 
 <td> ${awardItem.Nomenclature} </td>
 <td> ${awardItem.Awarddate} </td> 
 <td> ${awardItem.Awardid} </td>
 <td> 
 <input type="text" placeholder="i.e. 100 EA" class="form-control" value="" id="qty${index}"style="width: 110px;">
 </td>
 <td> 
 <input type="text" placeholder="i.e. 9ドル.23 " class="form-control" value="" style="width: 110px;">
 </td> 
 
 </tr>
 `;
 container.innerHTML += NSNcard;
 
 });
}

I want to get all the user entered quantity and price on a button click so I use this

document.querySelector("#savebtn").addEventListener("click", e => {
 var rows = document.getElementById("WelcomeTable").getElementsByTagName("tbody")[0].getElementsByTagName("tr").length;
 saveInventory(rows);
});
function saveInventory(rows) {
 const columnHeader = Array.prototype.map.call(
 document.querySelectorAll(".table th"),
 th => {
 return th.innerHTML;
 }
 );
 const tableContent = Object.values(
 document.querySelectorAll(".table tbody tr")
 ).map(tr => {
 const tableRow = Object.values(tr.querySelectorAll("td")).reduce(
 (accum, curr, i) => {
 const obj = { ...accum };
 obj[columnHeader[i]] = curr.innerHTML.trim();
 
 console.log(accum, curr, i)
 return obj;
 },
 {}
 );
 return tableRow;
 });
 
}

everything works fine except that the two input column in the table above does not detect user input. I'm not able to get the quantity and price value entered.

 Award Date: "08-23-2012"
 
 Award#: "SP452013D0055"
 
 NSN: "S222V00004789"
 
 Nomenclature: " BATTERIES, NICKEL-CADMIUM"
 
 Quantity: "<input type="text" placeholder="i.e. 100 EA" class="form-control" value="" id="qty18" style="width: 110px;">"
 
 Unit-Price: "<input type="text" placeholder="i.e. 9ドル.23 " class="form-control" value="" style="width: 110px;">"

I tried this and other things but they output undefine

obj[columnHeader[4]]=curr.val(); obj[columnHeader[4]]=curr.value;

how could i get the enetered quantity and price from the dynamic table?

asked Nov 3, 2018 at 14:31
2
  • Please edit your question and create ONE snippet that actually runs showing a minimal reproducible example Commented Nov 3, 2018 at 14:43
  • What kind of object do you pass to pullInventory? Commented Nov 3, 2018 at 14:48

3 Answers 3

1

You could try doing something like this:

window.onload = ()=>{
 let targetTable = document.getElementById('target-table');
 let targetTableRows = targetTable.rows;
 let tableHeaders = targetTableRows[0];
 
 // start from the second row as the first one only contains the table's headers
 for(let i = 1; i < targetTableRows.length; i++){
 // loop over the contents of each row
 for(let j = 0; j < targetTableRows[i].cells.length; j++){
 // something we could use to identify a given item
 let currColumn = tableHeaders.cells[j].innerHTML;
 // the current <td> element
 let currData = targetTableRows[i].cells[j];
 // the input field in the row
 let currDataInput = currData.querySelector('input');
 
 // is the current <td> element containing an input field? print its value.
 // Otherwise, print whatever is insside
 currDataInput ? console.log(`${currColumn}: ${currDataInput.value}`) 
 : console.log(`${currColumn}: ${currData.innerHTML}`); 
 }
 }
 
};
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<table class="table" id="target-table">
 <thead>
 <tr>
 <th scope="col">Person #</th>
 <th scope="col">First</th>
 <th scope="col">Last</th>
 <th scope="col">Handle</th>
 <th scope="col">Quantity</th>
 <th scope="col">Price</th> 
 </tr>
 </thead>
 <tbody>
 <tr>
 <th scope="row">1</th>
 <td>Mark</td>
 <td>Otto</td>
 <td>@mdo</td>
 <td><input type="text" value="01-quantity" id="value-01"></td>
 <td><input type="text" value="01-price" id="value-01-2"></td> 
 </tr>
 <tr>
 <th scope="row">2</th>
 <td>Jacob</td>
 <td>Thornton</td>
 <td>@fat</td>
 <td><input type="text" value="02-quantity" id="value-02"></td>
 <td><input type="text" value="02-price" id="value-02-2"></td> 
 </tr>
 <tr>
 <th scope="row">3</th>
 <td>Larry</td>
 <td>the Bird</td>
 <td>@twitter</td>
 <td><input type="text" value="03-quantity" id="value-03"></td>
 <td><input type="text" value="03-price" id="value-03-2"></td> 
 </tr>
 </tbody>
</table>

What is done in the example above should also work for your specific case.

Also, here's a working exmaple :)

answered Nov 3, 2018 at 16:44
Sign up to request clarification or add additional context in comments.

1 Comment

THIS IS PERFECT! Thank You my friend
1

val() is jQuery method. You'll need to use .value in JavaScript.

answered Nov 3, 2018 at 14:33

1 Comment

Not only that, but data seems to be an array - if it is not an array of inputs, then .value will also not work unless the object has a ["value"] attribute
0

obj[columnHeader[i]] = curr.innerHTML.trim();

innerHtml.trim returns only tag having direct child with text in it. In your code last two td having an input as child. so in that case you need to check 'curr' having a child available. if there is a child available and its tagName is input, then you have to use childs value.

for example

obj[columnHeader[i]] = curr.children.length && curr.children[0].tagName=="INPUT" ? curr.children[0].value : curr.innerHTML.trim();

the above condition can be check and assign to a variable before it is assigned to key

answered Nov 3, 2018 at 14:56

2 Comments

it still return undefine for both input fields
can you try using obj[columnHeader[i]] = curr.children.length && curr.children[0].tagName=="INPUT" ? curr.children[0].value : curr.innerHTML.trim();

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.