使用MultiDatesPicker for jQuery UI实现跨选择器的已选日期动态禁用与恢复
MultiDatesPicker for jQuery UI实现跨选择器的已选日期动态禁用与恢复
这个需求我之前做类似项目时刚好实现过,核心思路就是实时同步其他选择器的已选日期,然后在每个日期显示前判断是否要禁用,给你详细拆解下具体步骤和代码:
核心思路
我们需要实现两个关键逻辑:
- 每次渲染日期选择器的日历面板时,自动过滤掉其他两个选择器已经选中的日期,让这些日期不可点击
- 当任意一个选择器添加/删除日期后,立即刷新另外两个选择器的面板,让禁用规则实时生效
具体实现代码
首先建议给所有日期选择器加一个共同的CSS类(比如date-picker-group),这样后续遍历操作会更方便,不用硬编码每个选择器的ID。
1. 定义工具函数:获取当前选择器外的所有已选日期
这个函数用来帮我们筛选出「除了当前操作的选择器之外」的所有已选日期,避免把当前选择器自己的已选日期也禁用了(毕竟用户要能取消自己选的日期):
function getOtherSelectedDates(excludePicker) { let otherDates = []; // 遍历所有同组的日期选择器 $('.date-picker-group').each(function() { const $currentPicker = $(this); // 跳过当前操作的选择器,收集其他选择器的已选日期 if ($currentPicker[0] !== excludePicker[0]) { // 用插件的getDates方法获取已选日期数组 const selected = $currentPicker.multiDatesPicker('getDates'); otherDates = otherDates.concat(selected); } }); // 把Date对象转成和你配置的dateFormat一致的字符串,方便后续匹配 return otherDates.map(date => $.datepicker.formatDate('d MM', date)); }
2. 初始化带禁用规则的日期选择器
修改你原来的初始化代码,加上beforeShowDay(控制日期是否可选)、onSelect(选择日期后刷新其他面板)、onRemove(删除日期后刷新其他面板)这三个关键配置:
// 假设你的i是从1到3的循环变量 for (let i = 1; i <= 3; i++) { const $picker = $('#dates' + i); // 给选择器加共同类 $picker.addClass('date-picker-group'); $picker.multiDatesPicker({ dateFormat: "d MM", minDate: 0, maxDate: 365, // 每个日期渲染前触发,控制是否可选 beforeShowDay: function(date) { const formattedCurrentDate = $.datepicker.formatDate('d MM', date); // 获取其他选择器的已选日期 const disabledDates = getOtherSelectedDates($picker); // 如果当前日期在禁用列表里,返回[false, 样式类, 提示语] if (disabledDates.includes(formattedCurrentDate)) { return [false, 'ui-state-disabled', '该日期已被其他选择器选中']; } // 否则允许选择 return [true, '', '']; }, // 选中日期后,刷新另外两个选择器的面板 onSelect: function() { $('.date-picker-group').not($picker).each(function() { $(this).multiDatesPicker('refresh'); }); }, // 删除日期后,同样刷新另外两个选择器的面板 onRemove: function() { $('.date-picker-group').not($picker).each(function() { $(this).multiDatesPicker('refresh'); }); } }); }
关键细节说明
- 关于
dateFormat:一定要保证$.datepicker.formatDate里的格式和你插件配置的dateFormat完全一致,否则日期字符串会匹配不上,禁用规则就失效了 - 关于
getDates方法:这是MultiDatesPicker扩展的方法,用来获取当前选择器的所有已选日期,返回的是Date对象数组,所以我们需要转成字符串来匹配 - 关于
refresh方法:调用这个方法会重新渲染日期选择器的面板,让beforeShowDay的新规则立即生效
备注:内容来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

