fullcalendar日曆插件的使用並實現增刪改查
- 2019 年 10 月 8 日
- 筆記
我上個項目是做了一個關於教育方面的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.css" type="text/css" rel="stylesheet" />//我的彈出框是用bootstrap實現的,所以我導入了bootstrap的css和js <script src="./bootstrap/3.3.4/js/bootstrap.min.js" type="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="width: 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="width: 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="width: 45%;border:1px solid;margin: 42%;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</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="width: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="width: 45%;border:1px solid;margin: 42%;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</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="width: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>