0

I'm working on a Django form that can calculate values in real time. I would like the javascript function to work for all rows which consists of 3 input fields each. I tried assigning each input field with an id followed by a forloop counter. I also looped through the function hoping that it will work for all the ids, a1,a2,a3... b1,b2,b3... c1,c2,c3... However, the function only worked for the last row.

Here's the javascript I used:

<script type="text/javascript">

  for (i = 0; i < {{ total_rows|safe }}; i++) {  
    $('input').keyup(function(){ 
        var firstValue  = Number($('#a'+i).val());  
        var secondValue = Number($('#b'+i).val());
        document.getElementById('c'+i).value = firstValue * secondValue;
    });
  }

</script>

Here's my template:

<form>
{% csrf_token %}
  <table>
    <thead>
      <tr>
        <th>Quantity</th> 
        <th>Unit Price</th>
        <th>Amount</th>
      </tr>
    </thead>
    <tbody>
      {% for item, amount in loop_list %}
      <tr>
        <td>
          <input id="a{{ forloop.counter }}" type="text" class="form-control" placeholder="" name="quantity1" value="{{ item.quantity }}">
        </td>
        <td>
          <input id="b{{ forloop.counter }}" type="text" class="form-control" placeholder="" name="unit_price1" value="{{ item.product.unit_price }}">
        </td>
        <td>
          <input id="c{{ forloop.counter }}" type="text" class="form-control" placeholder="{{ amount }}" readonly>
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</form> 

1 Answer 1

2

You're binding all inputs multiple times to multiple keyup handlers. However, you don't need to use the ids here; loop over the rows in JavaScript. I've simplified the markup a little here.

(You will, however, need to have unique names per input if you are planning on POSTing this form back to Django!)

{% for item, amount in loop_list %}
<tr class="calc-row">
  <td>
    <input class="quantity" value="{{ item.quantity }}">
  </td>
  <td>
    <input class="unit-price" value="{{ item.product.unit_price }}">
  </td>
  <td>
    <input class="amount" readonly>
  </td>
</tr>
{% endfor %}

With the classes set, you can then bind to the quantity and unit price inputs only once, and have the event handler look up the elements per row.

$("input.quantity, input.unit-price").keyup(function() {
  var $row = $(this).closest("tr.calc-row");
  var quantity = Number($row.find(".quantity").val());
  var unitPrice = Number($row.find(".unit-price").val());
  $row.find(".amount").val(quantity * unitPrice);
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.