• fullcalendar日历插件的使用并动态增删改查


    我上个项目是做了一个关于教育方面的web端页面,其中的课程表就要用到fullcalendar日历插件,刚开始也是不会用,因为以前也没用过,后面也是看官方文档,问同事,最后完成了这个课程表,个人感觉fullcalendar这个日历插件功能很强大!下面我来附上几张图片:

    1、刚进去默认显示当前月份,查出数据库的数据并展示,今天是2018年1月19号,所以我给上过的课次颜色变为灰色,而没上过的课次变为橙色:

    2、点击特定的日期,添加课次:

    点击未上过的课次进行编辑或删除:

    以及课次的拖动,如将1月22号的“08:00-09:00 高数一班”拖动到1月29号:

    下面我来说一下我是怎么实现的

    首先需要导入必须的css和js:

    <link href='../../../../static/fullcalendar/css/fullcalendar.css' rel='stylesheet' />

    <script src='../../../../static/fullcalendar/js/jquery.min.js'></script>

    <script src='../../../../static/fullcalendar/js/moment.min.js'></script>

    <script src='../../../../static/fullcalendar/js/fullcalendar.min.js'></script> 

    <script src='../../../../static/fullcalendar/js/bootstrap.min.js'></script>

    <script src='../../../../static/fullcalendar/js/zh-cn.js'></script>

    在页面中我还使用了bootstrap和layer,所有我还导入了:

    <link href="./bootstrap/3.3.4/css_default/bootstrap.min.csstype="text/css" rel="stylesheet" />//我的弹出框是用bootstrap实现的,所以我导入了bootstrap的css和js
    <script src="./bootstrap/3.3.4/js/bootstrap.min.jstype="text/javascript"></script>

    <link href="./layui/css/layui.css" rel="stylesheet">

    <script src="./layui/layui.js"></script>

    <script src="./layer-v2.0/layer/layer.js"></script>

    还会用到一些公用的js方法对时间格式做转化:

    Date.prototype.Format = function(format){

    var o = {

    "M+" : this.getMonth()+1, //month

    "d+" : this.getDate(), //day

    "h+" : this.getHours(), //hour

    "m+" : this.getMinutes(), //minute

    "s+" : this.getSeconds(), //second

    "q+" : Math.floor((this.getMonth()+3)/3), //quarter

    "S" : this.getMilliseconds() //millisecond

    };

    if(/(y+)/.test(format)) {
    format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
    }
    for(var k in o) {
    if(new RegExp("("+ k +")").test(format)) {
    format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
    }
    }
    return format;
    };

    //将数据库的时间戳转成 *年*月*日 字符串
    function getDate(DBTime){
    var date = new Date(DBTime);
    var year = date.getFullYear();
    var month = date.getMonth()+1;
    var day = date.getDate();
    var dateStr;
    if(month<10&&day<10){
    dateStr = year+"-0"+month+"-0"+day;
    }else if(month<10&&day>=10){
    dateStr = year+"-0"+month+"-"+day;
    }else if(month>=10&&day<10){
    dateStr = year+"-"+month+"-0"+day;
    }else if(month>=10&&day>=10){
    dateStr = year+"-"+month+"-"+day;
    }
    return dateStr;
    }
    //将数据库的时间戳转成 *时*分 字符串
    function getTime(DBTime){
    var time = DBTime.substring(0,2)+"-"+DBTime.substring(3,5);
    return time;
    }


    然后就是初始化FullCalendar:

    下面这些代码建议在document。ready中写,在页面初始化的时候就加载运行

    $('#calendar').fullCalendar({
    //设置头部信息,如果不想显示,可以设置header为false
    header: {
    //日历头部左边:初始化切换按钮
    left: '',
    //日历头部中间:显示当前日期信息
    center: 'title',
    //日历头部右边:初始化视图
    right: 'prev,next today'
    },
    //月视图下日历格子宽度和高度的比例
    aspectRatio: 1.35,
    //月视图的显示模式,fixed:固定显示6周高;liquid:高度随周数变化;variable: 高度固定
    weekMode: 'liquid',
    //初始化时的默认视图,month、agendaWeek、agendaDay
    defaultView: 'month',
    //agenda视图下是否显示all-day
    allDaySlot: true,
    //agenda视图下all-day的显示文本
    allDayText: '全天',
    //agenda视图下两个相邻时间之间的间隔
    slotMinutes: 30,
    //区分工作时间
    businessHours: true,
    //非all-day时,如果没有指定结束时间,默认执行120分钟
    defaultEventMinutes: 60,
    //设置为true时,如果数据过多超过日历格子显示的高度时,多出去的数据不会将格子挤开,而是显示为 +...more ,点击后才会完整显示所有的数据
    eventLimit: true,
    //设置是否显示周六和周日,设为false则不显示
    weekends: true,
    //日历初始化时显示的日期,月视图显示该月,周视图显示该周,日视图显示该天,和当前日期没有关系
    //defaultDate: '2016-08-11',
    //设置是否可被单击或者拖动选择
    selectable: true,
    //点击或者拖动选择时,是否显示时间范围的提示信息,该属性只在agenda视图里可用
    selectHelper: true,
    //点击或者拖动选中之后,点击日历外的空白区域是否取消选中状态 true为取消 false为不取消,只有重新选择时才会取消
    unselectAuto: true,
    //Event是否可被拖动或者拖拽
    editable: true,
    //Event被拖动时的不透明度
    dragOpacity: 0.5,
    //日程数据
    events:
    function(start,end,timezone,callback){
    var className = $("#keyword").val();//该keyword是页面搜索框要查询的班级名称
    var date = new Date();
    var nowDate = date.Format("yyyyMMdd");
    var nowTime = date.Format("hhmmss");
    $.ajax({//通过ajax动态查询要展示的课次数据信息
    url: '后台controller中查询的路径',
    data : {
    "className": className,
    },
    dataType: 'json',
    type : 'post',
    success: function(result) { // 获取当前月的数据
    var events = [];
    if(result.body.wesClassCourseList!=null){//result.body.wesClassCourseList其实就是从后台返回前台的一个课次list,

    var len = result.body.wesClassCourseList.length;
    var wesClassCourseList=result.body.wesClassCourseList;
    var wesClassList=result.body.wesClassList;//result.body.wesClassList其实就是从后台返回前台的一个班级list,每一个课次都一一对应每一个班级,也就是说result.body.wesClassCourseList的长度和result.body.wesClassList的长度是一样的
    for(var i=0;i<len;i++){
    var classCourseDate=getDate(wesClassCourseList[i].classCourseDate);//通过getDate方法将日期格式进行转化
    var ccDate = classCourseDate.replace(/-/g,"");//去掉日期格式中的“-”
    var classCourseTime=getTime(wesClassCourseList[i].classCourseTime);//通过getTime方法将时间格式进行转化
    var ccTime = classCourseTime.replace(/-/g,"");//去掉时间格式中的“-”
    var wesClass = wesClassList[i].status;
    if((ccDate>nowDate||(ccDate==nowDate&&ccTime>nowTime))&&wesClass==false){
    events.push({
    id:wesClassCourseList[i].classCourseId+","+wesClassCourseList[i].classId,//这里我是将班级课次Id和班级Id一起作为fullcalendar中event事件的Id
    title: wesClassCourseList[i].classCourseTime+" "+wesClassList[i].name,//title我显示的是每一个课次的上下课时间和班级名称
    start: classCourseDate,//start表示这个event事件放在哪个日期框中
    color: 'red',//设置event的背景颜色,若该课次还没上且该班级已经删除则显示为红色
    });
    }else if((ccDate>nowDate||(ccDate==nowDate&&ccTime>nowTime))&&wesClass==true){
    events.push({
    id:wesClassCourseList[i].classCourseId+","+wesClassCourseList[i].classId,
    title: wesClassCourseList[i].classCourseTime+" "+wesClassList[i].name,
    start: classCourseDate,
    color: '#ff9f2c',//若该课次还没上且该班级没被删除则显示为红色
    });
    }
    else{
    events.push({
    id:wesClassCourseList[i].classCourseId+","+wesClassCourseList[i].classId,
    title: wesClassCourseList[i].classCourseTime+" "+wesClassList[i].name,
    start: classCourseDate,
    color: 'gray',//若该课次已经上过则显示为灰色
    });
    }
    }
    }
    callback(events);
    }
    });
    },

    //添加事件
    dayClick : function(date, allDay, jsEvent, view ) {
    var classCourseDate=date.format();//选择的日期
    var ccDate = classCourseDate.replace(/-/g,"");
    var date = new Date();
    var nowDate = date.Format("yyyyMMdd");
    var nowTime = date.Format("hhmmss");
    var nowClassCourseDate = getDate(classCourseDate).replace(/-/g,"");
    if(ccDate<nowDate){
    return;
    }
    $("#startTimeAdd").val("");
    $("#endTimeAdd").val("");
    //ajax获取班级信息,并展示添加框
    $.ajax({
    url: '后台controller层查询班级信息的路径',//因为点击日历某个特定日期时,弹出框需要以下拉框的形式显示班级信息
    dataType: 'json',
    type : 'post',
    success: function(result){ // 获取当前月的数据
    var len = result.body.wesClassList.length;
    var teacherClassInfo=result.body.wesClassList;
    str="";
    $("#classListInfoAdd").empty();
    //循环取教师所带班级
    str +='<select id="classIdAdd" style=" 60%;height:30px; padding-left:4px; padding-top:0px;padding-bottom:0px; line-height:30px; color: grey" >';
    str +='<option value="0">请选择</option>';
    for(var i=0;i<len;i++){
    str +='<option value="'+teacherClassInfo[i].classId+'">'+teacherClassInfo[i].name+'</option>';
    }
    str +='</select>';
    $("#classListInfoAdd").append(str);//班级下拉框赋值
    $("#addObjcectInputModalAdd").modal("show");//显示弹出框
    }
    });

    //编辑事件 

    eventClick : function( event ){

    var id=event.id;
    var classCourseId=id.split(",")[0];
    var classId=id.split(",")[1];
    var firstClassId = classId;
    var title= event.title;
    var startTimeEdit=(title.split(" ")[0]).split("-")[0];
    var endTimeEdit=(title.split(" ")[0]).split("-")[1];
    var classCourseDate=getDate(event.start);

    $.ajax({
    url: '查询所有班级信息的路径,弹出框要以下拉框的形式显示',
    dataType: 'json',
    type : 'post',
    success: function(result){ // 获取当前月的数据
    var len = result.body.wesClassList.length;
    var teacherClassInfo=result.body.wesClassList;
    str="";
    $("#classListInfoEdit").empty();
    //循环取教师所带班级
    str +='<select id="classIdEdit" style=" 60%;height:30px; padding-left:4px; padding-top:0px;padding-bottom:0px; line-height:30px >';
    str +='<option value="0">请选择</option>';
    for(var i=0;i<len;i++){
    if(teacherClassInfo[i].classId==classId){
    str +='<option value="'+teacherClassInfo[i].classId+'" selected = "selected" >'+teacherClassInfo[i].name+'</option>';
    }else{
    str +='<option value="'+teacherClassInfo[i].classId+'" >'+teacherClassInfo[i].name+'</option>';
    }
    }
    str +='</select>';
    $("#classListInfoEdit").append(str);//班级下拉框赋值
    $("#startTimeEdit").val(startTimeEdit);
    $("#endTimeEdit").val(endTimeEdit);
    $("#addObjcectInputModalEdit").modal("show");//显示弹出框
    }
    });

    //保存修改内容

    var classCourseTime=startTimeEdit+"-"+endTimeEdit;//开始结束时间段
    var updateEditBtn=document.getElementById('updateEdit');
    updateEditBtn.onclick=function(){

    $.ajax({
    url: '保存编辑内容的后台路径',
    data : {
    classCourseId : classCourseId,
    classId : classId,
    classCourseTime : classCourseTime,
    classCourseDate : classCourseDate,
    },
    dataType: 'json',
    type : 'post',
    success: function(result) { // 获取当前月的数据
    if (result.success) {
    $('#calendar'). fullCalendar ( 'refetchEvents' );
    $("#addObjcectInputModalEdit").modal("hide");//隐藏弹出框
    }
    }

    }

    //删除
    var deleEditBtn=document.getElementById('deleEdit');
    deleEditBtn.onclick=function(){
    layer.confirm('是否确认删除?', {closeBtn: 0, icon : 3 ,skin : 'layui-layer-red',btn: ['确认','取消'] //按钮
    }, function(){
    $.ajax({
    url: '路径',
    data : {
    classCourseId : classCourseId,
    },
    dataType: 'json',
    type : 'post',
    success: function(result) { // 获取当前月的数据
    if (result.success) {
    $('#calendar').fullCalendar( 'removeEvents' ,[ id ]),//删除当前日程
    $("#addObjcectInputModalEdit").modal("hide");//隐藏弹出框
    layer.closeAll('dialog');//隐藏消息提示框
    }
    }
    });
    });
    };

    //取消
    var cancelEditBtn=document.getElementById('cancelEdit');
    cancelEditBtn.onclick=function(){
    $("#addObjcectInputModalEdit").modal("hide");//隐藏弹出框
    };

    },

    //拖动事件

    eventDrop : function( event, dayDelta, revertFunc ) {
    var color = event.color;
    if(color=='gray'){
    layer.alert("已上课和已关闭的班级课次不能被拖动修改!", {skin:'layui-layer-red',closeBtn:0,icon:2});
    revertFunc(); //恢复原状
    return;
    }

    var id=event.id;
    var classId=id.split(",")[1];
    var title= event.title;
    var startTimeEdit=(title.split(" ")[0]).split("-")[0];
    var endTimeEdit=(title.split(" ")[0]).split("-")[1];
    var classCourseDate=getDate(event.start);
    var startTimeEditString = startTimeEdit.replace(/:/g,"");
    var endTimeEditString = endTimeEdit.replace(/:/g,"");
    var classCourseId=id.split(",")[0];

    $.ajax({
    url: '保存修改信息的后台路径',
    data : {
    classCourseId : classCourseId,
    classCourseDate : classCourseDate,
    },
    dataType: 'json',
    type : 'post',
    success: function(result) { // 获取当前月的数据
    if (result.success) {
    $('#calendar'). fullCalendar ( 'refetchEvents' );
    $("#addObjcectInputModalEdit").modal("hide");//隐藏弹出框
    }
    }
    });

    $("#search").click(function(){//当点击搜索按钮时页面重新刷新,日历重新初始化
    $('#calendar'). fullCalendar ( 'refetchEvents' );
    });

    //我的添加课次、编辑删除课次弹出框是在body中写的:

    //添加课次弹出框代码:

    <div class="modal fade" id="addObjcectInputModalAdd" tabindex="-1">
    <div class="modal-dialog">
    <div class="modal-content" style=" 45%;border:1px solid;margin: 42%;">
    <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
    <h4 class="modal-title"><i class="fa fa-info-circle"></i>新建课程</h4>
    </div>
    <div class="modal-body">
    <div class="form-group" style="margin: 2px; margin-bottom: 20px">
    <div class="input-group" style="100%;line-height: 3; ">
    <p>
    选择班级:<span id="classListInfoAdd"></span>
    </p>
    <p>
    开始时间:<input type="time" id="startTimeAdd" />
    </p>
    <p>
    结束时间:<input type="time" id="endTimeAdd" />
    </p>
    <p>
    <input type="button" class="btn btn-xs btn-secondary" id="cancelAdd" value="取 消">
    <input type="button" class="btn btn-xs btn-success" id="determineAdd" value="确 定">
    </p>
    </div>
    </div>

    </div>
    </div>

    //编辑删除课次弹出框代码:

    <div class="modal fade" id="addObjcectInputModalEdit" tabindex="-1">
    <div class="modal-dialog">
    <div class="modal-content" style=" 45%;border:1px solid;margin: 42%;">
    <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
    <h4 class="modal-title"><i class="fa fa-info-circle"></i>编辑课程</h4>
    </div>
    <div class="modal-body">
    <div class="form-group" style="margin: 2px; margin-bottom: 20px">
    <div class="input-group" style="100%;line-height: 3; ">
    <p>
    选择班级:<span id="classListInfoEdit"></span>
    </p>
    <p>
    开始时间:<input type="time" id="startTimeEdit" />
    </p>
    <p>
    结束时间:<input type="time" id="endTimeEdit" />
    </p>
    <p>
    <input type="button" class="btn btn-xs btn-secondary" id="cancelEdit" value="取 消">
    <input type="button" class="btn btn-xs btn-success" id="updateEdit" value="修 改">
    <input type="button" class="btn btn-xs btn-danger" id="deleEdit" value="删 除">
    </p>
    </div>
    </div>

    </div>
    </div>
    </div>
    </div>

  • 相关阅读:
    【CF875E】Delivery Club 二分+线段树
    【CF316G3】Good Substrings 后缀自动机
    【BZOJ3413】匹配 离线+后缀树+树状数组
    【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线
    【BZOJ5133】[CodePlus2017年12月]白金元首与独舞 矩阵树定理
    【LOJ6254】最优卡组 堆(模拟搜索)
    面试问题总结
    Nginx基本配置
    Visual Studio Enterprise 2015下载 Update3
    .net 中生成二维码的组件
  • 原文地址:https://www.cnblogs.com/gaopengfirst/p/8317723.html
Copyright © 2020-2023  润新知