如何在 laravel 中使用 ajax 更新购物车商品数量?

How to update cart item quantitty with ajax in laravel?

我想通过点击按钮increment/decrement购物车数量。看这张图 preview image

此购物车行由 forcach 循环显示。第一行运行良好。问题是,当我点击 seceond/last 行时,我只得到第一行的值。我不知道如何解决。这是查看代码

    @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

这是ajax代码

    $(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,
            },

这是我的控制器代码

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

    ]);

谁能告诉我如何解决这个问题?

这是问题所在:

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

jQuery 每次使用 class .input-quantity 获取 第一项的值,因为你已经使用了这个:

$('.input-quantity') 

所以你应该告诉它把相关项目的值传递给点击的项目:

$(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
    ....

}

我也没有发现你在任何地方设置了 id!所以你可以像这样设置为数据属性:

<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">

那么你可以使用这个代码:

$(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");
    ....

}

您必须考虑到您已经为一个元素使用了两次 class

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

那是绝对错误的

您应该使用触发式 event 来发挥您的优势,同时尝试确定要在 ajax 函数中查询哪些元素的值。 event 有几个对您有用的属性 - 在这种情况下,可以说最有用的是 target 属性,它标识调用事件的特定 DOM 元素。

问题中提供的 HTML 无效 - 隐藏输入不能合法存在于 table 行之间 - 它必须位于 table 单元格中,这就是我移至行中的第一个单元格(在循环内)

@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

    

并对 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)
    });

然而,这是未经测试的,因此对于任何小错误深表歉意...