-1

I'm having an issue regarding my total div using JQuery.

Actually this div changes values when + or - buttons are clicked, which actually works well.

My problem here is that when i "reset" a value to 0 after i augmented it, as soon as this value gets to 0, my total gets equal to NaN, where i want it to stay at 0 to keep calcullating total for my other values.

window.onload = function() {

  var ids = new Array();
  $('input').each(function() {
    ids.push($(this).attr("id"));


  });

  var total = 0;

  $('.add').click(function() {
    var quant, idprev, price, tot;

    if ($(this).prev().val() < 99) {
      $(this).prev().val(+$(this).prev().val() + 1);

      quant = ($(this).prev().val());
      idprev = ($(this).prev().attr('id') - 1);
      price = $("#" + idprev).val();
      tot = quant * price;

      $("#result" + idprev).html(tot.toFixed(2) + "€");

      for (var i = 0; i < ids.length; i++) {
        if (ids[i] % 2) {
          total = total + (tot / quant);
          $("#total").html("Total : " + total.toFixed(2) + "€");
        } else {
          return false;
        }
      }
    }
  });

  $('.sub').click(function() {
    var quant, idprev, price, tot;
    if ($(this).next().val() > 0) {
      if ($(this).next().val() > 0)
        $(this).next().val(+$(this).next().val() - 1);

      quant = ($(this).next().val());
      idprev = idprev = ($(this).next().attr('id') - 1);
      price = $("#" + idprev).val();
      tot = quant * price;

      $("#result" + idprev).html(tot.toFixed(2) + "€");

      for (var i = 0; i < ids.length; i++) {
        if (ids[i] % 2) {
          total = total - (tot / quant);
          $("#total").html("Total : " + total.toFixed(2) + "€");
        } else {
          return false;
        }

      }

    }
  });
}
<script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<div id="total"></div>
<div class="main">
  <table>
    <tr>
      <td align="center">Description</td>
      <td align="center">Price</td>
      <td align="center">Quantity</td>
    </tr>
    <tr>
      <td>Article 1</td>
      <td><input type="text" hidden="true" value="2.5" id="1">2.50€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" id="sub" class="sub">-</button>
          <input type="number" id="2" value="0" min="0" max="3" />
          <button type="button" id="add" class="add">+</button>
        </div>
      </td>
      <td>
        <div id="result1"></div>
      </td>

    </tr>
    <tr>
      <td>Article 2</td>
      <td><input type="text" hidden="true" value="1" id="3">1.00€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" id="sub" class="sub">-</button>
          <input type="number" id="4" value="0" min="0" max="3" />
          <button type="button" id="add" class="add">+</button>
        </div>
      </td>
      <td>
        <div id="result3"></div>
      </td>
    </tr>
    <tr>
      <td>Article 3</td>
      <td><input type="text" hidden="true" value="3.8" id="5">3.80€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" id="sub" class="sub">-</button>
          <input type="number" id="6" value="0" min="0" max="3" />
          <button type="button" id="add" class="add">+</button>
        </div>
      </td>
      <td>
        <div id="result5"></div>
      </td>
    </tr>
    <tr>
      <td>Article 4</td>
      <td><input type="text" hidden="true" value="1" id="7">1.00€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" id="sub" class="sub">-</button>
          <input type="number" id="8" value="0" min="0" max="3" />
          <button type="button" id="add" class="add">+</button>
        </div>
      </td>
      <td>
        <div id="result7"></div>
      </td>
    </tr>
  </table>
</div>

Thanks in advance :)

