window.auto_close_popup = false; if(window.calendar_variable == undefined){ window.calendar_variable = {}; window.calendar_variable.is_chinese = ( I18n && I18n.locale.indexOf('zh') != -1 ); window.calendar_variable.date_type = 0; }else{ if(window.calendar_variable.date_type == 1){ window.calendar_variable.is_chinese = false; }else{ window.calendar_variable.is_chinese = ( I18n && I18n.locale.indexOf('zh') != -1 ); } } if(!(window.calendar_variable.dayNames)){ if(window.calendar_variable.is_chinese){ window.calendar_variable.dayNames = ['週日', '週一', '週二', '週三','週四', '週五', '週六']; window.calendar_variable.dayNamesShort = ['日', '一', '二', '三','四', '五', '六']; }else{ window.calendar_variable.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday']; window.calendar_variable.dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed','Thu', 'Fri', 'Sat']; } } if(Array.prototype.rotate == undefined){ Array.prototype.rotate = function(n) { n = n % this.length; while (this.length && n < 0) n += this.length; this.push.apply(this, this.splice(0, n)); return this; } } if(window.calendar_variable.is_chinese){ window.calendar_variable.months = []; for(var i=0;i<12;i++){ window.calendar_variable.months.push((i+1)+"月"); } }else{ window.calendar_variable.months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; } if(window.calendar_variable.date_type == 2){ window.calendar_variable.month_year_format = calendar_variable.is_chinese ? 'yy/MM' : 'MM/yy'; window.calendar_variable.date_format = calendar_variable.is_chinese ? 'yy/MM/dd' : 'dd/MM/yy'; window.calendar_variable.date_format_with_short_month = calendar_variable.is_chinese ? 'yy/MM/dd' : 'dd/MM/yy'; window.calendar_variable.date_format_with_week = calendar_variable.is_chinese ? 'yy/MM/dd (W)' : 'W, MM/dd/yy'; window.calendar_variable.short_date = (calendar_variable.is_chinese ? "MM/dd (W)" : "W, dd/MM"); if(window.calendar_variable.time_type == 1){ window.calendar_variable.datetime_format = calendar_variable.is_chinese ? 'yy/MM/dd H:m' : 'dd/MM/yy H:m'; window.calendar_variable.short_date_time = (calendar_variable.is_chinese ? "MM/dd (W) H:m" : "W, dd/MM H:m"); }else{ window.calendar_variable.datetime_format = calendar_variable.is_chinese ? 'yy/MM/dd b h:m' : 'dd/MM/yy h:m b'; window.calendar_variable.short_date_time = (calendar_variable.is_chinese ? "MM/dd (W) b h:m" : "W, dd/MM h:m b"); } }else{ window.calendar_variable.month_year_format = calendar_variable.is_chinese ? 'y MMM' : 'MMM y'; window.calendar_variable.date_format = calendar_variable.is_chinese ? 'y MMM d' : 'd MMM, y'; window.calendar_variable.date_format_with_short_month = calendar_variable.is_chinese ? 'y M d' : 'd M, y'; window.calendar_variable.date_format_with_week = calendar_variable.is_chinese ? 'y MMM d (W)' : 'W, MMM d, y'; window.calendar_variable.short_date = (calendar_variable.is_chinese ? "MMM d (W)" : "W, d MMM"); if(window.calendar_variable.time_type == 1){ window.calendar_variable.datetime_format = calendar_variable.is_chinese ? 'y MMM d H:m' : 'd MMM, y H:m'; window.calendar_variable.short_date_time = (calendar_variable.is_chinese ? "MMM d (W) H:m" : "W, d MMM H:m"); }else{ window.calendar_variable.datetime_format = calendar_variable.is_chinese ? 'y MMM d b h:m' : 'd MMM, y h:m b'; window.calendar_variable.short_date_time = (calendar_variable.is_chinese ? "MMM d (W) b h:m" : "W, d MMM h:m b"); } } window.calendar_variable.date_format_numeric = 'yy/MM/dd'; window.calendar_variable.short_date_numeric = (calendar_variable.is_chinese ? "MM/dd (w)" : "w MM/dd"); if(window.calendar_variable.time_type == 1){ window.calendar_variable.time_format = "H:m"; }else{ window.calendar_variable.time_format = (calendar_variable.is_chinese ? "b h:m" : "h:m b"); } window.calendar_variable.std_date_format = 'y-MM-d'; window.calendar_variable.short_day = (calendar_variable.is_chinese ? "d (W)" : "W d"); $.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; }; function correct_date(date){ var new_date = new Date(); new_date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000); return new_date; } FullCalendar.Calendar.prototype.get_all_events = function(){ this.currentData.all_events = []; var all_events = this.currentData.all_events; if(this.currentData.eventStore && this.currentData.eventStore.instances){ var instances = this.currentData.eventStore.instances; Object.keys(instances).forEach(function(k){ var instance = instances[k]; var range = Object.assign({},instance.range); range.start = correct_date(range.start); range.end = correct_date(range.end); all_events.push(range); }) } return this.currentData.all_events; } FullCalendar.Calendar.prototype.isAnOverlapEvent = function(eventStartDay, eventEndDay){ eventStartDay = eventStartDay || eventEndDay; eventEndDay = eventEndDay || eventStartDay; if((typeof(eventStartDay)).toLowerCase() == "string") eventStartDay = new Date(eventStartDay); if((typeof(eventEndDay)).toLowerCase() == "string") eventEndDay = new Date(eventEndDay); var events = this.get_all_events(); for (var i = 0; i < events.length; i++) { var eventA = events[i]; // start-time in between any of the events if (eventStartDay >= eventA.start && eventStartDay <= eventA.end) { return true; } //end-time in between any of the events if (eventEndDay >= eventA.start && eventEndDay <= eventA.end) { return true; } //any of the events in between/on the start-time and end-time if (eventStartDay <= eventA.start && eventEndDay >= eventA.end) { return true; } } return false; } window.getDateString = function(date, format, is_chinese) { var months = calendar_variable.months; var week_days = calendar_variable.dayNames; var getPaddedComp = function(comp) { return ((parseInt(comp) < 10) ? ('0' + comp) : comp) }, formattedDate = format, y = date.getFullYear(), m = date.getMonth(), d = date.getDate(), H = date.getHours(), M = date.getMinutes(), s = date.getSeconds(), S = date.getMilliseconds(), month_name = months[m], am_trans = (calendar_variable.is_chinese ? '上午' : 'AM'), pm_trans = (calendar_variable.is_chinese ? '下午' : 'PM'), o = { "yy+": y, //raw year "y+": y + (calendar_variable.is_chinese ? "年" : ""), // year "MMM+": month_name, //month "MM+": getPaddedComp(m + 1), //raw month "M+": month_name.substring(0,3), //month "dd+": getPaddedComp(d), //raw day "d+": (calendar_variable.is_chinese ? (d + "日") : getPaddedComp(d)), //day "W+": week_days[date.getDay()], //weekday "w+": (calendar_variable.is_chinese ? week_days[date.getDay()].substr(-1, 1) : week_days[date.getDay()].substr(0, 3)), //weekday "h+": getPaddedComp((H > 12) ? H % 12 : H), //hour "H+": getPaddedComp(H), //hour "m+": getPaddedComp(M), //minute "s+": getPaddedComp(s), //second "S+": getPaddedComp(S), //millisecond, "b+": (H >= 12) ? pm_trans : am_trans }; for (var k in o) { if (new RegExp("(" + k + ")").test(format)) { formattedDate = formattedDate.replace(RegExp.$1, o[k]); } } return formattedDate; }; var Calendar = function(dom,page_id,event_date=''){ var c = this; this.title = $("#current_title"); this.calendar_dom = $(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.dialog = new EventDialog(c); this.loading = $('#calendar-loading'); this.agenda_space = $("#calendar_agenda"); this.currentView = "dayGridMonth"; this.page_id = page_id; this.navigation = $("#navigation"); this.rangeSelection = $("#range_selection"); var agendaView = new AgendaView(c); var loadeventsonviewchange = false; this.success_event = null; this.eventDataTransform = function(eventData){ if(eventData.allDay && eventData.end){ var tmp = new Date(eventData.end); tmp.setTime(tmp.getTime() + 86400000); // Add one day for displaying eventData.end = tmp.toISOString(); //eventData.end = eventData.end; } return eventData; }; this.initialize = function(){ if (event_date != ''){ var event_dates = event_date.split("-"); var date = new Date(Date.UTC(event_dates[0],event_dates[1],event_dates[2])); }else{ var date = new Date(); } var d = date.getDate(); var m = date.getMonth(); var y = date.getFullYear(); var dview = (c.currentView == "agenda" ? "dayGridMonth" : c.currentView); c.calendar_dom.css("overflow","visible"); c.calendar_dom.fullCalendar({ themeSystem: 'bootstrap', editable: false, selectable: true, width: "100%", height: $("body").height() - 141, events: function(args, success_callback, fail_callback) { var start = args.start; var end = args.end; $.ajax({ url: "/xhr/calendars/events.json?page_id="+c.page_id+"&locale="+I18n.locale, dataType: 'json', type: 'GET', data: { start: Math.round(start.getTime() / 1000), end: Math.round(end.getTime() / 1000), _: Date.now() }, success: function(json) { // json = json.map(function(obj){ // obj.start = new Date(obj.start).toJSON(); // obj.end = new Date(obj.end).toJSON(); // return obj; // }) success_callback(json); } }); }, eventDataTransform: c.eventDataTransform, // events: 'https://fullcalendar.io/demo-events.json', headerToolbar: false, fixedWeekCount: false, initialView: dview, loading: function(bool) { if (bool) c.loading.show(); else c.loading.hide(); if(this.currentData) $('#current_title').html(this.currentData.viewTitle); }, windowResize : function(view){ c.calendar_dom.calendar.refetchEvents(); }, eventTimeFormat: { hour12: (window.calendar_variable.time_type != 1), hour: '2-digit', minute: '2-digit', omitZeroMinute: true, meridiem: 'narrow' }, eventClick: function(eventClickInfo) { var calEvent = {"event": eventClickInfo.event}, originalEvent = eventClickInfo.jsEvent, view = eventClickInfo.view, el = $(eventClickInfo.el); if(el.hasClass("reserve_btn")){ window.calEvent = calEvent; var start_time = calEvent.event.start; var date_str = window.getDateString(start_time,std_date_format); c.dialog.hide(); var allow_times = calEvent.event._def.extendedProps.allow_times; window.pick_hire_date(date_str,allow_times); }else{ c.dialog.dismiss(); c.dialog.inflate(calEvent); c.dialog.show({"x": originalEvent.clientX,"y": originalEvent.clientY}); } }, dateClick: function(ev) { var calendar = this; var calendar_dom = $(this.el); if(c.calendar_dom.hasClass("active_picker")){ var date = ev.date, date_str = getDateString(date,date_time_str_format), day_element = ev.dayEl, jsEvent = ev.jsEvent; var time_str = date_str.split(" ")[1]; var date_str = date_str.split(" ")[0]; calendar_dom.trigger("init_time",[time_str]); calendar_dom.trigger("select_time",[date_str]); } }, views: { timeGridDay: { titleFormat: function(date_info){ var date = date_info.date.marker; return getDateString(date, calendar_variable.date_format_with_week); }, dayHeaderFormat: function(date_info){ return window.calendar_variable.dayNames[date_info.date.marker.getDay()]; } }, timeGridWeek: { titleFormat: function(date_info){ var start = date_info.start.marker, end = date_info.end.marker; return getDateString(start, calendar_variable.date_format) + ' ~ ' + getDateString(end, calendar_variable.date_format); }, dayHeaderFormat: function(date_info){ return getDateString(date_info.date.marker, calendar_variable.short_date_numeric); } }, dayGridMonth: { dayMaxEvents: false, titleFormat: function(date_info){ var date = date_info.date.marker; return getDateString(date, calendar_variable.month_year_format); }, dayHeaderFormat: function(date_info){ return window.calendar_variable.dayNamesShort[date_info.date.marker.getDay()]; } } }, firstDay: (window.calendar_variable.sunday_first == true ? 0 : 1) }); c.nextBtn.click(function(){ c.dialog.dismiss(); c.calendar_dom.calendar.next(); c.title.text(c.calendar_dom.calendar.currentData.viewTitle); }); c.prevBtn.click(function(){ c.dialog.dismiss(); c.calendar_dom.calendar.prev(); c.title.text(c.calendar_dom.calendar.currentData.viewTitle); }); c.todayBtn.click(function(){ c.dialog.dismiss(); c.calendar_dom.calendar.today(); c.title.text(c.calendar_dom.calendar.currentData.viewTitle); }); c.modeBtns.click(function(){ c.dialog.dismiss(); toggleViews($(this).data("mode")); }); c.refreshBtn.click(function(){ c.dialog.dismiss(); if(c.currentView == "agenda") agendaView.refresh(); else c.calendar_dom.calendar.refetchEvents(); }); 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_dom.calendar.changeView(view); }else{ // $("#sec1").addClass("span7").removeClass("span3"); $("#sec2").hide(); // $("#sec3").addClass("span5").removeClass("span4"); agendaView.inflate(); } c.currentView = view; if(loadeventsonviewchange){ c.calendar_dom.calendar.refetchEvents(); loadeventsonviewchange = false; } c.title.text(c.calendar_dom.calendar.currentData.viewTitle); // c.calendar_dom.calendar.rerenderEvents(); //Rerender to fix layout }; if(c.currentView == "agenda"){toggleViews("agenda");loadeventsonviewchange = true;} }; this.updateEvent = function(eventStick){ c.calendar_dom.fullCalendar("updateEvent",eventStick); } this.deleteEvent = function(delete_url,_id){ $.ajax({ type : "delete", url : delete_url, success : function(){ c.calendar_dom.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(); } }) } this.renderEvent = function(eventStick){ if(eventStick.recurring === true) c.calendar_dom.calendar.refetchEvents(); else c.calendar_dom.calendar.addEvent(eventStick); }; $(document).ready(function() { c.initialize(); }); }; var EventDialog = function(calendar,event){ _t = this; var event_quick_view = null; var template = ""; var _this_event = null; this.inflate = function(_event){ if(!_event) throw new UserException("EventStick can't be null!"); _event.allDay = _event.event.allDay; _event._start = _event.event.start; if(_event.event.end){ _event._end = _event.event.end; if(_event.allDay){ _event._end.setTime(_event._end.getTime() - 86400000); } }else{ _event._end = _event.event.start; } // var start_date = getDateString(_event._start,calendar_variable.date_format); // var end_date = getDateString(_event._end,calendar_variable.date_format); _event.title = _event.event.title; var extendedProps = _event.event.extendedProps; Object.keys(extendedProps).forEach(function(k){ _event[k] = extendedProps[k]; }) if(_event.hiring_person_name == undefined) _event.hiring_person_name = ""; _this_event = _event; var start_time = "", end_time = "", time_string = null; if(_event.allDay) { start_time = getDateString(_event._start,calendar_variable.date_format_with_short_month); if(_event._end) end_time = getDateString(_event._end,calendar_variable.date_format_with_short_month); time_string = (_event._start === _event._end || !_event._end ? "
" + start_time + "
" : "" + start_time + "" + start_time + "
" + stime +
" " + etime ;
}else{
time_string = "" + start_time + " " + stime +
"
" +
end_time + " " + etime + ""
}
// time_string = (same ? "
" + start_time + "
" + stime + " " + etime : "
" + start_time + "" + stime + "
" + end_time + "" + etime + "
"); } event_quick_view = $(''); template = ' '; } this.esc_keydown = function(e){ var code = e.keyCode || e.which; if( code ==27 ){ _t.hide(); } } this.show = function(pos){ event_quick_view.css({display: 'inline-block',width: '',height: '', position: "fixed", "z-index": "10000"}); var offset; var padding = 20; if(pos){ offset = {"left":pos.x,"top":pos.y}; var pos = getPosition(pos); event_quick_view.css(offset); }else{ offset = {"left": padding, "top": padding}; } 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;}); var window_width = $(window).width(), window_height = $(window).height(); var dialog_width = event_quick_view.width(), dialog_height = event_quick_view.height(); var new_offset = Object.assign({},offset); var need_redisplay = false; var new_width = null, new_height = null; var padding_top = padding + 40; if(offset.left + dialog_width > window_width){ new_offset.left = window_width - dialog_width - padding; need_redisplay = true; } if(new_offset.left < padding){ new_width = dialog_width - (padding - new_offset.left); new_offset.left = padding; need_redisplay = true; } if(offset.top + dialog_height > window_height){ new_offset.top = window_height - dialog_height - padding; need_redisplay = true; } if(new_offset.top < padding_top){ new_height = dialog_height - (padding_top - new_offset.top); new_offset.top = padding_top; need_redisplay = true; } if(need_redisplay){ event_quick_view.css(new_offset); event_quick_view.width(new_width); event_quick_view.height(new_height); } $(document).off("keydown", _t.esc_keydown); $(document).on("keydown", _t.esc_keydown); } this.hide = function(){ calendar.calendar_dom.find('.fc-popover-close').click(); $(event_quick_view).hide(); } 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 = window.calendar_variable.months; var month_template = ''+title+' | '; }).join('') + '
---|
DateTime | ' + 'Events | ' + '|
---|---|---|
No events for this month. | ' + '
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|
No events for this month. |