thecore7
thecore7

Reputation: 484

Jquery to calculate total of table row

I have to calculate the printing cost of when a customer makes an order of invitation.

If it was just 1 product in the basket its easy but in the example I've made the customer has 2 different invitation models and both have different printing options and cost.

I've made a custom js function based onclick action but for some reason it doesn't calculate correct Option cost.

I've prepared jsfidle below: Thank you for any help!

function calculate_options() {
  $('.cart > tbody  > .product').each(function() {
    var thisrow = $(this).attr("id");
    var ttloptions = 0.0;
    if ($('.optradio').length) {
      var qty = parseInt($(this).find('.qty').val());
      var optamount = $('#' + thisrow).find('.optradio:checked').attr('data');
      console.log(optamount);
      var ttloptions = optamount * qty;
      $('#' + thisrow).find('.optcost').text('' + ttloptions.toFixed(2));
    }
  })
}
.left {
  float: left;
  text-align: left;
  width: 100%;
}

table.cart label.h15,
.optradio {
  float: left;
}

label.h15 {
  height: auto;
  min-width: 172px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table class="cart">
  <tbody>
    <tr>
      <th>Product name</th>
      <th>qty</th>
      <th>Price</th>
      <th>Options</th>
      <th>Option cost</th>
      <th>Total</th>
    </tr>
    <tr id="1635" class="product">
      <td>Product 1</td>
      <td align="center"> <input type="number" min="20" name="qty[]" class="qty 1635" value="20"></td>
      <td align="left"><input type="text" name="price[]" readonly="true" class="price" maxlength="6" value="1.55"></td>
      <td align="center">
        <div class="row width100 left"><label class="h15">Print options</label><label class="nobold h15"><input type="radio" value="0" data="0" name="print" onclick="calculate_options();" class="optradio">No print</label><label class="nobold h15"><input type="radio" value="1" data="0.50" name="print[]" onclick="calculate_options();" class="optradio">Black print ($0.50) /piece</label>
          <label class="nobold h15"><input type="radio" value="2" data="0.70" name="print[]" onclick="calculate_options();" class="optradio">Color print ($0.70) /piece</label>
        </div>
      </td>
      <td align="center"><span class="optcost"></span></td>
      <td align="center"><span class="amount">$31.00</span></td>
    </tr>

    <tr id="1620" class="product">
      <td>Product 2</td>
      <td align="center"> <input type="number" min="20" name="qty[]" class="qty 1635" value="20"></td>
      <td align="left"><input type="text" name="price[]" readonly="true" class="price" maxlength="6" value="1.20"></td>
      <td align="center">
        <div class="row width100 left"><label class="h15">Print options</label><label class="nobold h15"><input type="radio" value="0" data="0" name="print" onclick="calculate_options();" class="optradio">No print</label><label class="nobold h15"><input type="radio" value="1" data="0.30" name="print[]" onclick="calculate_options();" class="optradio">Black print ($0.50) /piece</label>
          <label class="nobold h15"><input type="radio" value="2" data="0.70" name="print[]" onclick="calculate_options();" class="optradio">Color print ($0.70) /piece</label>
        </div>
      </td>
      <td align="center"><span class="optcost"></span></td>
      <td align="center"><span class="amount">$24.00</span></td>
    </tr>
  </tbody>
</table>

Upvotes: 0

Views: 1460

Answers (1)

charlietfl
charlietfl

Reputation: 171669

Instead of just doing options cost calcs in one function, do everything for whole row in a single change handler. The trick is to make sure you isolate the row instance first, then always look for row specific elements using find() from that parent row

$('.product :input ').on('change', function(e) {
  // start by isolating row instance
  var $row = $(this).closest('tr.product'),
    // then use find() for the row specific elements
    qty = +$row.find('.qty').val(),
    price = +$row.find('.price').val(),
    $opt = $row.find(':radio:checked'),
    optamount = 0;
  if ($opt.length) {
    optamount += $opt.attr('data') * qty;
  }
  total = (qty * price + optamount).toFixed(2);

  $row.find('.optcost').text(optamount.toFixed(2))

  $row.find('.amount').text('$' + total)
    // trigger one change on each row on page load
}).filter('.qty').change();

DEMO

Note you need to fix the radio names so they match each other on a per row basis

Upvotes: 2

Related Questions