Reputation: 484
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
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();
Note you need to fix the radio names so they match each other on a per row basis
Upvotes: 2