0

I have this function and I have a row with price and number of attendees to choose from. I'm trying to calculate the sum of all price based on the value chosen from attendee (1,2,3,4,...) on change / select.

function paymentTicketChanges() {
  var sumTicketAttendee = 0;
  var sumTicketPrice = 0;

  $('.ticketing-row').each(function(index, el) {
    var me = $(this);
    var attendee = me.find('.payment_number_attendees').val();
    var price = me.find('.payment_ticket_price').val();

    if ((attendee >= 1) && (price >= 1)) {
      sumTicketPrice += Number(price);
      sumTicketAttendee += Number(attendee);
    }

  });

  $('.payment_ticket_total span').text(sumTicketPrice * sumTicketAttendee);
  $('.card-payment #amount').val(sumTicketPrice * sumTicketAttendee);
}

Just a bit lot on how to get the accurate result. Its multiplying the total result

Soolie
  • 1,812
  • 9
  • 21
Shina
  • 2,019
  • 2
  • 19
  • 25
  • You need to add your HTML and show us a working [mcve] so that we can help you. – Soolie Nov 21 '17 at 16:05
  • 2
    So, just to point something out. You're doing `>=` on two variables, and later you are turning them into numbers. Does that seem strange to you? – Taplar Nov 21 '17 at 16:05
  • Yep, you don't need the `Number()` part. Just `+=` will do the trick. – Soolie Nov 21 '17 at 16:07
  • @Soolie no.... val() returns strings. – Taplar Nov 21 '17 at 16:07
  • @Taplar wow, nice catch :) – Shina Nov 21 '17 at 16:07
  • 1
    @Shina You're performing `>=` against string values is my point. – Taplar Nov 21 '17 at 16:08
  • 1
    @Taplar Ouch... Didn't expect that. – Soolie Nov 21 '17 at 16:09
  • 1
    @Taplar: While it's true `val` always returns a string (well, or `undefined` if you call it on an empty jQuery set), both `s >= n` where `n` is a number will coerce `s` to number, and `x * y` will coerce both `x` and `y` to number. Not a good idea to rely on it, of course. :-) Too easy to slip a `+` in there and get bit. – T.J. Crowder Nov 21 '17 at 16:14

1 Answers1

2

You're multiplying the sum of all prices by the sum of all attendees. You want to do the multiplication per row:

function paymentTicketChanges() {
  var total = 0;

  $('.ticketing-row').each(function(index, el) {
    var me = $(this);
    // Convert to number early, note the +
    var attendees = +me.find('.payment_number_attendees').val();
    var price = +me.find('.payment_ticket_price').val();

    if ((attendees >= 1) && (price >= 1)) {
      // Do the sum here, add to total
      total += attendees * price;
    }
  });

  // Use total
  $('.payment_ticket_total span').text(total);
  $('.card-payment #amount').val(total);
}

Perhaps use .toFixed(2) on total at the end.

Live Example:

$("input").on("input", paymentTicketChanges);
paymentTicketChanges();
function paymentTicketChanges() {
  var total = 0;

  $('.ticketing-row').each(function(index, el) {
    var me = $(this);
    // Convert to number early, note the +
    var attendees = +me.find('.payment_number_attendees').val();
    var price = +me.find('.payment_ticket_price').val();

    if ((attendees >= 1) && (price >= 1)) {
      // Do the sum here, add to total
      total += attendees * price;
    }
  });

  // Use total
  $('.payment_ticket_total span').text(total.toFixed(2));
  $('.card-payment #amount').val(total.toFixed(2));
}
<table>
  <tbody>
    <tr>
      <th>Attendees</th>
      <th>Price</th>
    </tr>
    <tr class="ticketing-row">
      <td><input class="payment_number_attendees" value="2"></td>
      <td><input type="text" class="payment_ticket_price" value="29.99"></td>
    </tr>
    <tr class="ticketing-row">
      <td><input type="text" class="payment_number_attendees" value="3"></td>
      <td><input class="payment_ticket_price" value="10.00"></td>
    </tr>
  </tbody>
</table>
<div class="payment_ticket_total">Total: <span></span></div>
<div class="card-payment">Amount: <input type="text" id="amount"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Side note: Beware JavaScript numbers and financial amounts (see: Is floating point math broken?).

Side note 2: There are lots of ways to convert to number from string. All of the built-in ones have some kind of downside (parseInt and parseFloat stop on the first invalid character instead of failing, Number and + treat "" as though it were 0). Here's where I've ended up on it, FWIW:

function toNumber(str) {
    str = str.trim();
    return str === "" ? NaN : +str;
}

Side note 3: They're harmless, but the inner () in your if are completely unnecessary. :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875