求助:实现多级联动下拉菜单的数据库数据动态获取功能
解决四级联动下拉菜单的动态数据加载问题
看起来你已经搭好了基础的联动框架,但在参数传递、事件绑定和SQL查询逻辑上有几个关键问题,我帮你梳理并修正这些问题,实现完整的「时间→线路→巴士→未预订座位」联动功能:
第一步:补全并优化HTML结构
你的HTML里缺失了巴士编号的下拉控件,同时给所有下拉框添加默认提示选项并初始禁用,提升用户体验:
<label id="label" for="schdtime">Schedule Time</label> <select id="schdtime" name="schdtime" style="margin-right: 15px;"> <option value="">Choose Time</option> <option value="5:30 AM">5:30 AM</option> <option value="7:30 AM">7:30 AM</option> <option value="9:30 AM">9:30 AM</option> <option value="11:30 AM">11:30 AM</option> <option value="12:30 PM">12:30 PM</option> <option value="1:30 PM">1:30 PM</option> <option value="3:30 PM">3:30 PM</option> <option value="5:00 PM">5:00 PM</option> </select> <label id="label" for="brnch">Route</label><br> <select id="brnch" name="brnch" disabled> <option value="">Choose Route</option> </select> <label id="label" for="busnum">Bus Number</label> <select id="busnum" name="busnum" disabled> <option value="">Choose Bus</option> </select> <label id="label">Seat Number</label> <select id="seatnum" name="seatnum" style="width: 100px;" disabled> <option value="">Choose Seat</option> </select>
第二步:修正AJAX逻辑(修复事件绑定与参数传递)
你的AJAX代码存在事件绑定错误、变量名不一致和选择器拼写问题,修正后的ajax.js:
$(document).ready(function() { // 选择时间后加载对应线路 $(document).on('change','#schdtime', function() { var schdtime = $(this).val(); // 重置后续所有下拉框状态 $("#brnch, #busnum, #seatnum").attr('disabled','disabled').html("<option value=''>Choose</option>"); if(schdtime != "") { $.ajax({ url:"get_data.php", type:'POST', data:{schdtime:schdtime}, success:function(response) { if(response != '') { $("#brnch").removeAttr('disabled').html(response); } else { $("#brnch").html("<option value=''>No routes available</option>"); } } }); } }); // 选择线路后加载对应时间+线路的巴士 $(document).on('change','#brnch', function() { var brnch = $(this).val(); var schdtime = $("#schdtime").val(); // 必须同时传入时间参数 $("#busnum, #seatnum").attr('disabled','disabled').html("<option value=''>Choose</option>"); if(brnch != "" && schdtime != "") { $.ajax({ url:"get_data.php", type:'POST', data:{brnch:brnch, schdtime:schdtime}, success:function(response) { if(response != '') { $("#busnum").removeAttr('disabled').html(response); } else { $("#busnum").html("<option value=''>No buses available</option>"); } } }); } }); // 选择巴士后加载未预订座位 $(document).on('change','#busnum', function() { var busnum = $(this).val(); $("#seatnum").attr('disabled','disabled').html("<option value=''>Choose</option>"); if(busnum != "") { $.ajax({ url:"get_data.php", type:'POST', data:{busnum:busnum}, success:function(response) { if(response != '') { $("#seatnum").removeAttr('disabled').html(response); } else { $("#seatnum").html("<option value=''>No seats available</option>"); } } }); } }); });
第三步:完善PHP后端逻辑(修正查询与参数处理)
你的PHP代码缺少时间筛选、座位查询逻辑,同时存在SQL注入风险,修正后的get_data.php:
<?php include('includes/connection.php'); // 处理时间选择,加载对应时段的线路 if (isset($_POST['schdtime'])) { $schdtime = mysqli_real_escape_string($conn, $_POST['schdtime']); // 假设branch表有schedule_time字段存储出发时间,需根据你的实际表结构调整 $qry1 = "SELECT * FROM branch WHERE schedule_time = '$schdtime'"; $res = mysqli_query($conn, $qry1); if(mysqli_num_rows($res) > 0) { echo '<option value="">Choose Route</option>'; while($row = mysqli_fetch_object($res)) { echo '<option value="'.$row->Br_Name.'">'.$row->Br_Name.'</option>'; } } else { echo '<option value="">No routes for this time</option>'; } } // 处理线路选择,加载对应时间+线路的巴士 if (isset($_POST['brnch']) && isset($_POST['schdtime'])) { $brnch = mysqli_real_escape_string($conn, $_POST['brnch']); $schdtime = mysqli_real_escape_string($conn, $_POST['schdtime']); // 假设bus表关联branch和schedule_time,需根据实际表结构调整 $qry2 = "SELECT * FROM bus WHERE Bus_Branch = '$brnch' AND schedule_time = '$schdtime'"; $res = mysqli_query($conn, $qry2); if(mysqli_num_rows($res) > 0) { echo '<option value="">Choose Bus</option>'; while($row = mysqli_fetch_object($res)) { $spc = ' '; echo '<option value="'.$row->Bus_Plate_Number.'">'.$row->Bus_Plate_Number. $spc .$row->Bus_Class.'</option>'; } } else { echo '<option value="">No buses available</option>'; } } // 处理巴士选择,加载未预订座位 if(isset($_POST['busnum'])) { $busnum = mysqli_real_escape_string($conn, $_POST['busnum']); // 1. 获取该巴士的总座位数(假设bus表有total_seats字段) $get_total = mysqli_query($conn, "SELECT total_seats FROM bus WHERE Bus_Plate_Number = '$busnum'"); $total_row = mysqli_fetch_assoc($get_total); $total_seats = $total_row['total_seats'] ?? 15; // 默认15个座位 // 2. 获取已预订的座位号(假设booking表存储已订座位,字段为bus_plate和seat_number) $booked_seats = []; $get_booked = mysqli_query($conn, "SELECT seat_number FROM booking WHERE bus_plate = '$busnum'"); while($b_row = mysqli_fetch_assoc($get_booked)){ $booked_seats[] = $b_row['seat_number']; } // 3. 生成未预订的座位选项 echo '<option value="">Choose Seat</option>'; for($i=1; $i<=$total_seats; $i++){ if(!in_array($i, $booked_seats)){ echo '<option value="'.$i.'">'.$i.'</option>'; } } // 无可用座位时的提示 if(count($booked_seats) == $total_seats){ echo '<option value="">No seats available</option>'; } } ?>
关键修改说明
- HTML优化:补全缺失的巴士下拉框,给所有下拉框添加默认提示并初始禁用,引导用户按顺序选择。
- AJAX修正:
- 修复多选择器绑定错误,移除无效的空选择器操作
- 线路选择时同时传递时间和线路参数,确保巴士数据的准确性
- 每次切换上级选项时,自动重置后续下拉框的状态
- 修正变量名不一致和选择器拼写错误(
$("$seatnum")→$("#seatnum"))
- PHP逻辑完善:
- 给线路查询添加时间筛选条件(需根据你的实际表字段调整)
- 巴士查询同时接收时间和线路参数,返回对应时段的线路巴士
- 添加未预订座位的查询逻辑:先获取总座位数,再排除已预订座位生成可用选项
- 统一使用
mysqli_real_escape_string防止SQL注入(更推荐使用预处理语句,可后续优化)
内容的提问来源于stack exchange,提问作者gellooo
相关产品推荐
相关产品推荐

