jQuery code to total the items in a shopping cart
this part of code  var id = $('.quant').attr('data-id');
  


Presuming there are multiple inputs with class "quant" (perhaps 1 for each row in the table), then this code will get a collection of elements and then as is desribed in the documentation for .attr():


  Get the value of an attribute for the first element in the set of matched elements or set one or more attributes for every matched element.


So yes it will get the value of the data-id attribute of the first element with that class name.

Consider the following snippet (try running it to see the result):



//find all elements with class name "quant"
var inputsWithClassQuant = $('.quant');
console.log('inputsWithClassQuant.length: ',inputsWithClassQuant.length);
//attr only returns attribute of first element:
console.log("inputsWithClassQuant.attr('data-id') (first element only): ",inputsWithClassQuant.attr('data-id'));
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;input type="text" data-id="30" data-price="20" value="3" class="quant" /&gt;
&lt;input type="text" data-id="35" data-price="10" value="0" class="quant" /&gt;
&lt;input type="text" data-id="36" data-price="15" value="2" class="quant" /&gt;





  
  Problem here:

var quantity;
$('#myTable &gt; tbody  &gt; tr').each(function () {
 quantity = $(this).find('.quant').val();
 ...
}

  


Yes, quantity = $(this).find('.quant').val(); overwrites the previous value each time so after the loop (i.e. the call to .each()), quantity will contain the value of the last element with class name quant.


  
  I was told that I pass first id and last quantity, but it is all present when I call function in $(document) - Please explain this to me.
  


This is basically a summary of points #1 and #2 above.

Perhaps a better implementation would move the code to call the AJAX request (i.e. to '/Cart/AddTocart') with the id and quantity of the row that changed, then call update() to update the total. Something like the code below.

Another suggestion is to update the request sent to the server to send the entire list of items with the respective quantities. That way, if a quantity is decreased or cleared, the cart can be accurately updated. It all depends on the back-end API - i.e. if it has endpoints to add/remove/update items with quantities, etc.

I also changed the input type of the quantity inputs to "Number" - that way only numbers can be entered, and many browsers will add up/down controls to the side of the input for the user to click on.



$(document).ready(function() {
  update();
  $(".quant").change(function() {
    //this: context of the input that was changed
    console.log('calling /Cart/AddTocart; id:',$(this).attr('data-id'),' quantity: ', $(this).val());
    $.get(
      '/Cart/AddTocart', {
        id: $(this).attr('data-id'),
        returnUrl: '',
        quantity: $(this).val()
      });
    update();
  });

  function update() {
    var sum = 0.0;
    var quantity;
    $('#myTable &gt; tbody  &gt; tr').each(function() {

      quantity = $(this).find('.quant').val();
      var price = parseFloat($(this).find('.price').attr('data-price').replace(',', '.'));
      var amount = (quantity * price);

      sum += amount;
      $(this).find('.amount').text('' + amount + ' грн');
    });
    $('.total').text(sum + ' грн');
  }
});
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;table id="myTable"&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th class="text-center"&gt;Товар&lt;/th&gt;
      &lt;th class="text-center"&gt;К-сть&lt;/th&gt;
      &lt;th&gt;Назва Товару&lt;/th&gt;
      &lt;th class="text-right"&gt;Ціна&lt;/th&gt;
      &lt;th class="text-right"&gt;Загальна ціна&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td class="text-center"&gt;&lt;/td&gt;
    &lt;td class="text-center"&gt;
      &lt;input type="number" data-id="97" data-price="30" value="1" class="quant" /&gt;
    &lt;/td&gt;
    &lt;td class="text-left"&gt;Kart&lt;/td&gt;
    &lt;td class="text-right price" data-price="30"&gt;30&lt;/td&gt;
    &lt;td class="text-right amount"&gt;30&lt;/td&gt;
    &lt;td&gt;
      &lt;input class="btn btn-sm btn-warning" type="submit" value="Видалити з кошику" /&gt; &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td class="text-center"&gt;&lt;/td&gt;
    &lt;td class="text-center"&gt;
      &lt;input type="number" data-id="99" data-price="60" value="0" class="quant" /&gt;
    &lt;/td&gt;
    &lt;td class="text-left"&gt;Kart&lt;/td&gt;
    &lt;td class="text-right price" data-price="10"&gt;10&lt;/td&gt;
    &lt;td class="text-right amount"&gt;30&lt;/td&gt;
    &lt;td&gt;
      &lt;input class="btn btn-sm btn-warning" type="submit" value="Видалити з кошику" /&gt; &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tfoot&gt;
    &lt;tr&gt;
      &lt;td colspan="4" class="text-right"&gt;&lt;b&gt;Всього до оплати:&lt;/b&gt;&lt;/td&gt;
      &lt;td id="test" class="text-right total"&gt;@Model.Cart.ComputeTotalValue().ToString("#.## грн")&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tfoot&gt;
&lt;/table&gt;