引言

最新工作中需要实现日程管理功能,由于技术选型(基于layui)限制,从网上对比查询最终选定使用FullCalendar插件来实现日程管理。
其中对比的日程还有XgCalendar、Google Calendar

实现效果
1、打开界面后,月视图

2、切换到周视图

3、切换到日视图

4、在月视图,添加会议室预订

5、在月视图,修改会议室预订

6、在月视图,鼠标移到event,显示详情

对应实现
1、依赖的js
下载路径:https://fullcalendar.io/docs/getting-started

2、对应的index

<!DOCTYPE html>
<html lang='en'>
<head><meta charset='utf-8' /><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="format-detection" content="telephone=no"><link rel="stylesheet" href='/fullcalendar/core/main.css' rel='stylesheet' /><link rel="stylesheet" href='/fullcalendar/daygrid/main.css' rel='stylesheet' /><link rel="stylesheet" href='/fullcalendar/timegrid/main.css' rel='stylesheet' /><link rel="stylesheet" href="/assets/libs/layui/css/layui.css" media="all"><link rel="stylesheet" href="/assets/common.css" media="all"><style>#calendar {max-width: 1200px;margin: 0 auto;}#external-events {float: left;width: 150px;padding: 0 10px;border: 1px solid #ccc;background: #eee;text-align: left;}#external-events h4 span {font-size: 16px;margin-top: 0;padding-top: 1em;}.external-event { /* try to mimick the look of a real event */margin: 10px 0;padding: 2px 4px;background: #3366CC;color: #fff;font-size: .85em;cursor: pointer;}/*日期控件*/.layui-laydate-content>.layui-laydate-list {padding-bottom: 0px;overflow: hidden;}.layui-laydate-content>.layui-laydate-list>li{width:50%}/* pop */.popper,.tooltip {position: absolute;z-index: 9999;background: #FFC107;color: black;width: 150px;border-radius: 3px;box-shadow: 0 0 2px rgba(0,0,0,0.5);padding: 10px;text-align: center;}.style5 .tooltip {background: #1E252B;color: #FFFFFF;max-width: 200px;width: auto;font-size: .8rem;padding: .5em 1em;}.popper .popper__arrow,.tooltip .tooltip-arrow {width: 0;height: 0;border-style: solid;position: absolute;margin: 5px;}.tooltip .tooltip-arrow,.popper .popper__arrow {border-color: #FFC107;}.style5 .tooltip .tooltip-arrow {border-color: #1E252B;}.popper[x-placement^="top"],.tooltip[x-placement^="top"] {margin-bottom: 5px;}.popper[x-placement^="top"] .popper__arrow,.tooltip[x-placement^="top"] .tooltip-arrow {border-width: 5px 5px 0 5px;border-left-color: transparent;border-right-color: transparent;border-bottom-color: transparent;bottom: -5px;left: calc(50% - 5px);margin-top: 0;margin-bottom: 0;}.popper[x-placement^="bottom"],.tooltip[x-placement^="bottom"] {margin-top: 5px;}.tooltip[x-placement^="bottom"] .tooltip-arrow,.popper[x-placement^="bottom"] .popper__arrow {border-width: 0 5px 5px 5px;border-left-color: transparent;border-right-color: transparent;border-top-color: transparent;top: -5px;left: calc(50% - 5px);margin-top: 0;margin-bottom: 0;}.tooltip[x-placement^="right"],.popper[x-placement^="right"] {margin-left: 5px;}.popper[x-placement^="right"] .popper__arrow,.tooltip[x-placement^="right"] .tooltip-arrow {border-width: 5px 5px 5px 0;border-left-color: transparent;border-top-color: transparent;border-bottom-color: transparent;left: -5px;top: calc(50% - 5px);margin-left: 0;margin-right: 0;}.popper[x-placement^="left"],.tooltip[x-placement^="left"] {margin-right: 5px;}.popper[x-placement^="left"] .popper__arrow,.tooltip[x-placement^="left"] .tooltip-arrow {border-width: 5px 0 5px 5px;border-top-color: transparent;border-right-color: transparent;border-bottom-color: transparent;right: -5px;top: calc(50% - 5px);margin-left: 0;margin-right: 0;}</style>
</head>
<body><div class="layui-fluid"><div class="layui-card" style="padding-top: 5px; margin-bottom: 8px;"><div class="layui-row layui-col-space15"><div class="layui-col-xs12 layui-col-md2"><div id='external-events'><h4>会议室</h4><#list roomList as room><div class="external-event" id="room${room.id}" roomId="${room.id}" onclick="changeRoom(this.id)">${room.name}</div></#list><#--<div id="1" roomId="1" onclick="changeRoom(this.id)">会议室1</div>--><#--<div id="2" roomId="2" onclick="changeRoom(this.id)">会议室2</div>--><#--<div id="3" roomId="3" onclick="changeRoom(this.id)">会议室3</div>--><#--<div id="4" roomId="4" onclick="changeRoom(this.id)">会议室4</div>--></div></div><div class="layui-col-xs12 layui-col-md10"><div id='calendar'></div></div></div></div>
</div><!-- 表单弹框 -->
<script  type="text/html" id="calendarForm"><form lay-filter="calendarForm" class="layui-form model-form"><input name="id" id="id" type="hidden"/><div class="layui-form-item"><label class="layui-form-label">预约主题</label><div class="layui-input-block"><input name="appointTheme" placeholder="请输入会议主题" type="text" class="layui-input" maxlength="50" lay-verify="required" required/></div></div><div class="layui-form-item"><label class="layui-form-label">预约开始时间</label><div class="layui-input-inline"><input type="text" class="layui-input" id="stime" name="stime" placeholder="HH:mm" lay-verify="required" required></div></div><div class="layui-form-item"><label class="layui-form-label">预约结束时间</label><div class="layui-input-inline"><input type="text" class="layui-input" id="etime" name="etime" placeholder="HH:mm" lay-verify="required" required></div></div><div class="layui-form-item"><label class="layui-form-label">预约人</label><div class="layui-input-block"><input name="appointPerson" value="<#if currentUser.name!=''>${currentUser.name}<#else>${currentUser.loginName}</#if>" type="text" class="layui-input" maxlength="50" readonly /></div></div><div class="layui-form-item"><label class="layui-form-label">联系方式</label><div class="layui-input-block"><input name="tel" value="<#if currentUser.phone??>${currentUser.phone}</#if>" type="text" class="layui-input" maxlength="20" readonly /></div></div><div class="layui-form-item text-right"><button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button><button class="layui-btn" lay-filter="formSubmit" lay-submit>保存</button><button class="layui-btn" type="button" id="delEdit" onclick="del()">删除</button></div></form>
</script><!-- js部分 -->
<script src='/fullcalendar/core/main.js'></script>
<script src='/fullcalendar/core/locales-all.js'></script>
<script src='/fullcalendar/daygrid/main.js'></script>
<script src='/fullcalendar/interaction/main.js'></script>
<script src='/fullcalendar/timegrid/main.js'></script>
<script src='/fullcalendar/core/locales/zh-cn.js'></script>
<script src="/assets/libs/jquery/jquery-3.2.1.min.js"></script>
<script src='/fullcalendar/popper.min.js'></script>
<script src='/fullcalendar/tooltip.min.js'></script>
<script type="text/javascript" src="/assets/libs/layui/layui.all.js"></script>
<script type="text/javascript" src="/assets/js/calendar/index.js"></script>
</body>
</html>

