skip to Main Content

I want to increment/decrement cart quantity by clicking the button. See this image preview image

This cart row is shown by forcach loop. First row is working perfectly. The problem is, when I click on the seceond/last row, I get only first row value. I don’t know how to solve that. Here is view code

    @foreach ($carts as $cart)
                            <input type="hidden" name="cart_id" class="id" value="{{ $cart->id }}">
                            <tr class="woocommerce-cart-form__cart-item cart_item">
                                <td class="product-remove">
                                    <a href="#" class="remove" onclick="removeCart({{ $cart->id }})"
                                        aria-label="Remove this item">
                                        <span class="lnr lnr-cross-circle"></span>
                                    </a>
                                </td>

                                <td class="product-thumbnail">
                                    <a href="">
                                        <img src="{{ asset('/storage/items/food/' . $cart->FoodItem->image) }}"
                                            class="attachment-shop_thumbnail size-shop_thumbnail wp-post-image" alt="" /
                                            height="60" width="80">
                                    </a>
                                </td>

                                <td class="product-name" data-title="Product">
                                    <a href="shop-single.html">{{ $cart->FoodItem->name }}</a>
                                </td>

                                <td class="product-price" data-title="Price">
                                    <span class="woocommerce-Price-amount amount"><span
                                            class="woocommerce-Price-currencySymbol">$</span>{{ $cart->price }}</span>
                                </td>
                                <td class="product-quantity" data-title="Quantity">
                                    <div class="quantity">
                                        <input type="number" class="input-text qty text input-quantity "
                                            class="quantity" step="1" min="0" name="quantity[]"
                                            value="{{ $cart->quantity }}" title="Qty" size="4">
                                        <div class="icon">
                                            <a href="#" class="number-button  plus">+</a>
                                            <a href="#" class="number-button minus">-</a>
                                        </div>
                                    </div>
                                </td>
                                <td class="product-subtotal" data-title="Total">
                                    <span class="woocommerce-Price-amount amount"><span
                                            class="woocommerce-Price-currencySymbol">$</span> <span
                                            class="sum">{{ $cart->total_price }}</span></span>
                                </td>
                            </tr>
                        @endforeach

Here is ajax code

    $(document).on('click', '.qty', function(e) {
        e.preventDefault();

        var quantity = $('.input-quantity').val();  
        var id = $('.id').val();

          $.ajax({
            url: "url",
            method: "POST",
            dataType: "json",
            data: {
                _token: "{{ csrf_token() }}",

                quantity: quantity,
                id: id,
            },

Here my controller code

   $cart = Cart::findOrFail($id);
    $cart->update([
        'quantity'    => $request->quantity,
        'total_price' => $cart['price'] * $request->quantity,

    ]);

Can anyone tell me way how to solve that problem?

2

Answers


  1. Here is the problem:

        var quantity = $('.input-quantity').val();  
        var id = $('.id').val();
    

    jQuery fetch’s the value of the first item with class .input-quantity every time because you’ve used this:

    $('.input-quantity') 
    

    so you should tell it to pass the value for related item to the clicked item:

    $(document).on('click', '.qty', function(e) {
        e.preventDefault();
    
        // $(this) mentions the clicked element (target)
        var quantity = $(this).val();  // trasnlate: pass the value of the clicked  (target) element
        ....
    
    }
    

    Also I didn’t find you’ve set id anywhere! so you can set as as an data-attribute like this:

    <input data-id={{ $cart->id }} type="number" 
           class="input-text qty text input-quantity "
           step="1" min="0" name="quantity[]"
           value="{{ $cart->quantity }}" title="Qty" size="4">
    

    then you can use this code:

    $(document).on('click', '.qty', function(e) {
        e.preventDefault();
    
        // $(this) mentions the clicked element (target)
        var quantity = $(this).val();  // trasnlate: pass the value of the clicked  (target) element
        var id = $(this).attr("data-id");
        ....
    
    }
    

    You must consider that you’ve used class twice for an element:

    class="input-text qty text input-quantity "  class="quantity"
    

    that is absolutely wrong

    Login or Signup to reply.
  2. You should use the triggered event to your advantage whilst trying to identify which elements to query for values in your ajax function. The event has several properties which are useful to you – in this case arguably the most useful is the target property which identifies the specific DOM element that invoked the event.

    The HTML provided in the question is invalid – the hidden input cannot legitimately exist between table rows – it MUST be in a table cell which is why I moved to the first cell in the row (within the loop)

    @foreach ($carts as $cart)
    
        <tr class="woocommerce-cart-form__cart-item cart_item">
            <td class="product-remove">
            
                <!-- move thie hidden element to within a cell -->
                <input type="hidden" name="cart_id" class="id" value="{{ $cart->id }}">
                
                <a href="#" class="remove" onclick="removeCart({{ $cart->id }})" aria-label="Remove this item">
                    <span class="lnr lnr-cross-circle"></span>
                </a>
            </td>
    
            <td class="product-thumbnail">
                <a href="#">
                    <img src="{{ asset('/storage/items/food/' . $cart->FoodItem->image) }}" class="attachment-shop_thumbnail size-shop_thumbnail wp-post-image" alt="" / height="60" width="80">
                </a>
            </td>
    
            <td class="product-name" data-title="Product">
                <a href="shop-single.html">{{ $cart->FoodItem->name }}</a>
            </td>
    
            <td class="product-price" data-title="Price">
                <span class="woocommerce-Price-amount amount">
                    <span class="woocommerce-Price-currencySymbol">$</span>{{ $cart->price }}
                </span>
            </td>
            <td class="product-quantity" data-title="Quantity">
                <div class="quantity">
                    <input type="number" class="input-text qty text input-quantity" class="quantity" step="1" min="0" name="quantity[]" value="{{ $cart->quantity }}" title="Qty" size="4">
                    <div class="icon">
                        <a href="#" class="number-button  plus">+</a>
                        <a href="#" class="number-button minus">-</a>
                    </div>
                </div>
            </td>
            
            <td class="product-subtotal" data-title="Total">
                <span class="woocommerce-Price-amount amount">
                    <span class="woocommerce-Price-currencySymbol">$</span>
                    <span class="sum">{{ $cart->total_price }}</span>
                </span>
            </td>
            
        </tr>
    @endforeach
    
        
    

    And with a few minor changes to the javascript

    const getparent=function(evt,tag){
        let n=evt.target;
        while( n.tagName.toLowerCase()!==tag ) {
            if( n.nodeName==='BODY' )return false;
            n=n.parentNode;
        }
        return n;
    }
    
    $(document).on('change', '.qty', function(e) {
        e.preventDefault();
        let parent=getparent(e,'tr');
    
        var quantity = e.target.value;  
        var id = parent.querySelector('td input[ name="cart_id" ]').value;
    
          $.ajax({
            url: "url",
            method: "POST",
            dataType: "json",
            data: {
                _token: "{{ csrf_token() }}",
                quantity: quantity,
                id: id
            },
            success:(r)=>alert(r),
            error:(e)=>alert(e)
        });
    

    This is however untested so apologies for any minor errors…

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search