Laravel9中如何用jQuery AJAX根据条件查询填充Select选项
解决动态加载指定日期可用预约时段的问题
问题根源
当前逻辑仅默认过滤当日的已预约时段,切换日期时没有重新请求后端获取对应日期的已预约数据,导致时段选择框没有动态更新。需要通过前端AJAX触发后端查询,返回指定日期的可用时段。
1. 确认数据库字段与关联
首先确保表结构包含必要字段:
appointments表需有appointment_date(存储预约日期,格式YYYY-MM-DD)字段slots表需有time_slot(存储时段字符串,如09:00-10:00)和appointment_id外键
模型关联保持原有配置:
// App\Models\Appointment.php public function slots() { return $this->hasMany(Slot::class); } // App\Models\Slot.php public function appointment() { return $this->belongsTo(Appointment::class); }
2. 添加后端API路由与控制器方法
路由(web.php)
新增GET路由用于获取指定日期的可用时段:
use App\Http\Controllers\AppointmentController; Route::get('/appointments/available-slots', [AppointmentController::class, 'getAvailableSlots'])->name('appointments.available-slots');
控制器方法(AppointmentController.php)
编写方法查询指定日期的已预约时段,从预设全时段列表中排除已预约项:
public function getAvailableSlots(Request $request) { $request->validate([ 'date' => 'required|date', ]); // 预设所有可预约时段(根据实际业务调整) $allSlots = [ '09:00-10:00', '10:00-11:00', '11:00-12:00', '14:00-15:00', '15:00-16:00', '16:00-17:00', ]; // 查询指定日期已被预约的时段 $bookedSlots = Appointment::whereDate('appointment_date', $request->date) ->with('slots') ->get() ->pluck('slots.*.time_slot') ->flatten() ->unique() ->toArray(); // 计算可用时段 $availableSlots = array_diff($allSlots, $bookedSlots); return response()->json(['slots' => $availableSlots]); }
3. 修改Blade视图,添加动态更新逻辑
在预约页面Blade文件中,给日期选择器绑定onchange事件,通过AJAX请求更新时段选择框:
<div class="form-group"> <label for="appointment_date">预约日期</label> <input type="date" id="appointment_date" name="appointment_date" class="form-control" value="{{ now()->format('Y-m-d') }}" required> </div> <div class="form-group"> <label for="time_slot">预约时段</label> <select id="time_slot" name="time_slot" class="form-control" required> <!-- 初始加载当日可用时段 --> @foreach($initialAvailableSlots as $slot) <option value="{{ $slot }}">{{ $slot }}</option> @endforeach </select> </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { // 加载指定日期的可用时段 function loadAvailableSlots(date) { $.ajax({ url: "{{ route('appointments.available-slots') }}", type: "GET", data: { date: date }, success: function(response) { const slotSelect = $('#time_slot'); slotSelect.empty(); // 清空现有选项 if (response.slots.length > 0) { response.slots.forEach(slot => { slotSelect.append(`<option value="${slot}">${slot}</option>`); }); } else { slotSelect.append('<option value="">该日期无可用时段</option>'); } }, error: function() { alert('加载可用时段失败,请重试'); } }); } // 日期选择变更时触发加载 $('#appointment_date').on('change', function() { const selectedDate = $(this).val(); loadAvailableSlots(selectedDate); }); }); </script>
补充:控制器传递初始时段到视图
在渲染预约页面的控制器方法中,传递当日的可用时段:
public function create() { $today = now()->format('Y-m-d'); $allSlots = [ '09:00-10:00', '10:00-11:00', '11:00-12:00', '14:00-15:00', '15:00-16:00', '16:00-17:00', ]; $bookedSlots = Appointment::whereDate('appointment_date', $today) ->with('slots') ->get() ->pluck('slots.*.time_slot') ->flatten() ->unique() ->toArray(); $initialAvailableSlots = array_diff($allSlots, $bookedSlots); return view('appointments.create', compact('initialAvailableSlots')); }
关键注意事项
- 确保
appointment_date字段格式与前端日期输入框返回的YYYY-MM-DD一致 - 如果时段是从
slots表预先配置的,可将$allSlots改为数据库查询语句 - 如需按科室过滤时段,可在API请求中添加科室参数,控制器查询时加入对应过滤条件
内容的提问来源于stack exchange,提问作者nabil1997
相关产品推荐
相关产品推荐

