I have created a cart page. Every cart item has their own checkboxes. I use regular checkbox which is <input type="checkbox">
. It is all working fine until I use iCheck plugin.
I cannot think of a better title composition of my question because it a weird circumstance.
Basically, what I want to happen is, every time I tick a checkbox, the grand_total
will reflect. It works fine when I tick checkboxes until I checked all individually. grand_total
reflects correctly. However, if I tick the select all
checkbox for the first time, it will compute all cart_items
excluding the last item in the cart. And when I click the select_all
for the last time, it reflects correctly. I cannot figure out what's causing this because it works fine when I used regular checkbox. Maybe I am missing something.
Here is a quick demo of what happens: Quick Demo Video
At the first click of select_all
, it seems like there are only 2 ticked checkboxes even though 3 are checked.
And when I click it again there are now 3 everytime.
so it seems like it happens at every first click of select all. Then works fine afterwards. And if I reload the page, there comes the problem again.
Here is my HTML code
<section class="cart_area">
<div class="table-responsive">
<table>
<thead>
<tr>
<th class="text-center">
<input type="checkbox" name="" id="" class="i-checks select_all">
</th>
<th>Product</th>
<th>Quantity</th>
<th class="text-center">Total</th>
</tr>
</thead>
<tbody>
<input type="hidden" name="cart_items" class="cart_items">
<?php
$cart_items = $cakeOrdering->get_data("SELECT * FROM vw_cart_items WHERE cartID = ? ORDER BY cart_itemID DESC", array($_SESSION['cartID']));
if(!empty($cart_items)){
if(is_array($cart_items) || is_object($cart_items)){
foreach($cart_items as $cart_item){
?>
<tr data-id="<?php echo $cart_item['cart_itemID'] ?>">
<td class="text-center">
<input type="checkbox" name="" id="" class="i-checks cart_item_checkbox">
</td>
<td class="product">
<img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="" class="product-img">
<div class="prod-info">
<p class="prod-name"><?php echo $cart_item['prod_name'] ?></p>
<p class="prod-price" data-price="<?php echo $cart_item['price']; ?>">₱ <?php echo number_format($cart_item['price'], 2, ".", ","); ?></p>
<a href="#" class="action text-info mr-2">Edit</a>
<a href="#" class="action text-danger">Delete</a>
</div>
</td>
<td class="quantity">
<div class="quantity-box">
<button class="minus-qty">-</button>
<input type="number" placeholder="1" value="<?php echo $cart_item['qty']; ?>" class="qty" disabled>
<button class="add-qty">+</button>
</div>
</td>
<td class="total text-right" data-total="<?php echo $cart_item['total_price']; ?>">₱ <?php echo number_format($cart_item['total_price'], 2, ".", ","); ?></td>
</tr>
<?php }}}else{ ?>
<tr>
<td colspan="4" class="text-center">There are no products in you cart. Shop now.</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div class="row mt-4">
<div class="col-lg-7"></div>
<div class="col-lg-5">
<div class="cart-total-text">
<div class="cart-head">Cart Total</div>
<div class="total-boxes">
<p>Sub Total <span class="sub-total">₱ 0.00</span></p>
</div>
<div class="total-boxes">
<p>Total <span class="grand-total">₱ 0.00</span></p>
<input type="hidden" name="grand-total" class="grand-total">
</div>
<div class="cart-footer text-right">
<button class="btn pest_btn" id="checkout">Proceed to Checkout</button>
</div>
</div>
</div>
</div>
</section>
here is my old codes with regular checkbox: (This one works with regular checkbox)
function sum() {
var overall_total = 0;
$(".cart_checkbox:checked").closest("tr").find('.total_price').each(function() {
total_price = $(this).data('total_price');
overall_total = overall_total + parseFloat(total_price);
})
$('.overall_total').text(formatToCurrency(overall_total));
return overall_total;
}
// Select All
$('.select_all').on('change', function() {
$('.cart_checkbox').not(this).prop('checked', this.checked);
sum();
});
// Individual Checkboxes
$(".cart_checkbox").change(function() {
var total_length = $(".cart_checkbox").length;
var checked_length = $(".cart_checkbox:checked").length
//check if length less then total
if (checked_length < total_length) {
$('.select_all').prop('checked', false); //uncheck
} else {
$('.select_all').prop('checked', true); //check
}
sum();
});
And Here's my code with iCheck: (When I convert codes into iCheck, this problem occurs)
// Select All
$(".select_all").on("ifClicked", function () {
$(".select_all").on("ifChecked ifUnchecked", function (e) {
if (e.type == "ifChecked") {
$(".cart_item_checkbox").iCheck("check");
} else {
$(".cart_item_checkbox").iCheck("uncheck");
}
});
sum();
});
// Individual Checkboxes
$(".cart_item_checkbox").on("ifChanged", function () {
var total_length = $(".cart_item_checkbox").length;
var checked_length = $(".cart_item_checkbox").filter(":checked").length;
if (checked_length < total_length) {
$(".select_all").iCheck("uncheck");
} else {
$(".select_all").iCheck("check");
}
sum();
});
function sum() {
var grand_total = 0;
$(".cart_item_checkbox:checked")
.closest("tr")
.find(".total")
.each(function () {
total = $(this).data("total");
grand_total = grand_total + parseFloat(total);
});
$(".sub-total").text(formatToCurrency(grand_total));
$(".grand-total").text(formatToCurrency(grand_total));
$(":input.grand-total").val(grand_total);
return grand_total;
}
To make this work i have use $(this).closest("div").hasClass("checked")
this will check if the parent of the checkbox has checked
class or not because the iCheck plugin adds this class dynamically . Then , i have pass different selector depending on which event handler has called the sum()
function.
Demo Code :
$(document).ready(function() {
$('input').iCheck({
checkboxClass: 'icheckbox_square-blue',
increaseArea: '20%',
handle: 'checkbox'
});
})
//keep only clicked..event
$(".select_all").on("ifClicked", function(e) {
//reverse cndtion..
if (!$(this).closest("div").hasClass("checked")) {
$(".cart_item_checkbox").iCheck("check");
} else {
$(".cart_item_checkbox").iCheck("uncheck");
}
sum($(".cart_item_checkbox").parent(".checked")); //pass the slector
});
$(".cart_item_checkbox").on("ifChanged", function() {
var total_length = $(".cart_item_checkbox").length;
var checked_length = $(".cart_item_checkbox").filter(":checked").length;
if (checked_length < total_length) {
$(".select_all").iCheck("uncheck");
} else {
$(".select_all").iCheck("check");
}
sum($(".cart_item_checkbox:checked")); //here pass different selector
});
function sum(el) {
var grand_total = 0;
el.closest("tr")
.find(".total")
.each(function() {
total = $(this).data("total");
grand_total = grand_total + parseFloat(total);
});
//remove formatToCurrency..for demo..purpose.
$(".sub-total").text((grand_total));
$(".grand-total").text((grand_total));
$(":input.grand-total").val(grand_total);
return grand_total;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/iCheck/1.0.3/skins/all.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/iCheck/1.0.3/icheck.min.js"></script>
<section class="cart_area">
<div class="table-responsive">
<table>
<thead>
<tr>
<th class="text-center">
<input type="checkbox" name="" id="" class="i-checks select_all">
</th>
<th>Product</th>
<th>Quantity</th>
<th class="text-center">Total</th>
</tr>
</thead>
<tbody>
<input type="hidden" name="cart_items" class="cart_items">
<tr data-id="1">
<td class="text-center">
<input type="checkbox" name="" id="" class=" cart_item_checkbox">
</td>
<td class="product">
<img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="" class="product-img">
<div class="prod-info">
<p class="prod-name">
A
</p>
<p class="prod-price" data-price="12">₱ 12
</p>
<a href="#" class="action text-info mr-2">Edit</a>
<a href="#" class="action text-danger">Delete</a>
</div>
</td>
<td class="quantity">
<div class="quantity-box">
<button class="minus-qty">-</button>
<input type="number" placeholder="1" value="2" class="qty" disabled>
<button class="add-qty">+</button>
</div>
</td>
<td class="total text-right" data-total="24">₱ 24
</td>
</tr>
<tr data-id="2">
<td class="text-center">
<input type="checkbox" name="" id="" class="i-checks cart_item_checkbox">
</td>
<td class="product">
<img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="" class="product-img">
<div class="prod-info">
<p class="prod-name">
A
</p>
<p class="prod-price" data-price="12">₱ 12
</p>
<a href="#" class="action text-info mr-2">Edit</a>
<a href="#" class="action text-danger">Delete</a>
</div>
</td>
<td class="quantity">
<div class="quantity-box">
<button class="minus-qty">-</button>
<input type="number" placeholder="1" value="3" class="qty" disabled>
<button class="add-qty">+</button>
</div>
</td>
<td class="total text-right" data-total="36">₱ 36
</td>
</tr>
</tbody>
</table>
</div>
<div class="row mt-4">
<div class="col-lg-7"></div>
<div class="col-lg-5">
<div class="cart-total-text">
<div class="cart-head">Cart Total</div>
<div class="total-boxes">
<p>Sub Total <span class="sub-total">₱ 0.00</span></p>
</div>
<div class="total-boxes">
<p>Total <span class="grand-total">₱ 0.00</span></p>
<input type="hidden" name="grand-total" class="grand-total">
</div>
<div class="cart-footer text-right">
<button class="btn pest_btn" id="checkout">Proceed to Checkout</button>
</div>
</div>
</div>
</div>
</section>