工作中所遇到的fullCalendar问题汇总

工作中因为需要课表方面的显示,所以为了方便就用到了一个开源的日历插件,中遇到了一些问题;因此做一个小小的汇总,希望能对大家有一些帮助!

首先 发一下文档的地址:https://fullcalendar.io/

1.如何通过ajax展示数据。

为了方便展示数据最好把数据库的字段对应上,这样的话数据库中的数据直接映射进Model的话就可以直接把Model转成json串而不用根据fullcalendar所需要的json串的模式进行更改,数据库设计如下:工作中所遇到的fullCalendar问题汇总_第1张图片

layui.use('form', function(){
    var form = layui.form;
    var calendar = $('#calendar');
    form.on("submit(query)", function(data){
        calendar.fullCalendar('refetchEvents');//重新渲染事件,这里就相当与重新执行events,这里的主要场景就是上面有一个搜索框,通过点击搜索,重新执行events中的ajax
	return false;
    });		
    var myfn = {
	initCalendar : function () {
	    var me = this;    
            calendar.fullCalendar({
	        weekNumbers:true,
	        firstDay: 1,
	        defaultView: 'agendaDay', 
	        allDaySlot: false,
	        allDayDefault: false,
	        minTime: "9:00",  
	        header: {
	            left: 'prev,next today',
	            center: 'title',
	            right: 'agendaWeek,agendaDay'
	        },
	        editable: false,//不允许拖拽调整
	        navLinks: true, // 显示导航栏
	        eventLimit: true, // 事件太多时, 折叠展示
	        events: function(start, end, timezone, callback) {  
	            $.ajax({  
		        url: '/schedule/todayCalendar/todayCalendarJson',  
		        dataType: 'json',
		        type : 'post',
		        data: {  
			        start: start.unix(),  
			        end: end.unix(),
			        '_query.w_lk.s.studentName' : $("#studentName").val(),
			        '_query.w_lk.s.teacherName' : $("#teacherName").val(),
			        '_query.w_lk.s.roomName' : $("#roomName").val(),
			        '_query.w_eq.p.courseId' : $("#courseName").val()
		        },  
		        success: function(doc) {  
		            callback(doc);  //回调  doc中就是一个个上面所说数据库的model的json串
		        }  
	            });  
	        },  
	        timeFormat: 'H(:mm)',
	        eventMouseover: function( event, jsEvent, view ) { //鼠标划过的事件
	            layer.tips(event.remarks, this, {tips : 1});
	        },
	        eventMouseout:function( event, jsEvent, view ) { //鼠标离开的事件
	            var index = layer.tips();
	            layer.close(index); 
	        },
	        eventClick: function(eventObj) {//这里是事件的点击事件
	            layer.open({
	                type: 2,
	                title: '课表操作',
	                shadeClose: true,
	                shade: false,
	                maxmin: true, //开启最大化最小化按钮
	                area: ['893px', '600px'],
	                content: '/schedule/todayCalendar/todayCalendarOperator/' + eventObj.id 
	            });
	        },
            });	
        }    		    
    }
    myfn.initCalendar();  //初始化fullcalendar,也就是绘制日历
});

这就是一个基础的日历的展示的功能,因为前端框架用的layui所以其中出现了layui字段;这都可以忽略!

上面的js要注意的地方主要是重新渲染日历中的事件要用到$("#生成日历的div的Id").fullCalendar('refetchEvents');

还有就是events中的callback() ,其中要传一个以日历需要数据的json串,如果以之前所说的数据库表数据生成的json串就没问题,要不然就自己给一个json串 类似{start:'2018-01-12 20:36:11', end :'2018-01-12 20:56:11' , title: 'test'} 也是没问题的;

eventMouseover和eventMouseout主要是为了展示课程的细节 

2.如何让用户禁止点击某个时间段

业务背景:其中有一个需求要通过点击课表进行排课,然后为了防止排课的时间段发生重叠,还有防止老师,教室发生冲突,需要在日历中以灰块标志出来!