empiric
  • 7,825
  • 7
  • 37
  • 48
  • What happens if you print the individual values to the console (as individual lines), as well as the final result? One of them is probably not a string or number. – Tim Sep 19 '19 at 14:55
  • Every values are printed as numbers, apparently it looks like when i'm trying to execute ```total = total - (tot / quant);``` and pushing - when total is 1,total gets resetted to 0, and the value then become NaN. – Pierre Loye Sep 19 '19 at 14:57
  • 3
    `total = total - (tot / quant);` is the issue, when looking at that formula as soon as the quantity reaches 0 you perform: `total = 2.5 - ( 0/0)` which is a division by zero which is not allowed – empiric Sep 19 '19 at 14:58
  • Possible duplicate of [Best way to prevent/handle divide by 0 in javascript](https://stackoverflow.com/questions/8072323/best-way-to-prevent-handle-divide-by-0-in-javascript) – Liam Sep 19 '19 at 15:03

3 Answers3

1

Try :

$("#total").html("Total : " + (+total || 0).toFixed(2) + "€");

This code casts variable total in number with + sign and substitute by 0 if is null or NaN with || logical or. This way .toFixed() method always have a number to work with.

EddiGordo
  • 682
  • 4
  • 10
0

The issue, as others have noted is because you're dividing by zero when the row total and quantity are both zero.

However you should note that your solution is a lot more complicated than it needs to be, and the division that's causing the issue is completely redundant.

The logic can be DRY'd up and made much more extensible by removing the unique id attributes (which removes the need for the loop/array and the modulo operator) and also by using common classes on all your elements. Try this:

window.addEventListener('load', function() {
  $('.change-quantity').click(function() {
    var amount = $(this).data('amount');
    var $quantity = $(this).siblings('.quantity').val(function(i, v) {
      v = +v || 0;
      return Math.max(0, v < 99 && v >= 0 ? v + amount : v);
    });
    updateRowTotal($quantity.closest('tr'));
    updateOverallTotal();
  });
  
  function updateRowTotal($row) {
    $row.find('.result').text(function() {
      return ((+$row.find('input.quantity').val() || 0) * (+$row.find('input.price').val() || 0)).toFixed(2) + '€';
    });
  }
  
  function updateOverallTotal() {
    var total = 0;
    $('.result').each(function() {
      total += parseFloat($(this).text()) || 0;
    });
    $('#total').text(total.toFixed(2) + '€');
  }
});
<script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<div id="total">0.00€</div>
<div class="main">
  <table>
    <tr>
      <td align="center">Description</td>
      <td align="center">Price</td>
      <td align="center">Quantity</td>
    </tr>
    <tr>
      <td>Article 1</td>
      <td><input type="text" hidden="true" value="2.5" class="price">2.50€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" class="change-quantity" data-amount="-1">-</button>
          <input type="number" class="quantity" value="0" min="0" max="3" />
          <button type="button" class="change-quantity" data-amount="1">+</button>
        </div>
      </td>
      <td>
        <div class="result"></div>
      </td>
    </tr>
    <tr>
      <td>Article 2</td>
      <td><input type="text" hidden="true" value="1" class="price">1.00€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" class="change-quantity" data-amount="-1">-</button>
          <input type="number" class="quantity" value="0" min="0" max="3" />
          <button type="button" class="change-quantity" data-amount="1">+</button>
        </div>
      </td>
      <td>
        <div class="result"></div>
      </td>
    </tr>
    <tr>
      <td>Article 3</td>
      <td><input type="text" hidden="true" value="3.8" class="price">3.80€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" class="change-quantity" data-amount="-1">-</button>
          <input type="number" class="quantity" value="0" min="0" max="3" />
          <button type="button" class="change-quantity" data-amount="1">+</button>
        </div>
      </td>
      <td>
        <div class="result"></div>
      </td>
    </tr>
    <tr>
      <td>Article 4</td>
      <td><input type="text" hidden="true" value="1" class="price">1.00€</td>
      <td>
        <div class="quantity buttons_added">
          <button type="button" class="change-quantity" data-amount="-1">-</button>
          <input type="number" class="quantity" value="0" min="0" max="3" />
          <button type="button" class="change-quantity" data-amount="1">+</button>
        </div>
      </td>
      <td>
        <div class="result"></div>
      </td>
    </tr>
  </table>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
-1

Ok so I actually fixed my problem thanks to empiric, here's what i did :

for (var i = 0; i < ids.length; i++) {
            if (ids[i]%2) {
                if(quant != 0){
                    total = total-(tot/quant);
                    $("#total").html("Total : "+total.toFixed(2)+"€");
                }
                else {
                    total = total-(quant*1+price);
                    $("#total").html("Total : "+total.toFixed(2)+"€");
                }
            }
            else {
                return false;
            }

        }

I prevented quant go get to 0 to prevent the division by 0, than added a condition to remove the price once from my total.

Thanks guys for your help :)