fullcalendar日历插件实现工作记录表格
1. 看下效果图
- 表头为2栏,分为计划、记录;
- 左侧栏是一天中具体时间点,具体到分钟;
- 按钮栏分为日周月,三种视图切换:
- 顶部、左侧固定,都支持滑动滚动条
- 文本超出,加入鼠标悬浮效果。



2. 用到插件
日历插件fullcalendar :使用v6版本:https://fullcalendar.io/docs/initialize-globals
官方文档:https://fullcalendar.io/
鼠标悬浮插件:Tippy.js
官方文档:https://tippyjs.bootcss.com/getting-started/
3. 实现步骤
(1)实现表头
(2)事件数据套入字段
(3)我的需求是事件有不同状态,对应不同颜色(背景色/文字颜色/边框等)
(4)最后加入鼠标悬浮功能
4. 具体代码:
使用的js、jq原生写法(...jsp项目)
(1)引入
<%-- 公共鼠标悬浮样式文件--%>
<link rel="stylesheet" href="${ctxStatic}/customTippy/customtippy.css">
<%-- 公共日历插件样式文件--%>
<link rel="stylesheet" href="${ctxStatic}/fullcalendar/customCalendar.css">
// 官方下载的源码包 放在本地文件夹的
<script src="${ctxStatic}/fullcalendar/index.global.js" type="text/javascript"></script>
// 下面2个是鼠标悬浮用到 <script src="https://unpkg.com/popper.js@1"></script> <script src="https://unpkg.com/tippy.js@5"></script>
(2)html部分
<div class="tabbable">
<div id="calendar"></div>
</div>
(3)js部分
<script>
// 文字颜色
var colorMap = {
1:'#234299',
2:'#a05eb5',
3:'#226f56',
98:'#ed9235',
100:'#9b9646' // 计划
}
// 背景颜色
var colorBgMap = {
1:'#ecf4ff',
2:'#fceefe',
3:'#e2f7f2',
98:'#ffefdf',
100:'#fefdea' // 计划
}
// 对应类名
var colorMapClass = {
1:'planDColor1',
2:'planDColor2',
3:'planDColor3',
98:'planDColor98',
100:'planDColor100' // 计划
}
document.addEventListener("DOMContentLoaded", function () {
var calendarEl = document.getElementById("calendar");
var calendar = new FullCalendar.Calendar(calendarEl, {
locale: "zh-cn", // 使用中文语言包
timeZone: "Asia/Shanghai",
initialDate: "${initYTD}", // 设置初始显示的日期
initialView: "resourceTimeGridDay", // resourceTimeGridDay日期表格
allDaySlot: false, // 禁用 all-day 行
headerToolbar: {
// 自定义工具栏
left:'',
center: "title,prev,next",
right:
"today,resourceTimeGridDay,resourceTimeGridFourDay,dayGridMonth",
},
firstDay: 1,
datesAboveResources: true,
views: {
resourceTimeGridFourDay: {
type: 'resourceTimeGrid',
duration: { days: 7 },
buttonText: '周'
}
},
buttonText: {
// 自定义按钮文本
today: "今天",
month: "月",
week: "周",
day: "日",
},
slotLabelFormat: {
// 格式化Y轴时间为24小时制
hour: "2-digit",
minute: "2-digit",
hour12: false, // 24小时制
},
eventTimeFormat: {
// 格式化节点时间为24小时制
hour: "2-digit",
minute: "2-digit",
hour12: false, // 24小时制
},
slotMinTime: "09:00:00", // 最小时间
slotMaxTime: "24:00:00", // 最大时间
resources: [
{
id: "${tPerform.userId}",
title: "计划",
},
{
id: "${tPerform.userId}perform",
title: "工作记录",
},
],
// 日期网格数据
events: function (fetchInfo, successCallback, failureCallback) {
$.ajax({
url: "${ctx}/perform/tPerform/showPerformData",
type: "GET",
data: {
id: "${tPerform.id}",
userId: "${tPerform.userId}",
// 传递当前视图的起始和结束日期
startTime: fetchInfo.startStr,
endTime: fetchInfo.endStr,
},
success: function (data) {
// 将获取到的事件数据传递给日历 重构插件所需的字段
data.data?.map((v)=>{
if(v.type==='perform'){
v.resourceId = v.resourceId+'perform'
v.title = '【工作记录】'+v.title
// 100 值对应工作计划
v.className=colorMapClass[Number(v.approvalState||100)]
}else{
v.title = '【计划】'+v.title
v.className= colorMapClass[Number(v.approvalState||100)]
}
v.backgroundColor= colorBgMap[Number(v.approvalState||100)]
})
successCallback(data.data);
},
error: function () {
// 如果发生错误,调用 failureCallback
failureCallback();
},
});
},
// 这里是鼠标悬浮
eventDidMount: function (info) {
tippy(info.el, {
placement: "bottom",
theme: "custom",
content: info.event.extendedProps.contents
,
});
},
});
calendar.render();
});
</script>
(4)css部分
<style> .fc .fc-col-header-cell-cushion, .fc .fc-daygrid-day-number { color: black; } /*日-周-视图*/ .fc-timegrid-event-harness { .planDColor1, .planDColor2, .planDColor3, .planDColor98, .planDColor100 { border: none; line-height: 22px; font-size: 12px; border-radius: 0; } .recordDColor1, .recordDColor2, .recordDColor3, .recordDColor98, .recordDColor100 { border: none; line-height: 22px; font-size: 12px; border-radius: 0; } } .planDColor1, .recordDColor1 { .fc-event-main { color: #234299 !important; border-top: 2px solid #234299; } a { color: #234299 !important; } } .planDColor2, .recordDColor2 { .fc-event-main { color: #a05eb5 !important; border-top: 2px solid #a05eb5; } a { color: #a05eb5 !important; } } .planDColor3, .recordDColor3 { .fc-event-main { border-top: 2px solid #226f56; color: #226f56 !important; } a { color: #226f56 !important; } } .planDColor98, .recordDColor98 { .fc-event-main { border-top: 2px solid #ed9235; color: #ed9235 !important; } a { color: #ed9235 !important; } } .planDColor100, .recordDColor100 { .fc-event-main { border-top: 2px solid #9b9646; color: #9b9646 !important; } a { color: #9b9646 !important; } } /*月视图*/ .fc-daygrid-event-harness { .fc-daygrid-dot-event .fc-event-title{ font-weight: 400; } .planCssDayWeek { border: none; border-top: 2px solid transparent; line-height: 22px; font-size: 12px; border-radius: 0; } /*月份 小圆点颜色*/ .planCssDayWeek .fc-daygrid-event-dot { /*border-color:#00a8dd !important;*/ } .recordCssDayWeek { border: none; border-top: 2px solid transparent; line-height: 22px; font-size: 12px; border-radius: 0; } /*月份 小圆点颜色*/ .recordCssDayWeek .fc-daygrid-event-dot { /*border-color:#0052d9 !important;*/ } .planDColor1, .recordDColor1 { font-size: 12px; color: #234299 !important; } .planDColor2, .recordDColor2 { font-size: 12px; color: #a05eb5 !important; } .planDColor3, .recordDColor3 { font-size: 12px; color: #226f56 !important; } .planDColor98, .recordDColor98 { font-size: 12px; color: #ed9235 !important; } .planDColor100, .recordDColor100 { font-size: 12px; color: #9b9646 !important; } } /*自定义按钮*/ .fc-direction-ltr .fc-button-group > .fc-button { background-color: rgb(231 231 231); color: rgb(0 0 0 / 60%); border-radius: 0.25em; padding: 0.2em 1.2em; font-size: 14px; } .fc .fc-button-primary:focus, .fc .fc-button-primary:not(:disabled).fc-button-active:focus, .fc .fc-button-primary:not(:disabled):active:focus { box-shadow: none; } .fc .fc-button-primary { border: none; } .fc-direction-ltr .fc-button-group > .fc-button:not(:last-child), .fc-direction-ltr .fc-button-group > .fc-button:not(:first-child) { border-bottom-right-radius: 0.25em; border-top-right-radius: 0.25em; } .fc .fc-button-primary:not(:disabled).fc-button-active:focus, .fc .fc-button-primary:not(:disabled).fc-button-active { color: #0052D9; border-radius: 0.25em; } .fc .fc-button-primary:not(:disabled).fc-button-active, .fc .fc-button-primary:not(:disabled):active { background-color: #fff; border: none; border-radius: 0.25em; } .fc .fc-button-group { background-color: rgb(231 231 231); color: rgb(0 0 0 / 60%); padding: 3px; border-radius: 0.25em; position: relative; } .fc-today-button { position: absolute !important; top: 0; left: -67px; padding: 0.4em 1.2em !important; } .fc-next-button, .fc-prev-button, .fc-toolbar-title { color: rgb(0 0 0 / 60%) !important; margin-right: 0 !important; } .fc .fc-button-primary:not(:disabled):active { padding: 0.2em 1.2em; margin-right: 0px; margin-bottom: 0px; font-size: 14px; } .fc .fc-button .fc-icon { font-size: 2em; } .fc .fc-next-button:active:focus, .fc .fc-prev-button:active:focus { background-color: transparent; color: rgb(0 0 0 / 60%) !important; border: none; box-shadow: none; padding: 0; margin-bottom: 8px; font-size: 16px; } </style>
(5)自定义公共样式文件
customCalendar.css
/*统一自定义 fullcalendar 插件 样式*/ /*头部标题*/ .fc .fc-toolbar-title { color: black; margin-right: 10px; display: inline-block; } /* 修改 prev 按钮的样式 */ /* 修改 next 按钮的样式 */ button.fc-prev-button.fc-button.fc-button-primary , button.fc-next-button.fc-button.fc-button-primary, .fc .fc-button-primary:not(:disabled):active { background-color: white; border: none; color: black; padding:0; margin-right: 5px; margin-bottom: 8px; font-size: 16px; box-shadow: none; } /*去掉阴影*/ .fc button.fc-prev-button.fc-button-primary:not(:disabled).fc-button-active:focus, .fc button.fc-next-button.fc-button-primary:not(:disabled):active:focus, .fc button.fc-next-button.fc-button-primary:not(:disabled).fc-button-active:focus, .fc button.fc-prev-button.fc-button-primary:not(:disabled):active:focus{ box-shadow: none; }
(6)下载的源码文件

官方下载地址:https://fullcalendar.io/docs/initialize-globals


浙公网安备 33010602011771号