layui.use('form', function(){
    var form = layui.form;
 	  	  	    	
    //回显之前有的课程  以及老师的上课事件教室占用的事件
    $.post("/schedule/calendar/showClass", data.field,
    	function(msg){
    	//进行禁止点击 的 设置
    	myfn.businessTimes = [];
    	$.post("/schedule/calendar/getTeacherAndRoomBussiness", data.field, function(info){
    	    myfn.pushBusinessTimes(msg);
    	    var info2 = new Array();
    	    $.extend(true, info2, info);//这里遇到一个大坑,因为一直以为info和info2为不同的对象改变info时info2不会受影响,所以之前两行代码是用var info2 = info.concat();但一直都是info变的话info2也会变;后来就觉得info和info2虽然是不同的对象,但他们引用的字符串是一样的;所以会变
    	    msg = msg.concat(info2);
    	    for(var i in info) {
    	        info[i].start = info[i].dateStr + " " + info[i].start;
    	        info[i].end = info[i].dateStr + " " + info[i].end;
    	    }
    	    myfn.pushBusinessTimes(info);
	    $("#calendar").fullCalendar('removeEvents');//移除日历中原有的事件
	    $("#calendar").fullCalendar('renderEvents', msg, true);//添加事件
    	});
    });

    form.on('select(change)', function(data){
        myfn.saveData();
        $("#calendar").fullCalendar('destroy');//摧毁日历,一般是想对日历中的参数修改的情况用到这个(像修改businessHours),然后再重新‘画’一个日历
    });
    var myfn={
    formData : null,
    //获取日期格式化后的
    businessTimes : [
    ],//这个主要是记录不能点击的区域时间
    removeBusinessTimes : function(id){//移除日历中时间时候,移除BusinessTimes
        var business = myfn.businessTimes;
        for(var i in business) {
            if(business[i].id == id) {
                business.splice(i, 1);
            }
        }
    },
    pushBusinessTimes : function(msg) {//添加BusinessTimes的方法
        for(var i in msg) {
            var temp = {id : msg[i].id, start : Number(new Date(msg[i].start)) / 1000, end : Number(new Date(msg[i].end)) / 1000};
            myfn.businessTimes.push(temp);
        }
    },
    compireTime : function(start, end) {//比较BusinessTimes和点击区域的时间
        var busyTime = myfn.businessTimes;
        var clickTime = {start : start, end : end};
        for(var i in busyTime) {
            if(!myfn.checkTime(clickTime, busyTime[i])) {
                return false;
            }
        }
        return true;
    },
    checkTime : function(timeScope1, timeScope2) {
        if(timeScope1.start >= timeScope2.end) {
            return true;
        }
        if(timeScope1.start < timeScope2.start) {
            if(timeScope1.end <= timeScope2.start) {
                return true;
            }
        }
        return false;
    },
    createCalendarConfig : {
        weekNumbers:true,
        selectable: true,
        firstDay: 1,
        timezone: 'local',
        defaultView: 'agendaWeek', 
        allDaySlot: false,
        allDayDefault: false,
        minTime: "9:00", 
        maxTime: "22:00",
        header: false,
        editable: false,//不允许拖拽调整
        navLinks: true, // 显示导航栏
        businessHours : false,
        eventLimit: true, // 事件太多时, 折叠展示
        timeFormat: 'HH:mm',
        select:function(start, end, jsEvent) {  //点击日历上的某个时间触发的函数
      	        	//添加 记录
        },
        selectAllow : function(clickInfo) {//可不可以点击主要是通过这个方法来限定,返回false就不能点击
            var start = clickInfo.start.unix();
            var end = start + 60 * myfn.formData.para_classTime;
            if(myfn.compireTime(start, end)) {
                return true;
            } 
            return false;
        },
        eventClick: function(eventObj) {
 
        }
    },
	        
    createCalendar: function() {
        $("#calendar").fullCalendar(myfn.createCalendarConfig);	
    }

  	
});

这里的主要判断思想就是把不能点击的时间放在一个字符串中,然后每次点击通过selectAllow方法去判断点击要不要触发事件!

但是类似那种有教室被占用的情况,也就是不能有select事件的区域是一个一个事件的时候,可以通过events返回特定的数据结构来禁止点击事件;

events中的json串可以返回这样的结构

[
    {
        id:    'available_hours',
        start: '2015-1-13T8:00:00',
        end:   '2015-1-13T19:00:00',
        rendering: 'background'
        color:'gray'
    },
    {
        id:    'work',
        start: '2015-1-13T10:00:00',
        end:   '2015-1-13T16:00:00',
        rendering: 'background'
        color:'gray'
    }
]

这样就不需要用businessHours了,因为businessHours json串中定义的是可以使用的时间,也就是不要阴影的时间,而且对与阴影部分插件也没有加什么限制,只不过是把样式改了一下,感觉比较坑!

你可能感兴趣的:(js)