[PHP][Laravel][AJAX] 基于Select2和AJAX的级联下拉菜单无法正常工作
问题描述
尝试使用Select2创建依赖级联下拉菜单,选择父级「服务组(group service)」时,子级「服务(service)」选项无法显示,相关代码如下:
1. 路由代码
Route::controller(TaskController::class)->prefix('dashboard/task')->middleware(['role:admin|operator|user-bisnis|user-qa'])->group(function () { Route::get('/', 'index'); Route::get('/create', 'create')->name('task.create'); Route::post('/', 'store')->name('task.store'); Route::get('/edit/{id}', 'edit')->name('task.edit'); Route::post('/update/{id}', 'update')->name('task.update'); Route::post('/delete/{id}', 'destroy')->name('task.delete'); Route::get('/groupservice', 'getGroupService')->name('groupservice.select'); Route::get('/service', 'getService')->name('service.select'); });
2. 控制器代码
public function getService(Request $request) { $service = []; $groupserviceID = $request->groupserviceID; if ($request->has('q')) { $search = $request->q; $service = Service::select("id", "nama") ->where('gruplayanan_id', $groupserviceID) ->Where('deskripsi', 'LIKE', "%$search%") ->get(); } else { $service = Service::where('gruplayanan_id', $groupserviceID)->limit(10)->get(); } return response()->json($service); }
3. 视图代码
JavaScript 部分
$(document).ready(function() { $('#gruplayanan_id').change(function() { //clear select $("#layanan_id").empty(); //set id let groupserviceID = $(this).val(); if (groupserviceID) { $('#layanan_id').select2({ allowClear: true, ajax: { url: "{{ route('service.select') }}?groupserviceID=" + groupserviceID, dataType: 'json', delay: 250, processResults: function(data) { return { results: $.map(data, function(item) { return { text: item.nama, id: item.id } }) }; } } }); } }); $('#gruplayanan_id').on('select2:clear', function(e) { $("#layanan_id").select2(); }); });
HTML 部分
<head> {{-- Select2 --}} <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css"> </head> <body> <div class="mb-3"> <label for="gruplayanan" class="form-label">Pilih Group Layanan</label><span style="color: red;">*</span> <select class="theSelect" name="gruplayanan_id" id="gruplayanan_id" style="width: 300px" autofocus required> <option hidden></option> @foreach ($groupservice as $item => $groupservice) <option value="{{ $groupservice->id }}">{{ $groupservice->deskripsi }}</option> @endforeach </select> </div> <div class="mb-3"> <label for="layanan" class="form-label">Pilih Layanan</label><span style="color: red;">*</span> <select class="theSelect" name="layanan_id" id="layanan_id" style="width: 300px" autofocus required> </select> </div> </body>
问题排查与解决办法
1. 修复重复初始化Select2的问题
每次父级下拉框变化时重新初始化子级Select2会导致组件状态混乱,应改为仅初始化一次,动态更新请求参数:
$(document).ready(function() { // 初始化父级Select2 $('#gruplayanan_id').select2({ allowClear: true, placeholder: "Pilih Group Layanan" }); // 初始化子级Select2,配置动态AJAX参数 $('#layanan_id').select2({ allowClear: true, placeholder: "Pilih Layanan", ajax: { url: "{{ route('service.select') }}", dataType: 'json', delay: 250, data: function(params) { return { q: params.term, groupserviceID: $('#gruplayanan_id').val() }; }, processResults: function(data) { return { results: $.map(data, function(item) { return { text: item.nama, id: item.id } }) }; } }, disabled: true // 初始禁用,选择父级后启用 }); // 父级选择变化时更新子级状态 $('#gruplayanan_id').on('change', function() { let groupserviceID = $(this).val(); let $layanan = $('#layanan_id'); if (groupserviceID) { $layanan.prop('disabled', false); $layanan.val(null).trigger('change'); // 清空并触发重新加载 } else { $layanan.prop('disabled', true); $layanan.val(null).trigger('change'); } }); // 父级清空时同步处理子级 $('#gruplayanan_id').on('select2:clear', function() { $('#layanan_id').val(null).prop('disabled', true).trigger('change'); }); });
2. 控制器参数验证与代码规范优化
添加参数验证避免SQL错误,同时统一代码风格:
public function getService(Request $request) { // 强制验证父级ID参数 $request->validate([ 'groupserviceID' => 'required|integer', ]); $groupserviceID = $request->groupserviceID; $query = Service::select("id", "nama")->where('gruplayanan_id', $groupserviceID); // 处理搜索关键词 if ($request->has('q')) { $search = $request->q; $query->where('deskripsi', 'LIKE', "%{$search}%"); } $service = $query->limit(10)->get(); return response()->json($service); }
3. 检查AJAX请求状态
打开浏览器开发者工具(F12)→ Network标签,选择父级服务组后:
- 确认请求URL是否携带正确的
groupserviceID参数 - 查看响应是否返回合法的JSON数据
- 检查是否存在404/500等错误状态码
内容的提问来源于stack exchange,提问作者ProgrammerWannabe
相关产品推荐
相关产品推荐

