PrimeFaces v8升级至v10:Schedule组件自定义扩展函数失效
PrimeFaces v10 Schedule 自定义扩展回调失效问题
我之前在PrimeFaces v8中使用Schedule组件的自定义扩展函数,实现节假日标记、事件样式定制、日期范围限制等功能,代码运行正常。但升级到内置FullCalendar v5的PrimeFaces v10后,扩展函数里的所有回调都不再触发。我已经查阅过PrimeFaces和FullCalendar的迁移指南,尝试适配FullCalendar v5的Day-cell渲染钩子和Event渲染钩子,但修改回调名称后问题仍未解决,希望能得到帮助。
原Schedule组件代码
<p:schedule id="myCal" value="#{calendar.value}" leftHeaderTemplate="today" rightHeaderTemplate="prev next" clientTimeZone="local" centerHeaderTemplate="title" draggable="false" showHeader="true" initialDate="#{calendar.initialDate}" tooltip="true" style="width:100%" styleClass="myCal" extender="schedulerExt"> </p:schedule>
原自定义扩展函数代码
function schedulerExt() { this.cfg.views = { month: { displayEventEnd: true } }, this.cfg.dayRender = function (info) { var hol = isHoliday(info.date); if (hol >= 0) { info.el.classList.remove('fc-past'); info.el.classList.remove('fc-day'); info.el.classList.remove('fc-sun'); info.el.classList.add('holiday'); info.el.classList.add(getHolidayStyle(hol)); info.el.setAttribute('title', getHoliday(hol)); var moment = new Date(info.date); MyDateString = moment.getFullYear() + '-' + ('0' + (moment.getMonth() +1) ).slice(-2) + "-" +('0' + moment.getDate()).slice(-2); $('[data-date='+MyDateString+']').css({"color": "red", "font-weight":"bold"}); } else { var schoolHol = isSchoolHoliday(info.date); if (schoolHol >= 0) { info.el.classList.remove('fc-past'); info.el.classList.remove('fc-day'); info.el.classList.remove('fc-sun'); info.el.classList.add('school-holiday'); info.el.setAttribute('title', 'School Holiday'); var moment = new Date(info.date); MyDateString = moment.getFullYear() + '-' + ('0' + (moment.getMonth() +1) ).slice(-2) + "-" +('0' + moment.getDate()).slice(-2); $('[data-date='+MyDateString+']').css({"font-weight":"bold"}); } } }, this.cfg.datesRender = function (info) { var minDate = moment().add(-2, 'year'); var maxDate = moment().add(1, 'year'); if (minDate >= info.view.activeStart && minDate <= info.view.activeEnd) { $('.fc-prev-button').prop('disabled', true); $('.fc-prev-button').addClass('fc-state-disabled'); } else { $('.fc-prev-button').removeClass('fc-state-disabled'); $('.fc-prev-button').prop('disabled', false); } if (maxDate >= info.view.activeStart && maxDate <= info.view.activeEnd) { $('.fc-next-button').prop('disabled', true); $('.fc-next-button').addClass('fc-state-disabled'); } else { $('.fc-next-button').removeClass('fc-state-disabled'); $('.fc-next-button').prop('disabled', false); } }, this.cfg.eventRender = function (info) { info.el.setAttribute('title', info.event.extendedProps.description); if (info.event.title.indexOf("PENDING") !== -1) { var spanElement = (function() { var span = document.createElement('span'); span.className = 'fa fa-share-square-o'; span.textContent = '\u00A0'; return span; })(); info.el.querySelector(".fc-title").innerHTML = info.el.querySelector(".fc-title").innerHTML.replace('PENDING', ''); info.el.querySelector(".fc-title").parentNode.insertBefore(spanElement, info.el.querySelector(".fc-title")); } else { if (info.event.title.indexOf("Childcare") !== -1) { var spanElement = (function() { var span = document.createElement('span'); span.className = 'fa fa-child'; span.textContent = '\u00A0'; return span; })(); info.el.querySelector(".fc-title").parentNode.insertBefore(spanElement, info.el.querySelector(".fc-title")); } else if (info.event.title.indexOf("Annual") !== -1) { var spanElement = (function() { var span = document.createElement('span'); span.className = 'fa fa-plane'; span.textContent = '\u00A0'; return span; })(); info.el.querySelector(".fc-title").parentNode.insertBefore(spanElement, info.el.querySelector(".fc-title")); } } }; }
适配PrimeFaces v10 + FullCalendar v5的修改方案
FullCalendar v5对回调钩子、参数结构和DOM元素类名做了大量变更,结合PrimeFaces v10的Schedule组件特性,需要对扩展函数做以下关键修改:
1. 替换废弃的回调函数名称
FullCalendar v5废弃了旧版回调,需替换为新的钩子:
dayRender→dayCellDidMountdatesRender→ 推荐用validRange配置替代(更符合官方API)eventRender→eventDidMount
2. 调整回调参数结构
v5的回调参数和旧版有差异:
info.date为Moment对象,可直接调用format()或toDate()转换为原生Date- 无需手动移除旧的FullCalendar类名,直接添加自定义类即可
3. 优化日期范围限制逻辑
v5推荐使用validRange配置替代手动禁用按钮,自动处理日期边界的按钮状态
修改后的完整扩展函数代码
function schedulerExt() { // 配置视图选项 this.cfg.views = { month: { displayEventEnd: true } }; // 替换dayRender为dayCellDidMount this.cfg.dayCellDidMount = function(info) { var date = info.date; var hol = isHoliday(date.toDate()); // 转换为原生Date适配原有方法 if (hol >= 0) { info.el.classList.add('holiday', getHolidayStyle(hol)); info.el.setAttribute('title', getHoliday(hol)); // v5单元格自带YYYY-MM-DD格式的data-date属性 $('[data-date=' + date.format('YYYY-MM-DD') + ']').css({"color": "red", "font-weight":"bold"}); } else { var schoolHol = isSchoolHoliday(date.toDate()); if (schoolHol >= 0) { info.el.classList.add('school-holiday'); info.el.setAttribute('title', 'School Holiday'); $('[data-date=' + date.format('YYYY-MM-DD') + ']').css({"font-weight":"bold"}); } } }; // 使用validRange替代datesRender,自动限制日期范围 this.cfg.validRange = function() { return { start: moment().add(-2, 'year').toDate(), end: moment().add(1, 'year').toDate() }; }; // 替换eventRender为eventDidMount this.cfg.eventDidMount = function(info) { info.el.setAttribute('title', info.event.extendedProps.description); var titleElement = info.el.querySelector('.fc-event-title'); if (!titleElement) return; if (info.event.title.indexOf("PENDING") !== -1) { var spanElement = document.createElement('span'); spanElement.className = 'fa fa-share-square-o'; spanElement.textContent = '\u00A0'; titleElement.textContent = titleElement.textContent.replace('PENDING', ''); titleElement.parentNode.insertBefore(spanElement, titleElement); } else if (info.event.title.indexOf("Childcare") !== -1) { var spanElement = document.createElement('span'); spanElement.className = 'fa fa-child'; spanElement.textContent = '\u00A0'; titleElement.parentNode.insertBefore(spanElement, titleElement); } else if (info.event.title.indexOf("Annual") !== -1) { var spanElement = document.createElement('span'); spanElement.className = 'fa fa-plane'; spanElement.textContent = '\u00A0'; titleElement.parentNode.insertBefore(spanElement, titleElement); } }; }
额外注意事项
- 确保项目已引入FullCalendar v5所需的依赖(如Moment.js)
- PrimeFaces v10的Schedule组件自动加载FullCalendar核心,若使用额外插件需确认依赖完整性
- 可通过浏览器控制台打印
this.cfg,确认配置是否正确传递给FullCalendar实例
内容的提问来源于stack exchange,提问作者Walking body
相关产品推荐
相关产品推荐

