如何在Laravel 8的表单中实现联动下拉选择框,数据取自PostgreSQL数据库
Laravel 8 动态联动下拉选择框实现方案
前置说明
本方案适配PostgreSQL数据源,默认假设你已有两张关联表(示例用省份provinces、城市cities表演示,cities表通过外键province_id关联provinces.id),你可以根据实际业务替换为自己的表名和关联字段。
实现步骤
1. 定义模型关联
在一级下拉对应模型(示例为App\Models\Province)中添加一对多关联:
public function cities() { return $this->hasMany(City::class); }
2. 新增路由
在routes/web.php中添加路由配置:
// 加载表单页面,初始化一级下拉选项 Route::get('/form', [SelectController::class, 'index']); // 二级下拉数据查询接口 Route::get('/get-child-options/{parentId}', [SelectController::class, 'getChildOptions']);
3. 编写控制器逻辑
执行命令创建控制器:php artisan make:controller SelectController
控制器完整代码:
namespace App\Http\Controllers; use App\Models\Province; use App\Models\City; use Illuminate\Http\Request; class SelectController extends Controller { public function index() { // 获取一级下拉所有选项,按名称排序 $parentOptions = Province::orderBy('name', 'asc')->get(); return view('form', compact('parentOptions')); } public function getChildOptions($parentId) { // 校验参数合法性 if (!is_numeric($parentId)) { return response()->json([]); } // 根据父级ID查询关联的子级选项 $childOptions = City::where('province_id', $parentId) ->orderBy('name', 'asc') ->get(['id', 'name']); return response()->json($childOptions); } }
4. 编写表单视图
在resources/views/form.blade.php中添加下拉框结构和交互逻辑:
下拉框HTML结构
<!-- 一级下拉 --> <div class="form-group"> <label>一级选项</label> <select id="parent-select" class="form-control"> <option value="">请选择</option> @foreach($parentOptions as $option) <option value="{{ $option->id }}">{{ $option->name }}</option> @endforeach </select> </div> <!-- 二级下拉 --> <div class="form-group"> <label>二级选项</label> <select id="child-select" class="form-control" disabled> <option value="">请先选择一级选项</option> </select> </div>
交互JS代码(原生JS版本,无需引入jQuery)
const parentSelect = document.getElementById('parent-select'); const childSelect = document.getElementById('child-select'); parentSelect.addEventListener('change', async () => { const parentId = parentSelect.value; // 清空二级下拉原有选项 childSelect.innerHTML = '<option value="">请选择</option>'; if (!parentId) { childSelect.disabled = true; return; } try { const res = await fetch(`/get-child-options/${parentId}`); const childOptions = await res.json(); if (childOptions.length > 0) { childOptions.forEach(option => { const opt = document.createElement('option'); opt.value = option.id; opt.textContent = option.name; childSelect.appendChild(opt); }); childSelect.disabled = false; } else { childSelect.innerHTML = '<option value="">暂无可用选项</option>'; } } catch (e) { console.error('数据加载失败', e); } });
注意事项
- Laravel查询构造器已兼容PostgreSQL语法,数据库层不需要做额外适配
- 可根据业务需求添加查询缓存、接口限流优化性能
- 如果需要多级联动,按照相同逻辑扩展路由、控制器查询逻辑和前端监听事件即可
内容的提问来源于stack exchange,提问作者Mathias VEN'KPE
相关产品推荐
相关产品推荐

