简体   繁体   中英

Get IDs of Multiple <td> in a <tr> with Javascript or JQuery

I have the following in my html:

<table id = 'manifest-table25' class="manifest-table2" width=100%>
                  <tbody width=100%>
                    <tr class="manifest-row">
                      <td width = 17.5%>{{form2.ProductCode}}</td>
                      <td width = 32.5%>{{form2.DescriptionOfGoods}}</td>
                      <td width = 12.5% class="quantity">{{form2.UnitQty}}</td>
                      <td width = 12.5%>{{form2.Type}}</td>
                      <td width = 12.5% oninput="calculate()">{{form2.Price}}</td>
                      <td width = 12.5%>{{form2.Amount}}</td>
                    </tr>
                  </tbody>
                </table>

I have a function calculate() called oninput to the Price field, which multiplies UnitQty * Price and displays the result in Amount.

<script>

    function calculate() {
      var UnitQty = document.getElementById('id_form-0-UnitQty').value;
      var Price = document.getElementById('id_form-0-Price').value;
      var LineTotal = UnitQty * Price;
      $('#id_form-0-Amount').val(LineTotal);
}
</script>

This works perfectly, but is hardcoded to use those specific IDs. My dilemma is that the user has the ability to dynamically add rows to this table, and this will work only for one row. So if the user adds one more row, obviously the above is hardcoded and doesn't apply for that new row. The function called for the new row would need to effectively look like this:

<script>

    function calculate() {
      var UnitQty = document.getElementById('id_form-1-UnitQty').value;
      var Price = document.getElementById('id_form-1-Price').value;
      var LineTotal = UnitQty * Price;
      $('#id_form-1-Amount').val(LineTotal);
}
</script>

So I need some way to dynamically pick replace the IDs in that function, based on which is actually being typed in. I am completely stuck on thinking up an approach, can anyone please help with this?

I'm going to guess that the {{...}} create input elements within those td elements.

A minimal change is to change

oninput="calculate()"

to

oninput="calculate(this)"

which passes the element the event was fired by into the function, then use DOM navigation within the function:

function calculate(el) {
    // Find the row containing this cell
    var row = el.closest("tr");
    // Get the quantity from the `input` in the `.quantity` cell in this row
    var unitQty = row.querySelector('.quantity input').value;
    // Get the price from the `input` in this cell (could use `e.target` instead)
    var price = el.querySelector('input').value;
    // Do the calculation, assign to the `input` in the `.amount` cell in this row
    var lineTotal = unitQty * price;
    row.querySelector(".amount input").value = lineTotal;
}

(Note: I've updated that code to follow standard JavaScript variable naming conventions.)

To avoid making that really fragile, I've added a class to the final td for that last querySelector call.

Or if you prefer jQuery:

function calculate(el) {
    // Find the row containing this cell
    var row = $(el).closest("tr");
    // Get the quantity from the `input` in the `.quantity` cell in this row
    var unitQty = row.find('.quantity input').val();
    // Get the price from the `input` in this cell (could use `e.target` instead)
    var price = $(el).find('input').val();
    // Do the calculation, assign to the `input` in the `.amount` cell in this row
    var lineTotal = unitQty * price;
    row.find(".amount input").val(lineTotal);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM