$.fn.fullCalendar = function(args){ var self = this[0] if(!self.calendar_args) self.calendar_args = args; else args = Object.assign(self.calendar_args, args); var calendar = new FullCalendar.Calendar(self,args); calendar.render(); $(window).on("load",function(){ calendar.render(); }) this.calendar = calendar; self.calendar = calendar; $.fullCalendar = calendar; return calendar; }; var Calendar = function(dom){ c = this; this.create_event_btn = $("#create_event_btn"); this.event_create_space = $("#event_create_space"); this.title = $("#current_title"); this.calendar = $(dom); this.nextBtn = $("#next_month_btn"); this.prevBtn = $("#prev_month_btn"); this.todayBtn = $("#today_btn"); this.modeBtns = $(".calendar_mode button"); this.refreshBtn = $("#refresh_btn"); this.mousePosition = {}; this.dialog = new EventDialog(c); this.loading = $('#calendar-loading'); this.success_event = null; this.agenda_space = $("#calendar_agenda"); this.currentView = "month"; this.navigation = $("#navigation"); this.rangeSelection = $("#range_selection"); var agendaView = new AgendaView(c); var loadeventsonviewchange = false; this.initialize = function(){ var date = new Date(); var d = date.getDate(); var m = date.getMonth(); var y = date.getFullYear(); var change_event = function(_event, delta) { _event.end = (_event.end ? _event.end : _event.start); var s = $.fullCalendar.parseDate(c.calendar.find(".fc-view table tbody td:first").data("date")); var e = $.fullCalendar.parseDate(c.calendar.find(".fc-view table tbody td:first").data("date")); $.ajax({ url: "/admin/calendars/"+_event.id, // data: {event:{id:_event.id,start:_event.start,end: _event.end,_s:Math.round(+s / 1000), _e:Math.round(+e / 1000)}}, data: {event:{id:_event.id,start:_event.start,end: _event.end}}, type: 'put' , datatype: 'JSON', error: function(jqXHR, textStatus, errorThrown) {}, success: function(data) { console.log('event was success updated'); } }); } var success_event = function(data,allDay,type,addbtn){ c.dialog.dismiss(); $('.bootstrap-datetimepicker-widget').remove(); c.event_create_space.html(data); var create_space_height = c.event_create_space.height(), create_space_width = c.event_create_space.width(); if((create_space_height + c.mousePosition["y"]) >= $(window).height()){ var top_pos = c.mousePosition["y"] - create_space_height if (top_pos < 0){ c.event_create_space.find('.modal-body').css('height',create_space_height+top_pos) c.event_create_space.css("top",0 + "px"); }else{ c.event_create_space.css("top",top_pos + "px"); } }else if(c.mousePosition["y"]+c.event_create_space.height()<$(window).height()){ c.event_create_space.css("top",c.mousePosition["y"] + "px"); } if((create_space_width + c.mousePosition["x"]) >= $(window).width()){ if (c.mousePosition["x"] - create_space_width < 0){ c.event_create_space.css("left",'0px') }else{ c.event_create_space.css("left",(c.mousePosition["x"] - create_space_width) + "px"); } }else{ c.event_create_space.css("left",c.mousePosition["x"] + "px"); } if(addbtn){ c.event_create_space.css({"right":"8px","bottom":"50px","left":"auto","top":"auto"}); }else{ c.event_create_space.css({"right":"","bottom":""}); } c.event_create_space.show(); var pickers = $('.default_picker input'); var checked = ($("#all_day_check").is(":checked") ? true : false); var checked_function = function(c){ var d = new Date() if(c){ for(i=0;i 9 ? start.getMonth() + 1 : "0" + (start.getMonth() + 1)) + "/" + (start.getDate() > 9 ? start.getDate() : "0" + start.getDate()), endString = end.getFullYear() + "/" + (end.getMonth() + 1 > 9 ? end.getMonth() + 1 : "0" + (end.getMonth() + 1)) + "/" + (end.getDate() > 9 ? end.getDate() : "0" + end.getDate()); if(!allDay){ startString += " " + (start.getHours() > 9 ? start.getHours() : "0" + start.getHours()) + ":" + (start.getMinutes() > 9 ? start.getMinutes() : "0" + start.getMinutes()); endString += " " + (end.getHours() > 9 ? end.getHours() : "0" + end.getHours()) + ":" + (end.getMinutes() > 9 ? end.getMinutes() : "0" + end.getMinutes()); }else{ startString += " " + start.getHours() + ":" + start.getMinutes(); endString += " " + end.getMinutes() + ":" + end.getMinutes(); } $.ajax({ type : "get", url : c.create_event_btn.attr("href"), data : {"startDate":startString,"endDate":endString,"allDay":allDay}, success : function(data){ success_event(data,allDay,"new"); } }) } }); c.create_event_btn.click(function(){ $.ajax({ type : "get", url : $(this).attr("href"), success : function(data){ success_event(data,false,"new",true); } }) return false; }); c.nextBtn.click(function(){ c.dialog.dismiss(); c.calendar.fullCalendar('next'); }); c.prevBtn.click(function(){ c.dialog.dismiss(); c.calendar.fullCalendar('prev'); }); c.todayBtn.click(function(){ c.dialog.dismiss(); c.calendar.fullCalendar('today'); }); c.modeBtns.click(function(){ c.dialog.dismiss(); c.event_create_space.html("").hide(); toggleViews($(this).data("mode")); }); c.refreshBtn.click(function(){ c.dialog.dismiss(); if(c.currentView == "agenda") agendaView.refresh(); else c.calendar.fullCalendar("refetchEvents"); }); c.calendar.mouseup(function(e){ c.mousePosition = {"x" : e.pageX, "y" : e.pageY}; }) var toggleViews = function(view){ c.modeBtns.removeClass("active"); c.modeBtns.each(function(){ if ($(this).data("mode") == view) $(this).addClass("active"); }) if(view != "agenda"){ if(c.currentView == "agenda"){ // $("#sec1").addClass("span3").removeClass("span7"); $("#sec2").show(); // $("#sec3").addClass("span4").removeClass("span5"); agendaView.hide(); } c.calendar.fullCalendar('changeView',view); }else{ // $("#sec1").addClass("span7").removeClass("span3"); $("#sec2").hide(); // $("#sec3").addClass("span5").removeClass("span4"); agendaView.inflate(); } c.currentView = view; if(loadeventsonviewchange){ c.calendar.fullCalendar("refetchEvents"); loadeventsonviewchange = false; } } if(c.currentView == "agenda"){toggleViews("agenda");loadeventsonviewchange = true;} c.calendar.on("DOMMouseScroll mousewheel", function(e){ if(c.calendar.fullCalendar("getView").name == "month"){ if(!c.isFormVisible()){ c.dialog.dismiss(); if(/Firefox/i.test(navigator.userAgent)){ if(e.originalEvent.detail == 1){ c.calendar.fullCalendar('next'); }else if(e.originalEvent.detail == -1){ c.calendar.fullCalendar('prev'); } }else{ if(e.originalEvent.wheelDelta /120 > 0) c.calendar.fullCalendar('prev'); else c.calendar.fullCalendar('next'); } } } }); } this.isFormVisible = function(){ return (c.event_create_space.html() == "" ? false : true); } this.renderEvent = function(eventStick){ if(eventStick.recurring == true){ c.calendar.fullCalendar("refetchEvents"); }else{ c.calendar.fullCalendar("renderEvent",eventStick); } } this.updateEvent = function(eventStick){ c.calendar.fullCalendar("updateEvent",eventStick); } this.deleteEvent = function(delete_url,_id){ $.ajax({ type : "delete", url : delete_url, success : function(){ c.calendar.fullCalendar("removeEvents",[_id]); c.dialog.dismiss(); } }) } this.editEvent = function(edit_url,allDay){ $.ajax({ type : "get", url : edit_url, success : function(data){ c.success_event(data,allDay,"edit",true); c.dialog.dismiss(); } }) } $(document).ready(function() { c.initialize(); }); } var EventDialog = function(calendar,event){ _t = this; var event_quick_view = null; var template = ""; var _this_event = null; var month_names = ["Jan","Feb","March","April","May","June","July","Aug","Sep","Oct","Nov","Dec"]; this.inflate = function(_event){ if(!_event) throw new UserException("EventStick can't be null!"); _this_event = _event; var start_time = "", end_time = "", time_string = null; Event_e = _event if(_event.allDay) { start_time = $.fullCalendar.formatDate(_event._start,"MMM dd, yyyy"); if(_event._end) end_time = $.fullCalendar.formatDate(_event._end,"MMM dd, yyyy"); time_string = (_event._start === _event._end || !_event._end ? "

" + start_time + "

" : " " + start_time + " " + end_time + ""); } else { var sh = _event._start.getHours() > 12 ? _event._start.getHours() - 12 : _event._start.getHours(), eh = _event._end.getHours() > 12 ? _event._end.getHours() - 12 : _event._end.getHours(), sm = _event._start.getMinutes() < 10 ? '0' + _event._start.getMinutes() : _event._start.getMinutes(), em = _event._end.getMinutes() < 10 ? '0' + _event._end.getMinutes() : _event._end.getMinutes(), stime = _event._start.getHours() > 12 ? sh + ':' + sm + " PM" : sh + ':' + sm + " AM", etime = _event._end.getHours() > 12 ? eh + ':' + em + " PM" : eh + ':' + em + " AM", same = (_event._start.getDate() == _event._end.getDate() && _event._start.getMonth() == _event._end.getMonth() && _event._start.getFullYear() == _event._end.getFullYear()); start_time = month_names[_event._start.getMonth()] + " " + _event._start.getDate() + ", " + _event._start.getFullYear(); end_time = month_names[_event._end.getMonth()] + " " + _event._end.getDate() + ", " + _event._end.getFullYear(); time_string = (same ? "

" + start_time + "

" + stime + " " + etime : "

" + start_time + "" + stime + "

" + end_time + "" + etime + "

"); } event_quick_view = $(''); template = '' + ''; if(_event.can_edit){ template += ''; } } this.show = function(pos){ event_quick_view.html(template).appendTo("body").show(); event_quick_view.find(".event-close-btn").one("click",function(){_t.dismiss();}); event_quick_view.find("a.delete").one("click",function(){calendar.deleteEvent(_this_event.delete_url,_this_event._id);return false;}); event_quick_view.find("a.edit").one("click",function(){calendar.editEvent(_this_event.edit_url,_this_event.allDay);return false;}); if(pos){ var pos = getPosition(pos); event_quick_view.css({"left":pos.x+"px","top":pos.y+"px"}); } } this.dismiss = function(){ if(event_quick_view) event_quick_view.remove(); } var getPosition = function(pos){ var x = pos.x, y = pos.y, winheight = $(window).height(); if((x + event_quick_view.width()) > $(window).width()){ x = x - event_quick_view.width(); } if((y + event_quick_view.height()) > winheight){ y = y - event_quick_view.height(); } return {"x":x,"y":y}; } if(event) _t.inflate(event); } var UserException = function(message) { this.message = message; this.name = "UserException"; this.toString = function(){ return this.message; } } var AgendaView = function(calendar){ var av = this; var _calendar = calendar; var agenda_space = _calendar.agenda_space; var today = new Date(); var minDifference = 6; var start_month = today.getMonth(); var start_year = today.getFullYear(); var end_month = ((start_month + minDifference) > 11 ? (start_month + minDifference) - 11 : start_month + minDifference); var end_year = ((start_month + minDifference) > 11 ? start_year+1 : start_year); var monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December']; var month_template = '
' + '

' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
SunMonTueWedThuFriSat
' + '
' + '
'; var event_list_template = '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
DateTimeEvents
No events for this month.
' + '
'; var head_template = '
' + '' + '' + '' + '' + '' + '
'; var event_template = '' + '' + '' + '' + '
' + '' + ''; var cache = false; var show_event_clicked = false; this.refresh = function(){ av.inflate(true); } this.inflate = function(forceInflation){ loading(true); _calendar.calendar.hide(); _calendar.navigation.hide(); if(!forceInflation){ if(cache){ av.show(); loading(false); return; } } agenda_space.empty(); if(!show_event_clicked){ _calendar.rangeSelection.empty(); _calendar.rangeSelection.append(renderHead().html()).show(); _calendar.rangeSelection.find("button#show_events").click(function(){ show_event_clicked = true; start_month = parseInt($("select[name=start_month]").val()); end_month = parseInt($("select[name=end_month]").val()); start_year = parseInt($("select[name=start_year]").val()); end_year = parseInt($("select[name=end_year]").val()); av.inflate(true); }) } show_event_clicked = false; eventsManager(); var s = start_month, e = end_month y = start_year; e = (e > s && start_year == end_year? e : e + 11); if(end_year > start_year) e = e + ((end_year - start_year -1) * 12); else e--; for(var i = s;i <= e+1; i++){ var m = new Month(s,y); s++; if(s > 11){ s = 0; y++; } if(e == 0) agenda_space.text("Invalid Range of Dates.") else agenda_space.append(m.monthDom); } loading(false); } this.hide = function(){ cache = true; _calendar.rangeSelection.hide(); agenda_space.hide(); _calendar.navigation.show(); _calendar.calendar.show(); } this.show = function(){ _calendar.rangeSelection.show(); agenda_space.show(); } var copyObject = function(x){ return x.clone(); } var eventsManager = function(){ var url = "/admin/calendars/agenda", sd = new Date(start_year,start_month,1), ed = new Date(end_year,end_month+1,0), usd = Math.round(sd/1000), ued = Math.round(ed/1000); $.ajax({ type : "get", url : url, data : {"agenda_start":sd.toLocaleString(),"agenda_end":ed.toLocaleString(),"unix_start":usd,"unix_end":ued}, success : function(events){ $.each(events,function(i,e){ var ed = eventDom(e), s = new Date(e.start), e = new Date(e.end), e_m = ((e.getMonth() > s.getMonth() || s.getMonth() == e.getMonth()) && s.getFullYear() == e.getFullYear() ? e.getMonth() : e.getMonth() + 12) s_m = s.getMonth(), s_y = s.getFullYear(); if(e.getFullYear() > s.getFullYear()) e_m = e_m + ((e.getFullYear() - s.getFullYear() -1) * 12); for(var i = s_m; i < e_m + 1; i++){ var temp_ed = copyObject(ed); var list = agenda_space.find("div[data-month="+s_m+"][data-year="+s_y+"] table.event_list tbody"); list.append(temp_ed); s_m++; if(s_m > 11){ s_m = 0; s_y++; } } if(s.getDate() == e.getDate() && s.getMonth() == s.getMonth() && e.getFullYear() == e.getFullYear()){ var td = agenda_space.find("td[data-date-node="+s.getDate()+"-"+s.getMonth()+"-"+s.getFullYear()+"]"); td.addClass("has_event"); }else{ var timeDiff = Math.abs(e.getTime() - s.getTime()), diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)), c_m = s.getMonth(), c_d = s.getDate(), c_y = s.getFullYear(), end_of_c_month = new Date(s.getFullYear(),s.getMonth()+1,0).getDate(); for(var i = 0; i <= diffDays; i++){ var td = agenda_space.find("td[data-date-node="+c_d+"-"+c_m+"-"+c_y+"]"); td.addClass("has_event"); c_d++; if(c_d > end_of_c_month){ c_d = 1; c_m++; if(c_m > 11){ c_m = 0; c_y++; } } } } }) agenda_space.find("table.event_list tbody").each(function(){ if($(this).find("tr").length > 1) $(this).find("td.no_events").parent().remove(); }) } }) var eventDom = function(event){ var e_t = $(event_template), s = new Date(event.start), e = new Date(event.end), dateFormat = ""; if(s.getDate() == e.getDate() && s.getMonth() == s.getMonth() && e.getFullYear() == e.getFullYear()) dateFormat = $.fullCalendar.formatDate(s, "ddd dd"); else dateFormat = $.fullCalendar.formatDates(s, e, "ddd dd, MMM - {ddd dd, MMM}"); e_t.find("td:first").text(dateFormat); e_t.find("td.event_time").text((event.allDay ? "All Day" : $.fullCalendar.formatDate(s, "hh:mm"))); e_t.find("div.event").html(event.title).css("color",event.color); return e_t; } } var loading = function(bool) { if (bool) _calendar.loading.css("left",($(window).width()/2 - 60) + "px").show(); else _calendar.loading.hide(); } var renderHead = function(){ var head = $(head_template); var start_month_select = head.find("select[name=start_month]"); for(var i = 0; i < 12; i++){ var option = $(""); if(i == start_month) option.attr("selected","selected"); start_month_select.append(option); } var end_month_select = head.find("select[name=end_month]"); for(var i = 0; i < 12; i++){ var option = $(""); if(i == end_month) option.attr("selected","selected"); end_month_select.append(option); } var start_year_select = head.find("select[name=start_year]"); var y = start_year - 5; for(var i = 0; i < 10; i++){ var option = $(""); if(y == start_year) option.attr("selected","selected"); start_year_select.append(option); y++; } var end_year_select = head.find("select[name=end_year]"); y = start_year - 5; for(var i = 0; i < 10; i++){ var option = $(""); if(y == end_year) option.attr("selected","selected"); end_year_select.append(option); y++; } return head; } var Month = function(month,year){ _this = this; this.monthDom = $("
"); var template = $(month_template); var list_template = $(event_list_template); var firstDay = new Date(year,month,1); var lastDay = new Date(year,month+1,0); var last_inserted_date = 1; var renderMonth = function(){ var num_of_rows = getNumberOfRows(year,month) for(var i = 0; i < num_of_rows; i++){ var tr = null; if(i == 0) tr = makeRow("first"); else if(i == (num_of_rows - 1)){ tr = makeRow("last"); }else{ tr = makeRow("middle"); } if(tr == null){ break; } template.find("table.table tbody").append(tr); template.find("h4").text(monthNames[firstDay.getMonth()] + " - " + firstDay.getFullYear()); } _this.monthDom.append(template); _this.monthDom.append(list_template); } function getNumberOfRows(year, month) { var day = 1, sat_counter = 0, sunday_counter = 0, date = new Date(year, month, day); while(date.getMonth() === month) { if(date.getDay() === 0) { sunday_counter++; }else if(date.getDay() === 6) { sat_counter++; } day++; date = new Date(year, month, day); } return (sunday_counter == 5 && sat_counter == 5 ? 6 : 5); } var makeRow = function(position){ if(last_inserted_date <= lastDay.getDate()){ var row = $(""); switch (position){ case "first": for(var i = 0;i < 7;i++){ var td = $(""); if(i >= firstDay.getDay()){ td.text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; } row.append(td); } break; case "middle": for(var i = 0;i < 7;i++){ var td = $(""); td.text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; row.append(td); } break; case "last": for(var i = 0;i < 7;i++){ var td = $(""); if(i <= lastDay.getDay()){ td.text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; } row.append(td); } break; } }else{ var row = null; } return row; } renderMonth(); } }