How to compute total price based on checkboxes

Viewed 69

In our website I have a cart table that contains all of the items. Each row has checkboxes. By clicking the checkboxes, it will determine the total price of your cart the you will checkout. At first I don't know what the title of my question should be as I have 2 problems.

First, when I clicked all the checkboxes, the Select all checkbox will be checked, and if I unchecked one, the Select all will be unchecked.

Second, is properly getting the total prices based on checkboxes. I am able to get the total price when I tick the checkboxes. It all adds up but if I tick the Select all while all other checkboxes are checked, it adds another total which is not right. Please see the demo I uploaded. Total Price Computation Demo

I'm guessing its because I have put computation in Select all also, but I actually run out of ideas on how to achieve this.

Here are my codes

Table

<table class="table">
    <thead>
        <tr>
            <th><input type="checkbox" name="" id="" class="select_all"></th>
            <th scope="col">Preview</th>
            <th scope="col">Product</th>
            <th class="text-right" scope="col">Price</th>
            <th scope="col">Quantity</th>
            <th class="text-right" scope="col">Total</th>
            <th scope="col"></th>
        </tr>
    </thead>
    <tbody class="product-container">
        <?php 
            $cart_items = $cakeOrdering->get_data("SELECT * FROM vw_cart_items ORDER BY cart_itemID DESC");
            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><input type="checkbox" name="cart_checkbox" class="cart_checkbox"></td>
            <td>
                <img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="<?php $cart_item['prod_name']; ?>" class="cart_preview">
            </td>
            <td><?php echo $cart_item['prod_name']; ?></td>
            <td class="price text-right" data-price="<?php echo $cart_item['price']; ?>">₱&nbsp;<?php echo number_format($cart_item['price'], 2, ".", ","); ?></td>
            <td>
                <div class="input-group input-group-sm mb-3">
                    <div class="input-group-prepend">
                        <button class="btn btn-outline-secondary minus_qty" type="button">-</button>
                    </div>
                    <input type="number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' class="text-center quantity" aria-label="quantity" aria-describedby="quantity" value="<?php echo $cart_item['qty']; ?>" disabled>
                    <div class="input-group-append">
                        <button class="btn btn-outline-secondary add_qty" type="button">+</button>
                    </div>
                </div>
            </td>
            <td class="total_price text-right" data-total_price="<?php echo $cart_item['total_price']; ?>">₱&nbsp;<?php echo number_format($cart_item['total_price'], 2, ".", ",");?></td>
            <td class="btn-action">
                <a href="" class="text-primary" title="View details"><i class="fa fa-pencil"></i></a>
                <a href="" data-id="<?php echo $cart_item['cart_itemID'];?>" class="text-danger remove" title="remove"><i class="fa fa-trash"></i></a>
            </td>
        </tr>
        <?php }}} ?>
    </tbody>
</table>

Script

var overall_total = 0;

$('.select_all').on('change', function(){
    $('.cart_checkbox').not(this).prop('checked', this.checked);

    if($(this).is(":checked")) {
        $('.total_price').each(function(){
            total_price = $(this).data('total_price');
            overall_total = overall_total + parseFloat(total_price);
        });
    }else{
        $('.total_price').each(function(){
            total_price = $(this).data('total_price');
            overall_total = overall_total - parseFloat(total_price);
        });
    }
    $('.overall_total').text(formatToCurrency(overall_total));
});

$(".cart_checkbox").change(function(){
    var total_price = $(this).closest('tr').find('.total_price').data('total_price');

    if($(this).is(":checked")) {
        overall_total = overall_total + parseFloat(total_price);
    }else{
        overall_total = overall_total - parseFloat(total_price);
    }
    $('.overall_total').text(formatToCurrency(overall_total));
})
2 Answers

For your first issue you can check if the length of total checkboxes and checked checkboxes are not equal depending this check/uncheck your select_all checkbox .

Now, for next issue i have move whole calculation part inside different function so whenever you need to total you can call this function and then loop through only checked trs row and change total values .

Demo Code :

$('.select_all').on('change', function() {
  $('.cart_checkbox').not(this).prop('checked', this.checked);
  sum(); //call this 
});

$(".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(); //call this
})

