预约程序如何从数据库取值实现datepicker指定日期禁用功能
代码存在的核心问题
- 异步逻辑时序错误:
$.ajax是异步请求,beforeShowDay执行时请求还未返回,dates数组始终为空,判断逻辑不会生效;同时beforeShowDay在每一个日期渲染时都会触发,重复发起AJAX请求会产生严重的性能浪费。 - 数据格式不匹配:PHP返回的是包含
day属性的对象数组,你在JS的success回调中直接把整个data数组循环push到dates,没有取出对应日期字符串,indexOf匹配永远返回-1。 - 变量作用域错误:
dates数组定义在beforeShowDay内部,每次触发都会重置为空,就算异步请求返回结果也会被覆盖。
修复方案
第一步:优化PHP接口返回格式
直接返回日期字符串数组,减少前端数据处理成本:
// 修正后的load_days.php代码 $data = array(); $query = "SELECT * FROM events ORDER BY id"; $statement = $connect->prepare($query); $statement->execute(); $result = $statement->fetchAll(); foreach($result as $row) { // 直接存入日期字符串,无需包裹关联数组 $data[] = date("d-m-Y", strtotime($row["start_event"])); } echo json_encode($data);
第二步:调整JS逻辑,提前拉取禁用日期
将AJAX请求移到datepicker初始化外部,等拿到禁用日期列表后再初始化组件,避免异步时序问题:
// 修正后的JS代码 $( function() { // 先请求禁用日期列表,请求成功后再初始化日期选择器 $.ajax({ url:"load_days.php", type:"POST", dataType:"json", success:function(disabledDates) { $( "#datepicker" ).datepicker({ minDate: 2, maxDate: "1w", beforeShowDay: function(date) { const currentDateStr = jQuery.datepicker.formatDate('dd-mm-yy', date); // 不在禁用列表的日期才允许选择 return [ disabledDates.indexOf(currentDateStr) === -1 ]; } }); } }); } );
如果不想修改PHP原有返回格式,只需要在JS的success回调中先处理数据即可:
success:function(data) { // 提取所有day属性组成禁用日期数组 const disabledDates = data.map(item => item.day); // 后续初始化datepicker逻辑不变 }
内容的提问来源于stack exchange,提问作者Thomas Alkmaar
相关产品推荐
相关产品推荐

