Laravel中通过复选框实现商品列表筛选的实现方法
Laravel 原生表单实现商品筛选方案
全程不依赖jQuery、Ajax等第三方前端库,通过原生GET表单提交+后端查询过滤实现需求,页面中@foreach会自动渲染符合筛选条件的商品。
修正前端表单结构
你现有代码存在3个问题:店铺、价格筛选控件不在表单内,选中后不会提交参数;价格排序用复选框会出现同时选升降序的逻辑冲突;分类复选框的name格式不支持多选传值。
将所有筛选控件统一放入同一个GET表单,修正后的侧边栏筛选区代码如下:
<div class="p-2 w-3/12 bg-red-100 mt-4 h-fit flex flex-col"> <h3 class=" p-2 m-auto text-2xl w-10/12 border-b border-black ">Verfijnen</h3> <form action="{{route('articles.index')}}" method="GET" id="filterForm"> <ul class="p-2 text-xl "> <li class="p-2">Categorieën <ul> @foreach ($categories as $category) <li class="text-sm"> <input type="checkbox" id="cat_{{$category->id}}" name="categories[]" value="{{$category->id}}" onChange="document.getElementById('filterForm').submit()" {{ in_array($category->id, request()->get('categories', [])) ? 'checked' : '' }}> <label for="cat_{{$category->id}}">{{ $category->title }}</label> </li> @endforeach </ul> </li> <li class="p-2">Website <ul> @foreach ($websites as $website) <li class="text-sm"> <input type="checkbox" id="web_{{$website->id}}" name="websites[]" value="{{$website->id}}" onChange="document.getElementById('filterForm').submit()" {{ in_array($website->id, request()->get('websites', [])) ? 'checked' : '' }}> <label for="web_{{$website->id}}">{{ $website->title }}</label> </li> @endforeach </ul> </li> <li class="p-2">Prijs <ul> <li class="text-sm"> <input type="radio" id="LnH" name="price_sort" value="asc" onChange="document.getElementById('filterForm').submit()" {{ request()->get('price_sort') == 'asc' ? 'checked' : '' }}> <label for="LnH">Laag naar Hoog</label> </li> <li class="text-sm"> <input type="radio" id="HnL" name="price_sort" value="desc" onChange="document.getElementById('filterForm').submit()" {{ request()->get('price_sort') == 'desc' ? 'checked' : '' }}> <label for="HnL">Hoog naar Laag</label> </li> </ul> </li> </ul> </form> </div>
关键调整点:
- 分类、店铺复选框的name用数组格式(
categories[]/websites[]),支持多选参数传递- 价格排序改用单选框,避免逻辑冲突
- 所有筛选项选中后通过原生JS触发表单提交,无第三方依赖
- 增加选中状态回显逻辑,页面重载后之前选择的筛选项会保持选中
- 修正了原代码中ul直接嵌套ul的不规范HTML写法
后端筛选逻辑实现
在对应路由的控制器方法中,根据前端提交的GET参数动态组装商品查询条件,最终将过滤排序后的数据集传给视图,@foreach就只会渲染符合要求的商品。
控制器代码示例(基于Laravel框架):
public function index(Request $request) { // 侧边栏所需的分类、店铺全量数据 $categories = Category::all(); $websites = Website::all(); // 初始化商品查询构造器 $articlesQuery = Article::query(); // 分类筛选:选中分类时,只查询对应分类下的商品 if ($request->has('categories') && is_array($request->categories)) { $articlesQuery->whereIn('category_id', $request->categories); } // 店铺筛选:选中店铺时,只查询对应店铺的商品 if ($request->has('websites') && is_array($request->websites)) { $articlesQuery->whereIn('website_id', $request->websites); } // 价格排序:根据选中项按价格升序/降序排列 if ($request->get('price_sort') === 'asc') { $articlesQuery->orderBy('prijs', 'asc'); } elseif ($request->get('price_sort') === 'desc') { $articlesQuery->orderBy('prijs', 'desc'); } // 获取最终处理后的商品列表 $articles = $articlesQuery->get(); return view('article-list', compact('categories', 'websites', 'articles')); }
运行逻辑说明
- 未选择任何筛选项时,查询不附加过滤条件,默认返回全部商品,和原有默认展示逻辑一致
- 用户勾选任意筛选项后,表单自动提交参数到后端,后端完成过滤排序后重新渲染页面
- 视图中
@foreach拿到的$articles已经是符合条件的商品集合,无需额外修改循环代码 - 筛选参数会拼接在URL中,用户刷新页面也不会丢失筛选状态
内容的提问来源于stack exchange,提问作者Stef Verniers
相关产品推荐
相关产品推荐

