Javascript function keeps retrieving data from last item in Model list in MVC

Viewed 43

I am trying to create functionality that will update a product's quantity in the users shop cart. I am able to populate the ViewModel with the relevant data and display it in a table in the View.

In the script tags, I have two functions, one to increase the quantity of the product and the other to decrease the quantity in increments of 1. Now all works well if there is one product in the list. I receive the correct values. As soon as there are two or more products in the list, whenever the increase or decrease functions are fired, the values (quantity and productId) of the last item in Model.Products are sent to the 'UpdateQuantity' ActionMethod, instead of the values from the inputs in the selected table row.

For example: If there are two products in the list. Product A (Id:1 and Quantity: 3) and Product B(ID:2 and quantity:5), If I click on either the increase or decrease buttons next to Product A's quantity input, the relevant function will pass Product B's values (2 and 5) to the Action Method instead of Product A's values (1 and 3).

I'm assuming that there is a naming convention issue, but I'm unable to figure out why this is happening. Any help would be highly appreciated.

Below is what I have so far:

ViewModel:

public class ShopCartViewModel : BaseViewModel
    {
        public List<OrderDetail> OrderDetailList { get; set; }
        public List<Order> OrderList { get; set; }
        public List<Product> Products { get; set; }           

    }

Controller:

    public List<Order> orderList = new List<Order>();
    public List<OrderDetail> orderDetailList = new List<OrderDetail>();
    public List<Product> productList = new List<Product>();

    public ActionResult Index()
    {
        ShopCartViewModel vm = new ShopCartViewModel();
        ConnectToDatabase();
        User u = Helpers.GetUser.GetUserDetails();

        orderList = GetAllOrdersForCustomer(u.Id);
        GetOrderDetails();            
        vm.OrderList = orderList;
        vm.OrderDetailList = orderDetailList;
        vm.Products = productList;

        return View(vm);


    }

    [HttpPost]
    public ActionResult UpdateQuantity(string quantity, string productId)
    {
        //do stuff here           

    }

View:

@foreach(var product in Model.Products)
{
 string class_quantity = "quantity_" + product.Id;
 string class_productId = "productId_" + product.Id;
<div class="quantity">
   <button class="dec-btn p-0" type="submit"><i class="fas fa-caret-left" onclick="q_dec()"></i></button>
   <input name="quantity" id="@class_quantity" class=" form-control" type="text" value="@product.Quantity" />
   <button class="inc-btn p-0" type="submit"><i class="fas fa-caret-right" onclick="q_inc()"></i></button>
   <input name="productId" id="@class_productId" class=" form-control" type="text" value="@product.Id" style="visibility:hidden" />
<script type="text/javascript">
    function q_inc(e) {
       var p_quantity = $("#@class_quantity").val();                                                                
       var final_quantity = parseInt(p_quantity) + 1;
       var p_productId = $("#@class_productId").val();

      $.ajax({

        url: '@Url.Action("UpdateQuantity","ShopCart")',
        type: 'POST',
        data: {quantity: final_quantity, productId: p_productId },
         success: function () {
            alert("Increase Success");

           }
          })
         }

     function q_dec(e) {                                                               

        var p_quantity = $("#@class_quantity").val();
                                                             
        if (p_quantity >= 2) {
        var final_quantity = parseInt(p_quantity) - 1;

        }                                                               
        var p_productId = $("#@class_productId").val();



        $.ajax({

         url: '@Url.Action("UpdateQuantity","ShopCart")',
         type: 'POST',
         data: {quantity: final_quantity, productId: p_productId },
          success: function () {
             alert("Decrease Success");

             }
           })
          }


       </script>



</div>
}
1 Answers

The problem with your code is that in your loop you are duplicating functions q_inc(e) and q_dec(e)

You should fix your code with something like this:

@foreach(var product in Model.Products)
{
 string class_quantity = "quantity_" + product.Id;
 string class_productId = "productId_" + product.Id;
<div class="quantity">
   <button class="dec-btn p-0" type="button" onclick="q_dec('@class_productId', '@class_quantity")'><i class="fas fa-caret-left"></i></button>
   <input name="quantity" id="@class_quantity" class=" form-control" type="text" value="@product.Quantity" />
   <button class="inc-btn p-0" type="button" onclick="q_inc('@class_productId', '@class_quantity')"><i class="fas fa-caret-right"></i></button>
   <input name="productId" id="@class_productId" class=" form-control" type="text" value="@product.Id" style="visibility:hidden" />
}

<script type="text/javascript">
    function q_inc(id, quantity) {
       var p_id = $("#" + id);
       var p_quantity = $("#" + quantity);
       var quantity_val = p_quantity.val()                                                             
       var final_quantity = parseInt(quantity_val) + 1;
       var p_productId = p_id.val();

      $.ajax({

        url: '@Url.Action("UpdateQuantity","ShopCart")',
        type: 'POST',
        data: {quantity: final_quantity, productId: p_productId },
         success: function () {
            alert("Increase Success");
            p_quantity.val(final_quantity);
           }
          })
         }

     function q_dec(id, quantity) {                                                               

       // change this function accordingly


       </script>
Related