function sum() {

  var overall_total = 0;
  //loop through only checked trs..
  $(".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(overall_total); //add your format fn
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<table class="table">
  <thead>
    <tr>
      <th><input type="checkbox" name="" id="" class="select_all"></th>
      <th scope="col">Preview</th>
      <th scope="col">Product</th>
      <th class="text-right" scope="col">Price</th>
      <th scope="col">Quantity</th>
      <th class="text-right" scope="col">Total</th>
      <th scope="col"></th>
    </tr>
  </thead>
  <tbody class="product-container">

    <tr data-id="1">
      <td><input type="checkbox" name="cart_checkbox" class="cart_checkbox"></td>
      <td>
        <img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="<?php $cart_item['prod_name']; ?>" class="cart_preview">
      </td>
      <td>A</td>
      <td class="price text-right" data-price="34">₱&nbsp;34</td>
      <td>
        <div class="input-group input-group-sm mb-3">
          <div class="input-group-prepend">
            <button class="btn btn-outline-secondary minus_qty" type="button">-</button>
          </div>
          <input type="number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' class="text-center quantity" aria-label="quantity" aria-describedby="quantity" value="<?php echo $cart_item['qty']; ?>" disabled>
          <div class="input-group-append">
            <button class="btn btn-outline-secondary add_qty" type="button">+</button>
          </div>
        </div>
      </td>
      <td class="total_price text-right" data-total_price="74">₱&nbsp;74</td>
      <td class="btn-action">
        <a href="" class="text-primary" title="View details"><i class="fa fa-pencil"></i></a>
        <a href="" data-id="1" class="text-danger remove" title="remove"><i class="fa fa-trash"></i></a>
      </td>
    </tr>

    <tr data-id="2">
      <td><input type="checkbox" name="cart_checkbox" class="cart_checkbox"></td>
      <td>
        <img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="<?php $cart_item['prod_name']; ?>" class="cart_preview">
      </td>
      <td>A2</td>
      <td class="price text-right" data-price="34">₱&nbsp;34</td>
      <td>
        <div class="input-group input-group-sm mb-3">
          <div class="input-group-prepend">
            <button class="btn btn-outline-secondary minus_qty" type="button">-</button>
          </div>
          <input type="number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' class="text-center quantity" aria-label="quantity" aria-describedby="quantity" value="<?php echo $cart_item['qty']; ?>" disabled>
          <div class="input-group-append">
            <button class="btn btn-outline-secondary add_qty" type="button">+</button>
          </div>
        </div>
      </td>
      <td class="total_price text-right" data-total_price="742">₱&nbsp;742</td>
      <td class="btn-action">
        <a href="" class="text-primary" title="View details"><i class="fa fa-pencil"></i></a>
        <a href="" data-id="2" class="text-danger remove" title="remove"><i class="fa fa-trash"></i></a>
      </td>
    </tr>

    <tr data-id="3">
      <td><input type="checkbox" name="cart_checkbox" class="cart_checkbox"></td>
      <td>
        <img src="../img/cake_uploads/<?php echo $cart_item['image']; ?>" alt="<?php $cart_item['prod_name']; ?>" class="cart_preview">
      </td>
      <td>A3</td>
      <td class="price text-right" data-price="343">₱&nbsp;343</td>
      <td>
        <div class="input-group input-group-sm mb-3">
          <div class="input-group-prepend">
            <button class="btn btn-outline-secondary minus_qty" type="button">-</button>
          </div>
          <input type="number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' class="text-center quantity" aria-label="quantity" aria-describedby="quantity" value="<?php echo $cart_item['qty']; ?>" disabled>
          <div class="input-group-append">
            <button class="btn btn-outline-secondary add_qty" type="button">+</button>
          </div>
        </div>
      </td>
      <td class="total_price text-right" data-total_price="743">₱&nbsp;743</td>
      <td class="btn-action">
        <a href="" class="text-primary" title="View details"><i class="fa fa-pencil"></i></a>
        <a href="" data-id="3" class="text-danger remove" title="remove"><i class="fa fa-trash"></i></a>
      </td>
    </tr>

  </tbody>
</table>
<span class="overall_total"></span>

Just make overall_total = 0 inside your $('.select_all').on('change' and it should work. And remove else portion.

$('.select_all').on('change', function(){
    
    $('.cart_checkbox').not(this).prop('checked', this.checked);
    // reset total value to 0 because in below every product values are being fetched and summed up.
    overall_total = 0;

    if($(this).is(":checked")) {
        $('.total_price').each(function(){
            total_price = $(this).data('total_price');
            overall_total = overall_total + parseFloat(total_price);
        });
    }
    //else{
    //    $('.total_price').each(function(){
    //        total_price = $(this).data('total_price');
    //        overall_total = overall_total - parseFloat(total_price);
    //    });
    //}

    $('.overall_total').text(formatToCurrency(overall_total));
});
Related