如何在FullCalendar中禁用已排程周内的中间日期?
解决FullCalendar中禁用已设置日程间日期的方案
嘿,刚好做过类似的需求,给你分享下具体的实现思路和代码:
首先,我们需要完成两个核心目标:阻止用户选择禁用日期,以及视觉上标记这些不可选日期。结合你已经实现的“每周最多3个日程”逻辑,咱们可以基于FullCalendar的原生API来搞定:
1. 工具函数:获取当前周的已有日程
先写一个复用性高的函数,用来筛选出当前周视图下已有的所有日程事件,方便后续判断:
function getCurrentWeekEvents(targetDate) { // 这里替换成你的日历实例获取方式,比如你存储的calendar变量 const calendar = $('#your-calendar-id').fullCalendar('getCalendar'); const weekStart = calendar.view.currentStart; const weekEnd = calendar.view.currentEnd; return calendar.getEvents().filter(event => { // 筛选出当前周范围内的事件 return event.start >= weekStart && event.start <= weekEnd; }); }
2. 阻止选择禁用日期(selectAllow钩子)
利用FullCalendar的selectAllow回调,在用户尝试点击选择日期时做校验:
$('#your-calendar-id').fullCalendar({ // 你的其他日历配置... selectAllow: function(selectInfo) { const weekEvents = getCurrentWeekEvents(selectInfo.start); // 先保留你已有的逻辑:每周最多3个日程 if (weekEvents.length >= 3) { alert('本周已达3个日程上限,无法新增'); return false; } // 提取已选日期并按时间排序 const selectedDates = weekEvents.map(evt => evt.start).sort((a, b) => a - b); // 检查当前选中的日期是否在任意两个已选日程之间 for (let i = 0; i < selectedDates.length - 1; i++) { const prevDate = selectedDates[i]; const nextDate = selectedDates[i + 1]; // 若当前日期在两个已选日期之间(不包含两端),则禁止选择 if (selectInfo.start > prevDate && selectInfo.start < nextDate) { alert('该日期位于已设置的日程之间,无法选择'); return false; } } return true; // 允许选择该日期 }, // 其他钩子配置... });
3. 视觉标记禁用日期(dayRender钩子)
为了让用户直观看到哪些日期不可选,我们可以在dayRender中给中间日期添加禁用样式:
$('#your-calendar-id').fullCalendar({ // 你的其他日历配置... dayRender: function(info) { const weekEvents = getCurrentWeekEvents(info.date); const selectedDates = weekEvents.map(evt => evt.start).sort((a, b) => a - b); // 遍历每一对相邻的已选日期,标记中间的日期 for (let i = 0; i < selectedDates.length - 1; i++) { const prevDate = selectedDates[i]; const nextDate = selectedDates[i + 1]; if (info.date > prevDate && info.date < nextDate) { // 添加禁用样式类 info.el.classList.add('fc-disabled-day'); // 阻止点击交互 info.el.style.pointerEvents = 'none'; info.el.style.opacity = '0.6'; } } }, // 其他钩子配置... });
别忘了在CSS里定义fc-disabled-day的样式,让禁用效果更明显:
.fc-disabled-day { background-color: #f0f0f0; cursor: not-allowed; }
4. 事件更新后重新渲染
当你新增或删除日程后,需要调用calendar.render()触发dayRender重新渲染日期,确保禁用状态实时更新:
// 比如新增事件后执行: calendar.addEvent(newEvent); calendar.render(); // 重新渲染日历视图
这样就能完美实现你的需求:每周最多3个日程,且已设置日程之间的日期既不能被选择,也会有清晰的视觉禁用标记。
内容的提问来源于stack exchange,提问作者da26
相关产品推荐
相关产品推荐

