Laravel实现点击搜索按钮无页面刷新展示查询结果
Laravel 无刷新搜索实现方案
现有代码问题
- 表单
action属性缺少闭合双引号,会导致请求地址解析错误 - 前后端参数名不匹配:前端下拉框
name属性为filter_category、filter_country,后端读取的是category、country,会导致参数获取失败 - 未拦截默认表单提交逻辑,点击按钮会触发页面跳转
- 页面未预留结果渲染容器,无法在当前页插入返回的搜索结果
- 后端查询逻辑未覆盖两个筛选条件都为空的边界场景,且多层
if-else写法冗余
分步修改
1. 修正表单基础属性、添加结果容器
首先补上表单action的闭合引号,再在现有表单代码下方,加入用于渲染搜索结果的区块:
<form class="new_is" id="lets_search" action="{{route('advanced-search.show','searchInfluencer')}}" method="GET"> <!-- 原有表单内容保持不变 --> </form> <!-- 搜索结果渲染容器 --> <div id="search-result" class="row mt-4"></div>
2. 修正后端控制器逻辑
优化查询写法,修正参数匹配问题,补全边界场景处理:
public function searchInfluencer(Request $request) { // 参数名和前端保持一致 $category = $request->get('filter_category'); $country = $request->get('filter_country'); $influencers = Influencer::query() ->when($category, function($query) use ($category) { $query->where('category_id', $category); }) ->when($country, function($query) use ($country) { $query->where('country_id', $country); }) ->get(); // 方案1:返回纯JSON,前端自行拼接DOM return response()->json($influencers); // 方案2(推荐):返回渲染好的HTML片段,前端无需拼接复杂DOM // return view('partials.influencer_list', compact('influencers'))->render(); }
如果选择方案2,需要新建局部视图文件resources/views/partials/influencer_list.blade.php,写入结果渲染模板:
@if($influencers->isEmpty()) <div class="col-12 text-center">未找到匹配的达人</div> @else @foreach($influencers as $influencer) <div class="col-md-4 mb-3"> <div class="card"> <div class="card-body"> <h5 class="card-title">{{ $influencer->name }}</h5> <!-- 按需补充其他展示字段 --> </div> </div> </div> @endforeach @endif
3. 添加前端AJAX交互逻辑
在页面引入jQuery后(Laravel默认自带),加入以下JS代码,实现无刷新请求和结果渲染:
$(document).ready(function() { $('#filter').on('click', function(e) { e.preventDefault(); // 获取筛选参数 const requestData = { filter_category: $('#filter_category').val(), filter_country: $('#filter_country').val() }; $.ajax({ url: "{{ route('advanced-search.show','searchInfluencer') }}", type: 'GET', data: requestData, // 如果用返回HTML的方案,把dataType改成'html' dataType: 'json', beforeSend: function() { // 加loading状态防止重复提交 $('#filter').attr('disabled', true).text('搜索中...'); $('#search-result').html('<div class="col-12 text-center">加载中...</div>'); }, success: function(res) { // 选JSON返回方案时用这段拼接逻辑 let html = ''; if (!res.length) { html = '<div class="col-12 text-center">未找到匹配结果</div>'; } else { res.forEach(item => { html += ` <div class="col-md-4 mb-3"> <div class="card"> <div class="card-body"> <h5 class="card-title">${item.name}</h5> </div> </div> </div> `; }); } $('#search-result').html(html); // 选HTML返回方案时直接替换内容即可,注释掉上面的拼接逻辑,打开下面这行 // $('#search-result').html(res); }, error: function() { $('#search-result').html('<div class="col-12 text-center text-danger">搜索请求失败,请重试</div>'); }, complete: function() { // 恢复按钮状态 $('#filter').attr('disabled', false).text('Search'); } }); }); });
补充说明
- GET请求无需额外配置CSRF令牌,可直接发起请求
- 如果需要下拉框选值后自动触发搜索,只要把点击事件改成
$('#filter_category, #filter_country').on('change', function() {})即可,逻辑和点击搜索按钮完全一致 - 前端拼接DOM时按照实际业务需要的样式调整结构即可
内容的提问来源于stack exchange,提问作者hassanezz
相关产品推荐
相关产品推荐

