You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用jQuery Ajax实现动态商品筛选的问题求助

商品筛选Ajax功能问题解决方案

一、解决apply_filter参数为空的问题

问题原因

表单中使用多个type="submit"按钮时,$(this).serialize()不会自动包含被点击按钮的name和value——jQuery的serialize()方法仅序列化表单中的输入类控件(如input、select等),提交按钮的参数不会被默认加入序列化数据。

解决办法

方案1:改用单选框+标签触发

修改视图中的分类选择部分,用隐藏单选框存储分类值,点击标签触发选中并提交表单:

@foreach($categories as $category)
    <label class="flex justify-between capitalize text-slate-600 font-semibold text-start gap-1 w-full mx-2 p-1 rounded-lg hover:bg-slate-300 cursor-pointer">
        <input type="radio" name="apply_filter" value="{{$category->name}}" class="hidden">
        {{$category->name}}
    </label>
@endforeach
<button type="submit" class="mt-2 px-4 py-1 bg-blue-500 text-white rounded">筛选</button>

方案2:提交时手动注入按钮值

保留原按钮结构,修改JS代码,记录点击的按钮值并手动添加到请求数据:

$(document).ready(function (e) {
    let clickedCate = '';
    // 记录点击的分类按钮值
    $('#filter_form button[name="apply_filter"]').click(function(){
        clickedCate = $(this).val();
    });

    $('#filter_form').submit(function (e){
        e.preventDefault();
        // 序列化表单并追加分类值
        let formData = $(this).serialize() + '&apply_filter=' + clickedCate;
        
        $.ajax({
            url: "{{route('product.filter.post')}}",
            type: "POST",
            data: formData,
            success: function (response){
                updateProductGallery(response.product);
            },
            error: function(error) {
                console.log('Error', error);
            }
        });
    });
});

同时优化控制器参数获取逻辑,增加容错处理:

public function getProductByCategory(Request $request)
{
    if($request->ajax()){
        $choosen_cate = $request->input('apply_filter', '');
        if(empty($choosen_cate)){
            $products = Product::all();
        }else{
            $categoryId = ProductCategory::where('name', $choosen_cate)->value('id');
            $products = Product::where('category_id', $categoryId)->get();
        }
        return response()->json(['product' => $products]);
    }
}

二、解决Ajax返回后更新商品展示的问题

步骤1:重构视图容器

修正原视图中重复的id,将商品列表单独提取为可替换容器:

<div id="product_container" class="w-full bg-gradient-to-r from-[#0066C1] to-cyan-500 rounded-md">
    <div class="mx-12 my-3 text-start text-slate-100 text-lg uppercase font-semibold">
        Home >>
        <span id="current_category" class="capitalize">All</span>
    </div>
    <!-- 商品列表专属容器 -->
    <div id="product_list" class="shadow-xl product-wrapper min-h-[724px] bg-white mx-12 grid grid-cols-4 justify-items-center p-3 gap-3 mb-10 rounded-lg">
        @foreach($products as $product)
            <!-- 原有商品卡片代码 -->
        @endforeach
    </div>
</div>

步骤2:编写商品更新函数

在JS中添加函数,遍历返回数据生成HTML并替换容器内容:

function updateProductGallery(products){
    let productHtml = '';
    if(products.length === 0){
        // 无商品提示
        productHtml = '<div class="shadow-xl flex justify-center items-center product-wrapper min-h-[724px] bg-white mx-12 p-3 gap-3 mb-10 rounded-lg">' +
            '<p class="uppercase text-slate-300 font-semibold">There aren\'t any available products currently</p>' +
        '</div>';
    }else{
        // 遍历生成商品卡片
        products.forEach(function(product){
            productHtml += '<div class="product-card w-fit bg-white h-fit flex flex-col shadow-xl rounded-lg">' +
                '<a href="/product_detail/' + product.id + '"><img class="w-60 h-60" src="' + product.image + '"></a>' +
                '<p class="uppercase font-semibold text-center">' + product.name + '</p>' +
                '<p class="text-[#1998EC] font-bold text-xl">' + product.price + ' $</p>' +
                '<p class="text-slate-400 text-xs line-through">1000.000$</p>' +
                '<div class="flex flex-row justify-between text-sm px-2 mb-2">' +
                    '<div>' +
                        '<p class="text-[#0DB866] font-semibold"><i class="fa-solid fa-square-check"></i> Còn hàng</p>' +
                        '<p class="text-slate-400"><i class="fa-solid fa-gift"></i> Quà tặng</p>' +
                    '</div>' +
                    '<div>' +
                        '<form action="/add_cart/' + product.id + '" method="POST">' +
                            '@csrf' +
                            '<button class="h-full bg-gradient-to-r from-blue-500 to-blue-300 rounded-full text-white px-5"><i class="fa-solid fa-cart-shopping"></i></button>' +
                        '</form>' +
                    '</div>' +
                '</div>' +
            '</div>';
        });
    }
    // 更新商品列表
    $('#product_list').html(productHtml);
    // 更新当前分类显示
    $('#current_category').text(products.length ? products[0].category.name : 'All');
}

步骤3:在Ajax回调中调用更新函数

修改Ajax的success回调,触发页面更新:

success: function (response){
    updateProductGallery(response.product);
},

额外优化建议

  1. 路由拆分:避免POST与GET请求共用同一路径,修改路由为:
Route::post('/product/filter', [HomeManager::class, 'getProductByCategory'])->name('product.filter.post');

同步更新视图中form的action与JS中的url。

  1. 移除重复ID:原视图中存在两个id="product_gallery",需确保DOM元素ID唯一。

内容的提问来源于stack exchange,提问作者Gia Khánh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:37:05