3、对应的js

var addIndex;
var roomId;
var calendar;
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var laydate = layui.laydate;roomId = $("#room1").attr("roomId");
$("#room1").css("backgroundColor", "#003399");document.addEventListener('DOMContentLoaded', function() {var calendarEl = document.getElementById('calendar');calendar = new FullCalendar.Calendar(calendarEl, {plugins: [ 'interaction', 'dayGrid', 'timeGrid' ],defaultView: 'dayGridMonth',// defaultDate: '2019-05-07',selectable: true, // dataClick生效locale: 'zh-cn', // 设置中文eventLimit: 4, // 显示更多displayEventEnd: true, // 显示结束时间header: {left: 'prev,next today',center: 'title',right: 'dayGridMonth,timeGridWeek,timeGridDay'},events: function(info, successCallback, failureCallback) {$.get("/erpcalendartask/getByParams", {roomId: roomId, sTime: info.start.valueOf(), eTime: info.end.valueOf()}, function (res) {if(res.code == 200) {successCallback(res.data);}else {failureCallback(res.errStr);}});},eventClick: function(info) {console.log('eventClick ' + info);openEditLayer(info);},dateClick: function(info) {console.log('dateClick ' + info.dateStr);openLayer(info);},eventRender: function(info) {var tooltip = new Tooltip(info.el, {title: popContent(info.event.title, info.event.extendedProps.appointPerson, info.event.start, info.event.end, info.event.extendedProps.tel),placement: 'top',trigger: 'hover',container: 'body',html: true});}});calendar.render();
});function popContent(title, appointPerson, stime, etime, tel) {var sDate =new Date(stime);var s = sDate.getHours() + '点' + sDate.getMinutes() + '分';var eDate =new Date(etime);var e = eDate.getHours() + '点' + eDate.getMinutes() + '分';var str = '<div style="font-weight: bold;">' + title + '</div>';str += '<div style="height: 1px;background-color: black;"></div>'str += '<div style="text-align: left;">预订人:' + appointPerson + '</div>';str += '<div style="text-align: left;">预订时间:' + s + ' -  ' + e + '</div>';str += '<div style="text-align: left;">预订电话:' + tel + '</div>'return str;
}$(document).ready(function () {});function initDateCtrl() {//日期时间选择器laydate.render({elem: '#stime' //指定元素,type: 'time',format: 'HH:mm',done: function(value, date){var etime = $("#etime").val();var ehour = parseInt(etime.split(":")[0]);var eminute = parseInt(etime.split(":")[1]);var hour = date.hours;var minute = date.minutes;if(ehour < hour) {$("#finishtime").val(value);} else {if(eminute < minute) {$("#etime").val(value);}}}});//日期时间选择器laydate.render({elem: '#etime' //指定元素,type: 'time',format: 'HH:mm',done: function(value, date){var stime = $("#stime").val();var shour = parseInt(stime.split(":")[0]);var sminute = parseInt(stime.split(":")[1]);var hour = date.hours;var minute = date.minutes;if(shour > hour) {$("#stime").val(value);} else {if(sminute > minute) {$("#stime").val(value);}}}});
}function openEditLayer(info){addIndex=layer.open({title : '<i class="fa fa-plus"></i>&nbsp;编辑日程',type : 1,fix : false,skin : 'layui-layer-rim',// 加上边框area : [ '470px', '450px' ],// 宽高content : $('#calendarForm').html(),success: function (layero, index) {initDateCtrl();$("#delEdit").show();var data = {};data.id = info.event.id;var sDate =new Date(info.event.start);data.stime = sDate.getHours() + ':' + sDate.getMinutes() ;var eDate =new Date(info.event.end);data.etime = eDate.getHours() + ':' + eDate.getMinutes() ;data.appointTheme = info.event.title;data.appointPerson = info.event.extendedProps.appointPerson;data.tel = info.event.extendedProps.tel;form.val('calendarForm', data);// 表单提交事件form.on('submit(formSubmit)', function (d) {var dataStr = sDate.getFullYear() + '-' + (sDate.getMonth() + 1) + '-' + sDate.getDate();d.field.roomId = roomId;d.field.stime = dataStr + " " + d.field.stime + ":00";d.field.etime = dataStr + " " + d.field.etime + ":00";$.ajax({type: 'POST',url: '/erpcalendartask/update',//发送请求contentType: "application/json; charset=utf-8",async: true,data: JSON.stringify(d.field),dataType: "json",success: function (res) {layer.closeAll("loading");if(res.code == 200){// layer.msg("添加成功!", {icon: 1});calendar.refetchEvents();layer.closeAll('page');}else{layer.msg(res.msg, {icon: 2});}}});return false;});}});
}function openLayer(info){addIndex=layer.open({title : '<i class="fa fa-plus"></i>&nbsp;新增日程',type : 1,fix : false,skin : 'layui-layer-rim',// 加上边框area : [ '470px', '450px' ],// 宽高content : $('#calendarForm').html(),success: function (layero, index) {initDateCtrl();$("#delEdit").hide();// 表单提交事件form.on('submit(formSubmit)', function (d) {d.field.roomId = roomId;d.field.stime = info.dateStr + " " + d.field.stime + ":00";d.field.etime = info.dateStr + " " + d.field.etime + ":00";$.ajax({type: 'POST',url: '/erpcalendartask/create',//发送请求contentType: "application/json; charset=utf-8",async: true,data: JSON.stringify(d.field),dataType: "json",success: function (res) {layer.closeAll("loading");if(res.code == 200){// layer.msg("添加成功!", {icon: 1});calendar.refetchEvents();layer.closeAll('page');}else{layer.msg(res.msg, {icon: 2});}}});return false;});}});
}function changeRoom(id){$(".external-event").each(function(i){if(this.id==id){$(this).css("backgroundColor", "#003399");roomId = $(this).attr("roomId");}else{$(this).css("backgroundColor", "#3366CC");}});calendar.refetchEvents();
}function del(){var id=$("#id").val();layer.confirm('确定要删除吗?', {offset: '65px',title: '提示'}, function (i) {layer.close(i);layer.load(2);$.post("/erpcalendartask/deleteByID", {id: id}, function (res){layer.closeAll('loading');if(res.code == 200){// layer.msg("删除成功");calendar.refetchEvents();layer.closeAll('page');}else{layer.msg(res.message);}});});
}// 所有ew-event
$('body').on('click', '*[ew-event]', function () {var event = $(this).attr('ew-event');if (event == 'closeDialog') {var id = $(this).parents('.layui-layer').attr('id').substring(11);layer.close(id);}
});

考虑到Java服务端只是CRUD,避免文字的篇幅太长,所以大家如需继续研究,可以在git上下载:
https://github.com/chyanwu/erp-framework

更多精彩,更多技术请关注:码蚁在线(coding_online)

基于LayUI使用FullCalendar实现日程管理相关推荐

  1. FullCalendar(日程管理控件)

    (以下是我学习FullCalendar控件时,网络上收集的一些资料) 第一部分(官方资料) jQuery.fullCalendar官方网址: http://arshaw.com/fullcalenda ...

  2. vue 使用 FullCalendar 实现日程管理 外部拖拽 自定义事件 事件拖拽 缩放 悬浮框 分类

    点击原文链接 可代码分享 fm: 用了两个星期研究这个全日历,具体的命令记不住了,就在packjson文件中导入这些东西 ,注意版本 全日历官网有不同的版本 同样 有些版本不同 就没办法使用 &quo ...

  3. python项目源码 日程管理_基于fullcalendar制作的日程管理小demo

    一.项目地址: 二.项目功能概述: 该项目是基于fullcalendar而制作的日程管理,fullcalendar是一个基于jquery的日历插件,在该项目中,我们可以在日历上编辑我们的日程,并将日程 ...

  4. 日程管理 FullCalendar

    日程管理,采用著名组件FullCalendar日历插件实现 FullCalendar提供了丰富的属性设置和方法调用,开发者可以根据FullCalendar提供的API快速完成一个日历日程的开发 1.实 ...

  5. 基于layui的后台管理模板

    介绍: 基于layui的后台管理模板 网盘下载地址: http://kekewangLuo.cc/U6mcEZKHXpb 图片:

  6. android中管理后台服务的控件,基于android的手机日程管理系统需求调研报告(12页)-原创力文档...

    PAGE 1 基于Android的手机日程管理系统的设计与实现 需求调研分析 学生姓名: 王炜 学 号: 09110514034 指导教师: 刘雪梅 课题类型: AXP 专 业: 软件工程 学 部 : ...

  7. android日程管理开发,基于Android日程管理工具的设计与开发.doc

    PAGE PAGE i 基于android日程管理工具的设计与开发 摘 要 随着移动平台的崛起,越来越多的传统PC软件被移植到移动平台,比如ipad,iphone,Android等智能终端设备,在这些 ...

  8. X-admin经典前端后台管理模板,基于layui的轻量级前端后台管理框架,简单,兼容性好,面向所有层次的前后端程序

    X-admin 简介 X-admin基于layui的轻量级前端后台管理框架,简单免费,兼容性好,面向所有层次的前后端程序.创立于2017年初,为了敏捷WEB应用开发和简化企业应用开发而诞生的.#X-a ...

  9. android日程管理的论文,毕业论文-基于安卓的手机日程管理系统.pdf

    2012 届毕业设计 (论文) 题 目 基于安卓的手机日程管理系统 姓 名 学 号 专 业 计算机科学与 班 级 技术 指 导 教 师 2012 年 6 月 基于安卓的手机日程管理系统 摘 要 随着生 ...

最新文章

  1. C 语言 和 C++语言的对比学习   二 数据类型
  2. 深入探秘 Netty、Kafka 中的零拷贝技术!
  3. 看完这篇文章之后,终于明白了编译到底怎么回事
  4. teacher want middle point result rather all drafts
  5. 【期望】守卫挑战(金牌导航 期望-9)
  6. 使用Excel和TF实现Transformer!
  7. mysql+json插入_MySQL对JSON数据的增删改查
  8. DiskGenius是一款硬盘分区及数据恢复软件
  9. 因Win10商店引起的卡死问题与解决方法
  10. DIY年轻人的第一辆电动滑板车
  11. ​​​​​​​Carryon 数数字
  12. 【技巧】vscode快速生成html结构
  13. 云创大数据荣膺英特尔“行业贡献奖”
  14. 算法高级(40)-基于分治算法完美解决的人类基因组计划
  15. DRF路由Routers
  16. 如何保护视频资源?这几个防盗链使用技巧你一定要知道!
  17. JVM命令与调优工具的使用(OOM与GC回收例)
  18. 期货开户手续费怎么计算?
  19. 微信小程序 - 气泡菜单组件(仿微信气泡弹框显示菜单)
  20. Photoshop CS2 视频教程-PS色彩范围(转)

热门文章

  1. 下一代IP协议----IPV6
  2. 看完315晚会,我们的数据隐私谁来保护?
  3. 基本系统调用性能lmbench测试方法和下载
  4. 输入学生成绩评定等级:90-100为A,80-89为B,60-79为C,小于60为D
  5. OPPOA79K_OPPOA79KT_官方线刷包_救砖包_解账户锁
  6. DBpedia Introduction
  7. C. Get an Even String
  8. 仿爱奇艺加载dialog
  9. 原型模式-广告邮件推送
  10. 实习总结第七谈-----------vue中element-ui的表格行高怎么控制