第一次点击“全选”复选框时,总计未正确计算

问题描述

我创建了一个购物车页面。每个购物车项目都有自己的复选框。我使用的是 <input type="checkBox"> 的常规复选框。一切正常,直到我使用 iCheck 插件

我想不出更好的标题组合我的问题,因为这是一个奇怪的情况。

基本上,我想要发生的是,每次我勾选复选框时,grand_total 都会反映出来。当我勾选复选框时它工作正常,直到我单独检查所有。 grand_total 反映正确。但是,如果我第一次勾选 select all 复选框,它将计算所有 cart_items包括购物车中的最后一个项目。当我最后一次点击 select_all 时,它会正确反映。我无法弄清楚是什么导致了这种情况,因为当我使用常规复选框时它工作正常。也许我错过了什么。

这是发生了什么的快速演示: Quick Demo Video

在第一次点击 select_all 时,即使勾选了 3 个复选框,似乎也只有 2 个勾选。

2 ticked checkboxes

当我再次点击它时,现在每次都是 3 个。

3 ticked checkboxes

所以它似乎发生在每次第一次点击全选时。然后之后工作正常。如果我重新加载页面,问题又来了。

这是我的 HTML 代码

<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']; ?>">₱&nbsp;<?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']; ?>">₱&nbsp;<?PHP echo number_format($cart_item['total_price'],"); ?></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>

这是我带有常规复选框的旧代码:(此代码适用于常规复选框)

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();                  
});

这是我使用 iCheck 的代码:(当我将代码转换为 iCheck 时,会出现此问题)

//   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;
}

解决方法

为了完成这项工作,我使用了 $(this).closest("div").hasClass("checked") 这将检查复选框的父级是否具有 checked 类,因为 iCheck 插件动态添加了此类。然后,我根据哪个事件处理程序调用了 sum() 函数传递了不同的选择器。

演示代码

$(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">₱&nbsp; 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">₱&nbsp; 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">₱&nbsp; 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">₱&nbsp; 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>