Fix calendar bug.

Update fullcalendar from 1.6.1 to 5.11.0.
This commit is contained in:
BoHung Chiu 2022-07-11 16:57:05 +08:00
parent 5441d0a45c
commit 906b0f9718
11 changed files with 19836 additions and 6782 deletions

View File

@ -1,26 +1,131 @@
window.auto_close_popup = false;
$.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.is_chinese = ( I18n && I18n.locale.indexOf('zh') != -1 );
window.datetime_format = is_chinese ? 'y M d h:m b' : 'd M, y h:m b';
window.date_format = is_chinese ? 'y M d' : 'd M, y';
window.datetime_format = window.date_format;
window.time_format = "h:m b";
window.std_date_format = 'y-MM-d';
window.short_day = (is_chinese ? "d (w)" : "w d");
window.short_date = (is_chinese ? "M d (w)" : "w d, M");
window.short_date_time = (is_chinese ? "M d (w) h:m b" : "w d, M h:m b");
window.getDateString = function(date, format,is_chinese) {
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var week_days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
if(is_chinese){
months = [];
for(var i=0;i<12;i++){
months.push((i+1)+"月");
}
week_days = ["週日","週一","週二","週三","週四","週五","週六"]
}
var getPaddedComp = function(comp) {
return ((parseInt(comp) < 10) ? ('0' + comp) : comp)
},
formattedDate = format,
o = {
"y+": date.getFullYear() + (is_chinese ? "年" : ""), // year
"MM+": getPaddedComp(date.getMonth() + 1), //raw month
"M+": months[date.getMonth()], //month
"d+": (is_chinese ? (date.getDate() + "日") : getPaddedComp(date.getDate())), //day
"w+": week_days[date.getDay()], //weekday
"h+": getPaddedComp((date.getHours() > 12) ? date.getHours() % 12 : date.getHours()), //hour
"H+": getPaddedComp(date.getHours()), //hour
"m+": getPaddedComp(date.getMinutes()), //minute
"s+": getPaddedComp(date.getSeconds()), //second
"S+": getPaddedComp(date.getMilliseconds()), //millisecond,
"b+": (date.getHours() >= 12) ? 'PM' : 'AM'
};
for (var k in o) {
if (new RegExp("(" + k + ")").test(format)) {
formattedDate = formattedDate.replace(RegExp.$1, o[k]);
}
}
return formattedDate;
};
var Calendar = function(dom){
c = this;
var c = this;
this.create_event_btn = $("#create_event_btn");
this.event_create_space = $("#event_create_space");
this.mousePosition = {};
this.title = $("#current_title");
this.calendar = $(dom);
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.mousePosition = {};
this.dialog = new EventDialog(c);
this.loading = $('#calendar-loading');
this.success_event = null;
this.agenda_space = $("#calendar_agenda");
this.currentView = "month";
this.currentView = "dayGridMonth";
this.navigation = $("#navigation");
this.rangeSelection = $("#range_selection");
var agendaView = new AgendaView(c);
var loadeventsonviewchange = false;
this.success_event = null;
this.initialize = function(){
var date = new Date();
var d = date.getDate();
@ -28,8 +133,8 @@ var Calendar = function(dom){
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"));
var s = $.fullCalendar.parseDate(c.calendar_dom.find(".fc-view table tbody td:first").data("date"));
var e = $.fullCalendar.parseDate(c.calendar_dom.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)}},
@ -37,9 +142,9 @@ var Calendar = function(dom){
type: 'put' ,
datatype: 'JSON',
error: function(jqXHR, textStatus, errorThrown) {},
success: function(data) {
console.log('event was success updated');
}
success: function(data) {
console.log('event was success updated');
}
});
}
var success_event = function(data,allDay,type,addbtn){
@ -102,12 +207,12 @@ var Calendar = function(dom){
pickers.eq(i).val(value + " " + d.getHours() + ":" + d.getMinutes())
}
pickers.eq(i).ui_datetimepicker({
dateFormat: 'yy/mm/dd',
controlType: 'select',
timeInput: true,
oneLine: true,
timeFormat: 'HH:mm'
})
dateFormat: 'yy/mm/dd',
controlType: 'select',
timeInput: true,
oneLine: true,
timeFormat: 'HH:mm'
})
}
}
}
@ -144,7 +249,7 @@ var Calendar = function(dom){
if(type == "new")
c.renderEvent(data);
if(type == "edit")
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.fullCalendar("refetchEvents");
});
c.event_create_space.find("#event_period").change(function(){
//repeat_function();
@ -152,36 +257,66 @@ var Calendar = function(dom){
//repeat_function();
}
c.success_event = success_event;
var dview = (c.currentView == "agenda" ? "month" : c.currentView);
c.calendar.fullCalendar({
editable: true,
var dview = (c.currentView == "agenda" ? "dayGridMonth" : c.currentView);
c.calendar_dom.css("overflow","visible");
c.calendar_dom.fullCalendar({
themeSystem: 'bootstrap',
editable: false,
selectable: true,
events: window.location.href,
eventResize: change_event,
eventDrop: change_event ,
header: false,
default: dview,
width: "100%",
height: $(window).height() - 315,
events: function(args, success_callback, fail_callback) {
var start = args.start;
var end = args.end;
$.ajax({
url: window.location.href,
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);
}
});
},
// events: 'https://fullcalendar.io/demo-events.json',
headerToolbar: false,
fixedWeekCount: false,
initialView: dview,
loading: function(bool) {
if (bool) c.loading.css("left",($(window).width()/2 - 60) + "px").show();
if (bool) c.loading.show();
else c.loading.hide();
if(this.currentData)
$('#current_title').html(this.currentData.viewTitle);
},
windowResize : function(view){
view.setHeight($(window).height() - 315);
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
},
viewDisplay: function(view) {
c.title.html(view.title);
},
eventClick: function(calEvent, e, view) {
c.event_create_space.html("").hide();
c.dialog.dismiss();
c.dialog.inflate(calEvent);
c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
},
select : function(startDate, endDate, allDay, jsEvent, view){
var start = new Date(startDate),
end = new Date(endDate),
eventTimeFormat: { hour12: true, 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);
c.event_create_space.html("").hide();
c.dialog.dismiss();
c.dialog.inflate(calEvent);
c.dialog.show({"x": originalEvent.clientX,"y": originalEvent.clientY});
},
select : function(selectionInfo){
var jsEvent = selectionInfo.jsEvent,
view = selectionInfo.view;
var start = selectionInfo.start,
end = selectionInfo.end,
allDay = selectionInfo.allDay,
startString = start.getFullYear() + "/"+ (start.getMonth() + 1 > 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());
@ -193,15 +328,20 @@ var Calendar = function(dom){
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");
}
})
}
$.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");
}
})
},
views: {
dayGridMonth: {
dayMaxEvents: false
}
}
});
c.create_event_btn.click(function(){
$.ajax({
@ -215,19 +355,18 @@ var Calendar = function(dom){
});
c.nextBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('next');
c.calendar_dom.calendar.next();
});
c.prevBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('prev');
c.calendar_dom.calendar.prev();
});
c.todayBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('today');
c.calendar_dom.calendar.today();
});
c.modeBtns.click(function(){
c.dialog.dismiss();
c.event_create_space.html("").hide();
toggleViews($(this).data("mode"));
});
c.refreshBtn.click(function(){
@ -235,18 +374,17 @@ var Calendar = function(dom){
if(c.currentView == "agenda")
agendaView.refresh();
else
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
});
c.calendar.mouseup(function(e){
c.calendar_dom.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");
@ -254,7 +392,7 @@ var Calendar = function(dom){
// $("#sec3").addClass("span4").removeClass("span5");
agendaView.hide();
}
c.calendar.fullCalendar('changeView',view);
c.calendar_dom.calendar.changeView(view);
}else{
// $("#sec1").addClass("span7").removeClass("span3");
$("#sec2").hide();
@ -263,47 +401,22 @@ var Calendar = function(dom){
}
c.currentView = view;
if(loadeventsonviewchange){
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
loadeventsonviewchange = false;
}
}
if(c.calendar_dom.calendar.currentData){
var viewTitle = c.calendar_dom.calendar.currentData.viewTitle;
if(view == "timeGridDay" && $('.fc-col-header-cell-cushion ').text() != "")
viewTitle = $('.fc-col-header-cell-cushion ').text() + ', ' + viewTitle;
$('#current_title').html(viewTitle);
}
c.calendar_dom.calendar.render(); //Rerender to fix layout
};
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);
c.calendar_dom.fullCalendar("updateEvent",eventStick);
}
this.deleteEvent = function(delete_url,_id){
@ -311,7 +424,7 @@ var Calendar = function(dom){
type : "delete",
url : delete_url,
success : function(){
c.calendar.fullCalendar("removeEvents",[_id]);
c.calendar_dom.fullCalendar("removeEvents",[_id]);
c.dialog.dismiss();
}
})
@ -328,53 +441,80 @@ var Calendar = function(dom){
})
}
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;
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!");
_event.allDay = _event.event.allDay;
_event._start = _event.event.start;
_event._end = (_event.event.end ? _event.event.end : _event.event.start);
// var start_date = getDateString(_event._start,date_format);
// var end_date = getDateString(_event._end,date_format);
if(_event._end - _event._start > 86400 * 1000){
_event.allDay = true;
}
_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;
Event_e = _event
end_time = "",
time_string = null;
if(_event.allDay) {
start_time = $.fullCalendar.formatDate(_event._start,"MMM dd, yyyy");
start_time = getDateString(_event._start,datetime_format, is_chinese);
if(_event._end)
end_time = $.fullCalendar.formatDate(_event._end,"MMM dd, yyyy");
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + end_time + "");
end_time = getDateString(_event._end,datetime_format, is_chinese);
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /></i>" + start_time + "</p>" : "<i class='icons-calendar' /></i>" + start_time + "<br><i class='icons-arrow-right-5' /></i>" + 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 ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
start_time = getDateString(_event._start,date_format, is_chinese);
end_time = getDateString(_event._end,date_format, is_chinese);
var stime = getDateString(_event._start,time_format, is_chinese),
etime = getDateString(_event._end,time_format, is_chinese),
same = (start_time == end_time);
if( same ){
time_string = "<p class='date'><i class='icons-calendar' /></i> " +
start_time +
"</p><p class='time'><i class='icons-clock' /></i> " + stime +
" <i class='icons-arrow-right-5' /></i> " + etime ;
}else{
time_string = "<i class='icons-calendar' /></i><span class='start-date'>" + start_time + " " + stime +
"</span><br><i class='icons-arrow-right-5' /></i><span class='end-date'>" +
end_time + " " + etime + "</span>"
}
// time_string = (same ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
}
event_quick_view = $('<div class="modal calendar-modal" style="display:none;"></div>');
template = '<div class="modal-header">' +
event_quick_view = $('<div class="calendar-modal" style="display:none;"></div>');
template = '<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close event-close-btn" data-dismiss="modal" aria-hidden="true">&times;</button>' +
'<h3>'+ (_event.url_linked=='' ? _event.title : ("<a href=\"" +_event.url_linked+"\">"+_event.title+"</a>")) +'</h3>' +
'<h3>' + _event.title + '</h3>' +
'</div>' +
'<div class="modal-body">' +
'<div class="event_summary">' +
time_string +
'</div>' +
_event.note +
'</div>';
'<div class="event_summary">' + time_string + '</br>' + _event.hiring_person_name + '</div>' + _event.note +
(_event.error_message ? ("<br><span style=\"color: #FC4040;\">" + _event.error_message + "</span>") : "")
'</div>' +
'<div class="modal-footer" />' +
'</div>';
if(_event.can_edit){
template += '<div class="modal-footer">' +
'<a href="'+ _event.delete_url +'" class="delete btn btn-primary">Delete</a>' +
@ -383,17 +523,58 @@ var EventDialog = function(calendar,event){
}
}
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.offset(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;});
if(pos){
var pos = getPosition(pos);
event_quick_view.css({"left":pos.x+"px","top":pos.y+"px"});
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.offset(new_offset);
event_quick_view.width(new_width);
event_quick_view.height(new_height);
}
}
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();
@ -417,11 +598,11 @@ var EventDialog = function(calendar,event){
}
var UserException = function(message) {
this.message = message;
this.name = "UserException";
this.toString = function(){
return this.message;
}
this.message = message;
this.name = "UserException";
this.toString = function(){
return this.message;
}
}
var AgendaView = function(calendar){
@ -435,7 +616,7 @@ var AgendaView = function(calendar){
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 = '<div class="span4">' +
var month_template = '<div class="col-md-4">' +
'<h4></h4>' +
'<div class="tiny_calendar">' +
'<table class="table table-condensed table-bordered">' +
@ -454,31 +635,30 @@ var AgendaView = function(calendar){
'</div>' +
'</div>';
var event_list_template = '<div class="span8">' +
'<table class="table table-condensed table-bordered event_list">' +
'<thead>' +
'<tr>' +
'<th>Date</th>' +
'<th>Time</th>' +
'<th>Events</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td colspan="3" class="no_events">No events for this month.</td>' +
'</tr>' +
'</tbody>' +
'</table>' +
var event_list_template = '<div class="col-md-8 agenda-event">' +
'<table class="table table-condensed table-bordered event_list">' +
'<thead>' +
'<tr>' +
'<th>Date</th>' +
'<th>Time</th>' +
'<th>Events</th>' +
'<th>Borrower</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td colspan="3" class="no_events">No events for this month.</td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>';
var head_template = '<div>' +
'<label>From</label>' +
'<select name="start_month" class="input-small" />' +
'<select name="start_year" class="input-small" />' +
'<input class="input-large" id="agenda_start" placeholder="YYYY/MM" type="text" value="'+start_year+'/'+('0'+(start_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
'<label>To</label>' +
'<select name="end_month" class="input-small" />' +
'<select name="end_year" class="input-small" />' +
'<button id="show_events" class="btn bt-filter">Show Events</button>' +
'<input class="input-large" id="agenda_end" placeholder="YYYY/MM" type="text" value="'+end_year+'/'+('0'+(end_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
'<button id="show_events" class="btn btn-sm bt-filter btn-primary">Show Events</button>' +
'</div>';
var event_template = '<tr>' +
@ -487,7 +667,15 @@ var AgendaView = function(calendar){
'<td>' +
'<div class="event" />' +
'</td>' +
'<td class="Borrower">'+
'</tr>';
// var month_template = '<div class="span4"><h4></h4><div class="tiny_calendar"><table class="table"><tbody><tr><th class="week_title">Sun</th><th class="week_title">Mon</th><th class="week_title">Tue</th><th class="week_title">Wed</th><th class="week_title">Thu</th><th class="week_title">Fri</th><th class="week_title">Sat</th></tr></tbody></table></div></div>';
// var event_list_template = '<div class="span8"><table class="table event_list"><thead><tr height="0"><th class="span3"></th><th class="span2"></th><th class=""></th></tr></thead><tbody><tr><td colspan="3" class="no_events">No events for this month.</td></tr></tbody></table></div>';
// var head_template = '<div><label>From</label> <select name="start_month" class="input-small"></select><select name="start_year" class="input-small"></select><label>To</label> <select name="end_month" class="input-small"></select><select name="end_year" class="input-small"></select><button id="show_events" class="btn bt-filter">Show Events</button></div>';
// var event_template = "<tr><th></th><td class='event_time'></td><td><div class='event'></div></td></tr>";
var cache = false;
var show_event_clicked = false;
@ -498,7 +686,7 @@ var AgendaView = function(calendar){
this.inflate = function(forceInflation){
loading(true);
_calendar.calendar.hide();
_calendar.calendar_dom.hide();
_calendar.navigation.hide();
if(!forceInflation){
@ -515,10 +703,12 @@ var AgendaView = function(calendar){
_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());
var starts = $("#agenda_start").val().split("/"),
ends = $("#agenda_end").val().split("/");
start_month = parseInt(starts[1]) - 1;
end_month = parseInt(ends[1]) - 1;
start_year = parseInt(starts[0]);
end_year = parseInt(ends[0]);
av.inflate(true);
})
}
@ -552,7 +742,7 @@ var AgendaView = function(calendar){
_calendar.rangeSelection.hide();
agenda_space.hide();
_calendar.navigation.show();
_calendar.calendar.show();
_calendar.calendar_dom.show();
}
this.show = function(){
@ -571,9 +761,39 @@ var AgendaView = function(calendar){
$.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){
dataType : "json",
data : {"agenda_start":sd.toLocaleString(),"agenda_end":ed.toLocaleString(),"page_id" : _calendar.page_id,"start":usd,"end":ued},
success : function(data){
$("#agenda_start,#agenda_end").datepicker({
dateFormat: "yy/mm",
onChangeMonthYear: function( year, month, inst ){
$(this).val($.datepicker.formatDate('yy/mm', new Date(year, month-1, 1)));
},
gotoCurrent: true
});
$("#agenda_start,#agenda_end").on("focus",function(){
var input = this;
var inst = $(this).data("datepicker");
var year_month = $(input).val().split("/");
if(year_month.length == 2){
inst.selectedYear = parseInt(year_month[0]);
inst.selectedMonth = parseInt(year_month[1]) - 1;
inst.drawYear = inst.selectedYear;
inst.drawMonth = inst.selectedMonth;
inst.currentYear = inst.selectedYear;
inst.currentMonth = inst.selectedMonth;
}
$.datepicker._updateDatepicker(inst);
})
$("#agenda_start,#agenda_end").focus(function () {
$(".ui-datepicker-calendar").hide();
$("#ui-datepicker-div").position({
my: "center top",
at: "center bottom",
of: $(this)
});
});
$.each(data,function(i,e){
var ed = eventDom(e),
s = new Date(e.start),
e = new Date(e.end),
@ -622,20 +842,24 @@ var AgendaView = function(calendar){
if($(this).find("tr").length > 1)
$(this).find("td.no_events").parent().remove();
})
// nano scroller here
}
})
var eventDom = function(event){
var e_t = $(event_template),
s = new Date(event.start),
e = new Date(event.end),
dateFormat = "";
dateFormat = "",
hiring_person_name = event.hiring_person_name;
if(s.getDate() == e.getDate() && s.getMonth() == s.getMonth() && e.getFullYear() == e.getFullYear())
dateFormat = $.fullCalendar.formatDate(s, "ddd dd");
dateFormat = getDateString(s, short_day,is_chinese);
else
dateFormat = $.fullCalendar.formatDates(s, e, "ddd dd, MMM - {ddd dd, MMM}");
dateFormat = getDateString(s,short_date,is_chinese) + ' - ' + getDateString(e,short_date,is_chinese);
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("td.event_time").text((event.diff_day ? (getDateString(s, short_date_time,is_chinese)+"~"+getDateString(e, short_date_time, is_chinese)) : (getDateString(s, time_format)+"~"+getDateString(e, time_format))));
e_t.find("div.event").html(event.title).css("color",event.color);
e_t.find("td.Borrower").text(hiring_person_name);
return e_t;
}
@ -683,9 +907,10 @@ var AgendaView = function(calendar){
}
return head;
}
var Month = function(month,year){
_this = this;
this.monthDom = $("<div class='row-fluid' data-year='"+year+"' data-month='"+month+"'></div>");
this.monthDom = $("<div class='row' data-year='"+year+"' data-month='"+month+"'></div>");
var template = $(month_template);
var list_template = $(event_list_template);
var firstDay = new Date(year,month,1);
@ -714,21 +939,21 @@ var AgendaView = function(calendar){
}
function getNumberOfRows(year, month) {
var day = 1,
sat_counter = 0,
sunday_counter = 0,
date = new Date(year, month, day);
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);
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){
@ -775,34 +1000,5 @@ var AgendaView = function(calendar){
renderMonth();
}
}
}

View File

@ -1,7 +1,114 @@
window.auto_close_popup = false;
$.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.is_chinese = ( I18n && I18n.locale.indexOf('zh') != -1 );
window.datetime_format = is_chinese ? 'y M d h:m b' : 'd M, y h:m b';
window.date_format = is_chinese ? 'y M d' : 'd M, y';
window.time_format = "h:m b";
window.date_time_str_format = 'y/MM/d H:m';
window.std_date_format = 'y-MM-d';
window.short_day = (is_chinese ? "d (w)" : "w d");
window.short_date = (is_chinese ? "M d (w)" : "w d, M");
window.short_date_time = (is_chinese ? "M d (w) h:m b" : "w d, M h:m b");
window.getDateString = function(date, format,is_chinese) {
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var week_days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
if(is_chinese){
months = [];
for(var i=0;i<12;i++){
months.push((i+1)+"月");
}
week_days = ["週日","週一","週二","週三","週四","週五","週六"]
}
var getPaddedComp = function(comp) {
return ((parseInt(comp) < 10) ? ('0' + comp) : comp)
},
formattedDate = format,
o = {
"y+": date.getFullYear() + (is_chinese ? "年" : ""), // year
"MM+": getPaddedComp(date.getMonth() + 1), //raw month
"M+": months[date.getMonth()], //month
"d+": (is_chinese ? (date.getDate() + "日") : getPaddedComp(date.getDate())), //day
"w+": week_days[date.getDay()], //weekday
"h+": getPaddedComp((date.getHours() > 12) ? date.getHours() % 12 : date.getHours()), //hour
"H+": getPaddedComp(date.getHours()), //hour
"m+": getPaddedComp(date.getMinutes()), //minute
"s+": getPaddedComp(date.getSeconds()), //second
"S+": getPaddedComp(date.getMilliseconds()), //millisecond,
"b+": (date.getHours() >= 12) ? 'PM' : 'AM'
};
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=''){
c = this;
var c = this;
this.title = $("#current_title");
this.calendar = $(dom);
this.calendar_dom = $(dom);
this.nextBtn = $("#next_month_btn");
this.prevBtn = $("#prev_month_btn");
this.todayBtn = $("#today_btn");
@ -10,7 +117,7 @@ var Calendar = function(dom,page_id,event_date=''){
this.dialog = new EventDialog(c);
this.loading = $('#calendar-loading');
this.agenda_space = $("#calendar_agenda");
this.currentView = "month";
this.currentView = "dayGridMonth";
this.page_id = page_id;
this.navigation = $("#navigation");
this.rangeSelection = $("#range_selection");
@ -23,51 +130,103 @@ var Calendar = function(dom,page_id,event_date=''){
}else{
var date = new Date();
}
// var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var dview = (c.currentView == "agenda" ? "month" : c.currentView);
c.calendar.fullCalendar({
var dview = (c.currentView == "agenda" ? "dayGridMonth" : c.currentView);
c.calendar_dom.css("overflow","visible");
c.calendar_dom.fullCalendar({
themeSystem: 'bootstrap',
editable: false,
selectable: false,
events: "/xhr/calendars/events?page_id="+c.page_id+"&locale="+I18n.locale,
header: false,
default: dview,
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);
}
});
},
// events: 'https://fullcalendar.io/demo-events.json',
headerToolbar: false,
fixedWeekCount: false,
initialView: dview,
loading: function(bool) {
if (bool) c.loading.css("left",($(window).width()/2 - 60) + "px").show();
if (bool) c.loading.show();
else c.loading.hide();
if(this.currentData)
$('#current_title').html(this.currentData.viewTitle);
},
windowResize : function(view){
view.setHeight($("body").height() - 141);
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
},
viewDisplay: function(view) {
c.title.html(view.title);
eventTimeFormat: { hour12: true, 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});
}
},
eventClick: function(calEvent, e, view) {
c.dialog.dismiss();
c.dialog.inflate(calEvent);
c.dialog.show({"x":e.originalEvent.clientX,"y":e.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: {
dayGridMonth: {
dayMaxEvents: false
}
}
});
if (event_date != ''){
c.calendar.fullCalendar('gotoDate', y, (m - 1), d);
}
c.nextBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('next');
c.calendar_dom.calendar.next();
});
c.prevBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('prev');
c.calendar_dom.calendar.prev();
});
c.todayBtn.click(function(){
c.dialog.dismiss();
c.calendar.fullCalendar('today');
c.calendar_dom.calendar.today();
});
c.modeBtns.click(function(){
c.dialog.dismiss();
@ -78,7 +237,7 @@ var Calendar = function(dom,page_id,event_date=''){
if(c.currentView == "agenda")
agendaView.refresh();
else
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
});
var toggleViews = function(view){
@ -86,7 +245,7 @@ var Calendar = function(dom,page_id,event_date=''){
c.modeBtns.each(function(){
if ($(this).data("mode") == view)
$(this).addClass("active");
})
});
if(view != "agenda"){
if(c.currentView == "agenda"){
// $("#sec1").addClass("span3").removeClass("span7");
@ -94,7 +253,7 @@ var Calendar = function(dom,page_id,event_date=''){
// $("#sec3").addClass("span4").removeClass("span5");
agendaView.hide();
}
c.calendar.fullCalendar('changeView',view);
c.calendar_dom.calendar.changeView(view);
}else{
// $("#sec1").addClass("span7").removeClass("span3");
$("#sec2").hide();
@ -103,67 +262,117 @@ var Calendar = function(dom,page_id,event_date=''){
}
c.currentView = view;
if(loadeventsonviewchange){
c.calendar.fullCalendar("refetchEvents");
c.calendar_dom.calendar.refetchEvents();
loadeventsonviewchange = false;
}
}
if(c.calendar_dom.calendar.currentData){
var viewTitle = c.calendar_dom.calendar.currentData.viewTitle;
if(view == "timeGridDay" && $('.fc-col-header-cell-cushion ').text() != "")
viewTitle = $('.fc-col-header-cell-cushion ').text() + ', ' + viewTitle;
$('#current_title').html(viewTitle);
}
c.calendar_dom.calendar.render(); //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.fullCalendar("refetchEvents");
if(eventStick.recurring === true)
c.calendar_dom.calendar.refetchEvents();
else
c.calendar.fullCalendar("renderEvent",eventStick);
}
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;
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!");
_event.allDay = _event.event.allDay;
_event._start = _event.event.start;
_event._end = (_event.event.end ? _event.event.end : _event.event.start);
// var start_date = getDateString(_event._start,date_format);
// var end_date = getDateString(_event._end,date_format);
if(_event._end - _event._start > 86400 * 1000){
_event.allDay = true;
}
_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;
end_time = "",
time_string = null;
if(_event.allDay) {
start_time = $.fullCalendar.formatDate(_event._start,"MMM dd, yyyy");
start_time = getDateString(_event._start,datetime_format, is_chinese);
if(_event._end)
end_time = $.fullCalendar.formatDate(_event._end,"MMM dd, yyyy");
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + end_time + "");
end_time = getDateString(_event._end,datetime_format, is_chinese);
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /></i>" + start_time + "</p>" : "<i class='icons-calendar' /></i>" + start_time + "<br><i class='icons-arrow-right-5' /></i>" + 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 ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
start_time = getDateString(_event._start,date_format, is_chinese);
end_time = getDateString(_event._end,date_format, is_chinese);
var stime = getDateString(_event._start,time_format, is_chinese),
etime = getDateString(_event._end,time_format, is_chinese),
same = (start_time == end_time);
if( same ){
time_string = "<p class='date'><i class='icons-calendar' /></i> " +
start_time +
"</p><p class='time'><i class='icons-clock' /></i> " + stime +
" <i class='icons-arrow-right-5' /></i> " + etime ;
}else{
time_string = "<i class='icons-calendar' /></i><span class='start-date'>" + start_time + " " + stime +
"</span><br><i class='icons-arrow-right-5' /></i><span class='end-date'>" +
end_time + " " + etime + "</span>"
}
// time_string = (same ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
}
event_quick_view = $('<div class="calendar-modal" style="display:none;"></div>');
template = '<div class="modal-content">' +
'<div class="modal-header">' +
'<div class="modal-header">' +
'<button type="button" class="close event-close-btn" data-dismiss="modal" aria-hidden="true">&times;</button>' +
'<h3>' + (_event.url_linked=='' ? _event.title : ("<a href=\"" +_event.url_linked+"\">"+_event.title+"</a>")) + '</h3>' +
'</div>' +
'<div class="modal-body">' +
'<div class="event_summary">' + time_string + '</div>' +
_event.note +
'<div class="event_summary">' + time_string + '</br>' + _event.hiring_person_name + '</div>' + _event.note +
(_event.error_message ? ("<br><span style=\"color: #FC4040;\">" + _event.error_message + "</span>") : "")
'</div>' +
'<div class="modal-footer" />' +
'</div>';
@ -171,16 +380,56 @@ var EventDialog = function(calendar,event){
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.offset(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;});
if(pos){
var pos = getPosition(pos);
event_quick_view.css({"left":pos.x+"px","top":pos.y+"px"});
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.offset(new_offset);
event_quick_view.width(new_width);
event_quick_view.height(new_height);
}
}
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();
@ -248,6 +497,7 @@ var AgendaView = function(calendar){
'<th>Date</th>' +
'<th>Time</th>' +
'<th>Events</th>' +
'<th>Borrower</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
@ -260,11 +510,9 @@ var AgendaView = function(calendar){
var head_template = '<div>' +
'<label>From</label>' +
'<select name="start_month" class="form-control input-sm" />' +
'<select name="start_year" class="form-control input-sm" />' +
'<input class="input-large" id="agenda_start" placeholder="YYYY/MM" type="text" value="'+start_year+'/'+('0'+(start_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
'<label>To</label>' +
'<select name="end_month" class="form-control input-sm" />' +
'<select name="end_year" class="form-control input-sm" />' +
'<input class="input-large" id="agenda_end" placeholder="YYYY/MM" type="text" value="'+end_year+'/'+('0'+(end_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
'<button id="show_events" class="btn btn-sm bt-filter btn-primary">Show Events</button>' +
'</div>';
@ -274,6 +522,7 @@ var AgendaView = function(calendar){
'<td>' +
'<div class="event" />' +
'</td>' +
'<td class="Borrower">'+
'</tr>';
// var month_template = '<div class="span4"><h4></h4><div class="tiny_calendar"><table class="table"><tbody><tr><th class="week_title">Sun</th><th class="week_title">Mon</th><th class="week_title">Tue</th><th class="week_title">Wed</th><th class="week_title">Thu</th><th class="week_title">Fri</th><th class="week_title">Sat</th></tr></tbody></table></div></div>';
@ -292,7 +541,7 @@ var AgendaView = function(calendar){
this.inflate = function(forceInflation){
loading(true);
_calendar.calendar.hide();
_calendar.calendar_dom.hide();
_calendar.navigation.hide();
if(!forceInflation){
@ -309,10 +558,12 @@ var AgendaView = function(calendar){
_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());
var starts = $("#agenda_start").val().split("/"),
ends = $("#agenda_end").val().split("/");
start_month = parseInt(starts[1]) - 1;
end_month = parseInt(ends[1]) - 1;
start_year = parseInt(starts[0]);
end_year = parseInt(ends[0]);
av.inflate(true);
})
}
@ -346,7 +597,7 @@ var AgendaView = function(calendar){
_calendar.rangeSelection.hide();
agenda_space.hide();
_calendar.navigation.show();
_calendar.calendar.show();
_calendar.calendar_dom.show();
}
this.show = function(){
@ -358,16 +609,46 @@ var AgendaView = function(calendar){
}
var eventsManager = function(){
var url = "/xhr/calendars/agenda",
sd = new Date(Date.UTC(start_year,start_month,1)),
ed = new Date(Date.UTC(end_year,end_month+1,0)),
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(),"page_id" : _calendar.page_id,"unix_start":usd,"unix_end":ued},
dataType : "json",
data : {"agenda_start":sd.toLocaleString(),"agenda_end":ed.toLocaleString(),"page_id" : _calendar.page_id,"start":usd,"end":ued},
success : function(data){
$.each(data.events,function(i,e){
$("#agenda_start,#agenda_end").datepicker({
dateFormat: "yy/mm",
onChangeMonthYear: function( year, month, inst ){
$(this).val($.datepicker.formatDate('yy/mm', new Date(year, month-1, 1)));
},
gotoCurrent: true
});
$("#agenda_start,#agenda_end").on("focus",function(){
var input = this;
var inst = $(this).data("datepicker");
var year_month = $(input).val().split("/");
if(year_month.length == 2){
inst.selectedYear = parseInt(year_month[0]);
inst.selectedMonth = parseInt(year_month[1]) - 1;
inst.drawYear = inst.selectedYear;
inst.drawMonth = inst.selectedMonth;
inst.currentYear = inst.selectedYear;
inst.currentMonth = inst.selectedMonth;
}
$.datepicker._updateDatepicker(inst);
})
$("#agenda_start,#agenda_end").focus(function () {
$(".ui-datepicker-calendar").hide();
$("#ui-datepicker-div").position({
my: "center top",
at: "center bottom",
of: $(this)
});
});
$.each(data,function(i,e){
var ed = eventDom(e),
s = new Date(e.start),
e = new Date(e.end),
@ -395,7 +676,7 @@ var AgendaView = function(calendar){
c_m = s.getMonth(),
c_d = s.getDate(),
c_y = s.getFullYear(),
end_of_c_month = new Date(Date.UTC(s.getFullYear(),s.getMonth()+1,0)).getDate();
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+"]");
@ -424,14 +705,16 @@ var AgendaView = function(calendar){
var e_t = $(event_template),
s = new Date(event.start),
e = new Date(event.end),
dateFormat = "";
dateFormat = "",
hiring_person_name = event.hiring_person_name;
if(s.getDate() == e.getDate() && s.getMonth() == s.getMonth() && e.getFullYear() == e.getFullYear())
dateFormat = $.fullCalendar.formatDate(s, "ddd dd");
dateFormat = getDateString(s, short_day,is_chinese);
else
dateFormat = $.fullCalendar.formatDates(s, e, "ddd dd, MMM - {ddd dd, MMM}");
dateFormat = getDateString(s,short_date,is_chinese) + ' - ' + getDateString(e,short_date,is_chinese);
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("td.event_time").text((event.diff_day ? (getDateString(s, short_date_time,is_chinese)+"~"+getDateString(e, short_date_time, is_chinese)) : (getDateString(s, time_format)+"~"+getDateString(e, time_format))));
e_t.find("div.event").html(event.title).css("color",event.color);
e_t.find("td.Borrower").text(hiring_person_name);
return e_t;
}
@ -485,8 +768,8 @@ var AgendaView = function(calendar){
this.monthDom = $("<div class='row' data-year='"+year+"' data-month='"+month+"'></div>");
var template = $(month_template);
var list_template = $(event_list_template);
var firstDay = new Date(Date.UTC(year,month,1));
var lastDay = new Date(Date.UTC(year,month+1,0));
var firstDay = new Date(year,month,1);
var lastDay = new Date(year,month+1,0);
var last_inserted_date = 1;
var renderMonth = function(){
@ -514,7 +797,7 @@ var AgendaView = function(calendar){
var day = 1,
sat_counter = 0,
sunday_counter = 0,
date = new Date(Date.UTC(year, month, day));
date = new Date(year, month, day);
while(date.getMonth() === month) {
if(date.getDay() === 0) {
@ -523,7 +806,7 @@ var AgendaView = function(calendar){
sat_counter++;
}
day++;
date = new Date(Date.UTC(year, month, day));
date = new Date(year, month, day);
}
return (sunday_counter == 5 && sat_counter == 5 ? 6 : 5);
}
@ -573,34 +856,4 @@ var AgendaView = function(calendar){
renderMonth();
}
}
}

View File

@ -0,0 +1,606 @@
var Calendar = function(dom,page_id,event_date=''){
c = this;
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.dialog = new EventDialog(c);
this.loading = $('#calendar-loading');
this.agenda_space = $("#calendar_agenda");
this.currentView = "month";
this.page_id = page_id;
this.navigation = $("#navigation");
this.rangeSelection = $("#range_selection");
var agendaView = new AgendaView(c);
var loadeventsonviewchange = false;
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 date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var dview = (c.currentView == "agenda" ? "month" : c.currentView);
c.calendar.fullCalendar({
editable: false,
selectable: false,
events: "/xhr/calendars/events?page_id="+c.page_id+"&locale="+I18n.locale,
header: false,
default: dview,
height: $("body").height() - 141,
loading: function(bool) {
if (bool) c.loading.css("left",($(window).width()/2 - 60) + "px").show();
else c.loading.hide();
},
windowResize : function(view){
view.setHeight($("body").height() - 141);
c.calendar.fullCalendar("refetchEvents");
},
viewDisplay: function(view) {
c.title.html(view.title);
},
eventClick: function(calEvent, e, view) {
c.dialog.dismiss();
c.dialog.inflate(calEvent);
c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
}
});
if (event_date != ''){
c.calendar.fullCalendar('gotoDate', y, (m - 1), d);
}
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();
toggleViews($(this).data("mode"));
});
c.refreshBtn.click(function(){
c.dialog.dismiss();
if(c.currentView == "agenda")
agendaView.refresh();
else
c.calendar.fullCalendar("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.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;}
}
this.renderEvent = function(eventStick){
if(eventStick.recurring == true)
c.calendar.fullCalendar("refetchEvents");
else
c.calendar.fullCalendar("renderEvent",eventStick);
}
$(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;
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 ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + 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 ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
}
event_quick_view = $('<div class="calendar-modal" style="display:none;"></div>');
template = '<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close event-close-btn" data-dismiss="modal" aria-hidden="true">&times;</button>' +
'<h3>' + (_event.url_linked=='' ? _event.title : ("<a href=\"" +_event.url_linked+"\">"+_event.title+"</a>")) + '</h3>' +
'</div>' +
'<div class="modal-body">' +
'<div class="event_summary">' + time_string + '</div>' +
_event.note +
'</div>' +
'<div class="modal-footer" />' +
'</div>';
}
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 = '<div class="col-md-4">' +
'<h4></h4>' +
'<div class="tiny_calendar">' +
'<table class="table table-condensed table-bordered">' +
'<tbody>' +
'<tr>' +
'<th class="week_title">Sun</th>' +
'<th class="week_title">Mon</th>' +
'<th class="week_title">Tue</th>' +
'<th class="week_title">Wed</th>' +
'<th class="week_title">Thu</th>' +
'<th class="week_title">Fri</th>' +
'<th class="week_title">Sat</th>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>' +
'</div>';
var event_list_template = '<div class="col-md-8 agenda-event">' +
'<table class="table table-condensed table-bordered event_list">' +
'<thead>' +
'<tr>' +
'<th>Date</th>' +
'<th>Time</th>' +
'<th>Events</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td colspan="3" class="no_events">No events for this month.</td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>';
var head_template = '<div>' +
'<label>From</label>' +
'<select name="start_month" class="form-control input-sm" />' +
'<select name="start_year" class="form-control input-sm" />' +
'<label>To</label>' +
'<select name="end_month" class="form-control input-sm" />' +
'<select name="end_year" class="form-control input-sm" />' +
'<button id="show_events" class="btn btn-sm bt-filter btn-primary">Show Events</button>' +
'</div>';
var event_template = '<tr>' +
'<td />' +
'<td class="event_time" />' +
'<td>' +
'<div class="event" />' +
'</td>' +
'</tr>';
// var month_template = '<div class="span4"><h4></h4><div class="tiny_calendar"><table class="table"><tbody><tr><th class="week_title">Sun</th><th class="week_title">Mon</th><th class="week_title">Tue</th><th class="week_title">Wed</th><th class="week_title">Thu</th><th class="week_title">Fri</th><th class="week_title">Sat</th></tr></tbody></table></div></div>';
// var event_list_template = '<div class="span8"><table class="table event_list"><thead><tr height="0"><th class="span3"></th><th class="span2"></th><th class=""></th></tr></thead><tbody><tr><td colspan="3" class="no_events">No events for this month.</td></tr></tbody></table></div>';
// var head_template = '<div><label>From</label> <select name="start_month" class="input-small"></select><select name="start_year" class="input-small"></select><label>To</label> <select name="end_month" class="input-small"></select><select name="end_year" class="input-small"></select><button id="show_events" class="btn bt-filter">Show Events</button></div>';
// var event_template = "<tr><th></th><td class='event_time'></td><td><div class='event'></div></td></tr>";
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 = "/xhr/calendars/agenda",
sd = new Date(Date.UTC(start_year,start_month,1)),
ed = new Date(Date.UTC(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(),"page_id" : _calendar.page_id,"unix_start":usd,"unix_end":ued},
success : function(data){
$.each(data.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(Date.UTC(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();
})
// nano scroller here
}
})
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 = $("<option value='"+i+"'>"+monthNames[i]+"</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 = $("<option value='"+i+"'>"+monthNames[i]+"</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 = $("<option value='"+y+"'>"+y+"</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 = $("<option value='"+y+"'>"+y+"</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 = $("<div class='row' data-year='"+year+"' data-month='"+month+"'></div>");
var template = $(month_template);
var list_template = $(event_list_template);
var firstDay = new Date(Date.UTC(year,month,1));
var lastDay = new Date(Date.UTC(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(Date.UTC(year, month, day));
while(date.getMonth() === month) {
if(date.getDay() === 0) {
sunday_counter++;
}else if(date.getDay() === 6) {
sat_counter++;
}
day++;
date = new Date(Date.UTC(year, month, day));
}
return (sunday_counter == 5 && sat_counter == 5 ? 6 : 5);
}
var makeRow = function(position){
if(last_inserted_date <= lastDay.getDate()){
var row = $("<tr></tr>");
switch (position){
case "first":
for(var i = 0;i < 7;i++){
var td = $("<td></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></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 = $("<td></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();
}
}

View File

@ -0,0 +1,824 @@
$.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<pickers.length;i++){
pickers.eq(i).ui_datetimepicker("destroy");
pickers.eq(i).attr('placeholder','yyyy/MM/dd')
var value = pickers.eq(i).val()
if (value != ''){
pickers.eq(i).val(value.split(" ")[0])
}
pickers.eq(i).ui_datepicker({dateFormat: 'yy/mm/dd',show_view: ''})
}
}else{
for(i=0;i<pickers.length;i++){
pickers.eq(i).ui_datepicker("destroy");
pickers.eq(i).attr('placeholder','yyyy/MM/dd HH:mm')
var value = pickers.eq(i).val()
if (value != ''){
pickers.eq(i).val(value + " " + d.getHours() + ":" + d.getMinutes())
}
pickers.eq(i).ui_datetimepicker({
dateFormat: 'yy/mm/dd',
controlType: 'select',
timeInput: true,
oneLine: true,
timeFormat: 'HH:mm'
})
}
}
}
var repeat_function = function(){
if(c.event_create_space.find("#event_period").val() == c.event_create_space.find("#event_period option:eq(0)").val()){
c.event_create_space.find("#event_frequency").attr("disabled","disabled");
}else{
c.event_create_space.find("#event_frequency").removeAttr("disabled");
}
}
$("a.btn-close").one("click",function(){
c.event_create_space.html("").hide();
$('.bootstrap-datetimepicker-widget').remove();
return false;
});
$("#all_day_check").change(function(){
if($(this).is(":checked")){
checked = true;
}else{
checked = false;
}
checked_function(checked);
});
$("#recurring_checkbox").click(function(){
if($(this).is(":checked"))
$("#recurring_panel").show();
else
$("#recurring_panel").hide();
})
$('form[data-remote]').bind("ajax:success",function(evt, data, status){
c.event_create_space.html("").hide();
if(type == "new")
c.renderEvent(data);
if(type == "edit")
c.calendar.fullCalendar("refetchEvents");
});
c.event_create_space.find("#event_period").change(function(){
//repeat_function();
})
//repeat_function();
}
c.success_event = success_event;
var dview = (c.currentView == "agenda" ? "month" : c.currentView);
c.calendar.fullCalendar({
editable: true,
selectable: true,
events: window.location.href,
eventResize: change_event,
eventDrop: change_event ,
header: false,
default: dview,
height: $(window).height() - 315,
loading: function(bool) {
if (bool) c.loading.css("left",($(window).width()/2 - 60) + "px").show();
else c.loading.hide();
},
windowResize : function(view){
view.setHeight($(window).height() - 315);
c.calendar.fullCalendar("refetchEvents");
},
viewDisplay: function(view) {
c.title.html(view.title);
},
eventClick: function(calEvent, e, view) {
c.event_create_space.html("").hide();
c.dialog.dismiss();
c.dialog.inflate(calEvent);
c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
},
select : function(startDate, endDate, allDay, jsEvent, view){
var start = new Date(startDate),
end = new Date(endDate),
startString = start.getFullYear() + "/"+ (start.getMonth() + 1 > 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 ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + 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 ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
}
event_quick_view = $('<div class="modal calendar-modal" style="display:none;"></div>');
template = '<div class="modal-header">' +
'<button type="button" class="close event-close-btn" data-dismiss="modal" aria-hidden="true">&times;</button>' +
'<h3>'+ (_event.url_linked=='' ? _event.title : ("<a href=\"" +_event.url_linked+"\">"+_event.title+"</a>")) +'</h3>' +
'</div>' +
'<div class="modal-body">' +
'<div class="event_summary">' +
time_string +
'</div>' +
_event.note +
'</div>';
if(_event.can_edit){
template += '<div class="modal-footer">' +
'<a href="'+ _event.delete_url +'" class="delete btn btn-primary">Delete</a>' +
'<a href="'+ _event.edit_url +'" class="edit btn btn-primary" >Edit</a>' +
'</div>';
}
}
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 = '<div class="span4">' +
'<h4></h4>' +
'<div class="tiny_calendar">' +
'<table class="table table-condensed table-bordered">' +
'<tbody>' +
'<tr>' +
'<th class="week_title">Sun</th>' +
'<th class="week_title">Mon</th>' +
'<th class="week_title">Tue</th>' +
'<th class="week_title">Wed</th>' +
'<th class="week_title">Thu</th>' +
'<th class="week_title">Fri</th>' +
'<th class="week_title">Sat</th>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>' +
'</div>';
var event_list_template = '<div class="span8">' +
'<table class="table table-condensed table-bordered event_list">' +
'<thead>' +
'<tr>' +
'<th>Date</th>' +
'<th>Time</th>' +
'<th>Events</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr>' +
'<td colspan="3" class="no_events">No events for this month.</td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>';
var head_template = '<div>' +
'<label>From</label>' +
'<select name="start_month" class="input-small" />' +
'<select name="start_year" class="input-small" />' +
'<label>To</label>' +
'<select name="end_month" class="input-small" />' +
'<select name="end_year" class="input-small" />' +
'<button id="show_events" class="btn bt-filter">Show Events</button>' +
'</div>';
var event_template = '<tr>' +
'<td />' +
'<td class="event_time" />' +
'<td>' +
'<div class="event" />' +
'</td>' +
'</tr>';
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 = $("<option value='"+i+"'>"+monthNames[i]+"</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 = $("<option value='"+i+"'>"+monthNames[i]+"</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 = $("<option value='"+y+"'>"+y+"</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 = $("<option value='"+y+"'>"+y+"</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 = $("<div class='row-fluid' data-year='"+year+"' data-month='"+month+"'></div>");
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 = $("<tr></tr>");
switch (position){
case "first":
for(var i = 0;i < 7;i++){
var td = $("<td></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></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 = $("<td></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();
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,579 @@
/*!
* FullCalendar v1.6.1 Stylesheet
* Docs & License: http://arshaw.com/fullcalendar/
* (c) 2013 Adam Shaw
*/
.fc {
direction: ltr;
text-align: left;
}
.fc table {
border-collapse: collapse;
border-spacing: 0;
}
html .fc,
.fc table {
font-size: 1em;
}
.fc td,
.fc th {
padding: 0;
vertical-align: top;
}
/* Header
------------------------------------------------------------------------*/
.fc-header td {
white-space: nowrap;
}
.fc-header-left {
width: 25%;
text-align: left;
}
.fc-header-center {
text-align: center;
}
.fc-header-right {
width: 25%;
text-align: right;
}
.fc-header-title {
display: inline-block;
vertical-align: top;
}
.fc-header-title h2 {
margin-top: 0;
white-space: nowrap;
}
.fc .fc-header-space {
padding-left: 10px;
}
.fc-header .fc-button {
margin-bottom: 1em;
vertical-align: top;
}
/* buttons edges butting together */
.fc-header .fc-button {
margin-right: -1px;
}
.fc-header .fc-corner-right, /* non-theme */
.fc-header .ui-corner-right { /* theme */
margin-right: 0; /* back to normal */
}
/* button layering (for border precedence) */
.fc-header .fc-state-hover,
.fc-header .ui-state-hover {
z-index: 2;
}
.fc-header .fc-state-down {
z-index: 3;
}
.fc-header .fc-state-active,
.fc-header .ui-state-active {
z-index: 4;
}
/* Content
------------------------------------------------------------------------*/
.fc-content {
clear: both;
}
.fc-view {
width: 100%; /* needed for view switching (when view is absolute) */
overflow: hidden;
}
/* Cell Styles
------------------------------------------------------------------------*/
.fc-widget-header, /* <th>, usually */
.fc-widget-content { /* <td>, usually */
border: 1px solid #ddd;
}
.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */
background: #fcf8e3;
}
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
background: #bce8f1;
opacity: .3;
filter: alpha(opacity=30); /* for IE */
}
/* Buttons
------------------------------------------------------------------------*/
.fc-button {
position: relative;
display: inline-block;
padding: 0 .6em;
overflow: hidden;
height: 1.9em;
line-height: 1.9em;
white-space: nowrap;
cursor: pointer;
}
.fc-state-default { /* non-theme */
border: 1px solid;
}
.fc-state-default.fc-corner-left { /* non-theme */
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.fc-state-default.fc-corner-right { /* non-theme */
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
/*
Our default prev/next buttons use HTML entities like &lsaquo; &rsaquo; &laquo; &raquo;
and we'll try to make them look good cross-browser.
*/
.fc-text-arrow {
margin: 0 .1em;
font-size: 2em;
font-family: "Courier New", Courier, monospace;
vertical-align: baseline; /* for IE7 */
}
.fc-button-prev .fc-text-arrow,
.fc-button-next .fc-text-arrow { /* for &lsaquo; &rsaquo; */
font-weight: bold;
}
/* icon (for jquery ui) */
.fc-button .fc-icon-wrap {
position: relative;
float: left;
top: 50%;
}
.fc-button .ui-icon {
position: relative;
float: left;
margin-top: -50%;
*margin-top: 0;
*top: -50%;
}
/*
button states
borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)
*/
.fc-state-default {
background-color: #f5f5f5;
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
background-repeat: repeat-x;
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
color: #333;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.fc-state-hover,
.fc-state-down,
.fc-state-active,
.fc-state-disabled {
color: #333333;
background-color: #e6e6e6;
}
.fc-state-hover {
color: #333333;
text-decoration: none;
background-position: 0 -15px;
-webkit-transition: background-position 0.1s linear;
-moz-transition: background-position 0.1s linear;
-o-transition: background-position 0.1s linear;
transition: background-position 0.1s linear;
}
.fc-state-down,
.fc-state-active {
background-color: #cccccc;
background-image: none;
outline: 0;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.fc-state-disabled {
cursor: default;
background-image: none;
opacity: 0.65;
filter: alpha(opacity=65);
box-shadow: none;
}
/* Global Event Styles
------------------------------------------------------------------------*/
.fc-event {
border: 1px solid #3a87ad; /* default BORDER color */
background-color: #3a87ad; /* default BACKGROUND color */
color: #fff; /* default TEXT color */
font-size: .85em;
cursor: default;
}
a.fc-event {
text-decoration: none;
}
a.fc-event,
.fc-event-draggable {
cursor: pointer;
}
.fc-rtl .fc-event {
text-align: right;
}
.fc-event-inner {
width: 100%;
height: 100%;
overflow: hidden;
}
.fc-event-time,
.fc-event-title {
padding: 0 1px;
}
.fc .ui-resizable-handle {
display: block;
position: absolute;
z-index: 99999;
overflow: hidden; /* hacky spaces (IE6/7) */
font-size: 300%; /* */
line-height: 50%; /* */
}
/* Horizontal Events
------------------------------------------------------------------------*/
.fc-event-hori {
border-width: 1px 0;
margin-bottom: 1px;
}
.fc-ltr .fc-event-hori.fc-event-start,
.fc-rtl .fc-event-hori.fc-event-end {
border-left-width: 1px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.fc-ltr .fc-event-hori.fc-event-end,
.fc-rtl .fc-event-hori.fc-event-start {
border-right-width: 1px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
/* resizable */
.fc-event-hori .ui-resizable-e {
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
right: -3px !important;
width: 7px !important;
height: 100% !important;
cursor: e-resize;
}
.fc-event-hori .ui-resizable-w {
top: 0 !important;
left: -3px !important;
width: 7px !important;
height: 100% !important;
cursor: w-resize;
}
.fc-event-hori .ui-resizable-handle {
_padding-bottom: 14px; /* IE6 had 0 height */
}
/* Reusable Separate-border Table
------------------------------------------------------------*/
table.fc-border-separate {
border-collapse: separate;
}
.fc-border-separate th,
.fc-border-separate td {
border-width: 1px 0 0 1px;
}
.fc-border-separate th.fc-last,
.fc-border-separate td.fc-last {
border-right-width: 1px;
}
.fc-border-separate tr.fc-last th,
.fc-border-separate tr.fc-last td {
border-bottom-width: 1px;
}
.fc-border-separate tbody tr.fc-first td,
.fc-border-separate tbody tr.fc-first th {
border-top-width: 0;
}
/* Month View, Basic Week View, Basic Day View
------------------------------------------------------------------------*/
.fc-grid th {
text-align: center;
}
.fc .fc-week-number {
width: 22px;
text-align: center;
}
.fc .fc-week-number div {
padding: 0 2px;
}
.fc-grid .fc-day-number {
float: right;
padding: 0 2px;
}
.fc-grid .fc-other-month .fc-day-number {
opacity: 0.3;
filter: alpha(opacity=30); /* for IE */
/* opacity with small font can sometimes look too faded
might want to set the 'color' property instead
making day-numbers bold also fixes the problem */
}
.fc-grid .fc-day-content {
clear: both;
padding: 2px 2px 1px; /* distance between events and day edges */
}
/* event styles */
.fc-grid .fc-event-time {
font-weight: bold;
}
/* right-to-left */
.fc-rtl .fc-grid .fc-day-number {
float: left;
}
.fc-rtl .fc-grid .fc-event-time {
float: right;
}
/* Agenda Week View, Agenda Day View
------------------------------------------------------------------------*/
.fc-agenda table {
border-collapse: separate;
}
.fc-agenda-days th {
text-align: center;
}
.fc-agenda .fc-agenda-axis {
width: 50px;
padding: 0 4px;
vertical-align: middle;
text-align: right;
white-space: nowrap;
font-weight: normal;
}
.fc-agenda .fc-week-number {
font-weight: bold;
}
.fc-agenda .fc-day-content {
padding: 2px 2px 1px;
}
/* make axis border take precedence */
.fc-agenda-days .fc-agenda-axis {
border-right-width: 1px;
}
.fc-agenda-days .fc-col0 {
border-left-width: 0;
}
/* all-day area */
.fc-agenda-allday th {
border-width: 0 1px;
}
.fc-agenda-allday .fc-day-content {
/*min-height: 34px; *//* TODO: doesnt work well in quirksmode */
_height: 34px;
}
/* divider (between all-day and slots) */
.fc-agenda-divider-inner {
height: 2px;
overflow: hidden;
}
.fc-widget-header .fc-agenda-divider-inner {
background: #eee;
}
/* slot rows */
.fc-agenda-slots th {
border-width: 1px 1px 0;
}
.fc-agenda-slots td {
border-width: 1px 0 0;
background: none;
}
.fc-agenda-slots td div {
height: 20px;
}
.fc-agenda-slots tr.fc-slot0 th,
.fc-agenda-slots tr.fc-slot0 td {
border-top-width: 0;
}
.fc-agenda-slots tr.fc-minor th,
.fc-agenda-slots tr.fc-minor td {
border-top-style: dotted;
}
.fc-agenda-slots tr.fc-minor th.ui-widget-header {
*border-top-style: solid; /* doesn't work with background in IE6/7 */
}
/* Vertical Events
------------------------------------------------------------------------*/
.fc-event-vert {
border-width: 0 1px;
}
.fc-event-vert.fc-event-start {
border-top-width: 1px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.fc-event-vert.fc-event-end {
border-bottom-width: 1px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.fc-event-vert .fc-event-time {
white-space: nowrap;
font-size: 10px;
}
.fc-event-vert .fc-event-inner {
position: relative;
z-index: 2;
}
.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: .25;
filter: alpha(opacity=25);
}
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
.fc-select-helper .fc-event-bg {
display: none\9; /* for IE6/7/8. nested opacity filters while dragging don't work */
}
/* resizable */
.fc-event-vert .ui-resizable-s {
bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
width: 100% !important;
height: 8px !important;
overflow: hidden !important;
line-height: 8px !important;
font-size: 11px !important;
font-family: monospace;
text-align: center;
cursor: s-resize;
}
.fc-agenda .ui-resizable-resizing { /* TODO: better selector */
_overflow: hidden;
}

View File

@ -114,10 +114,9 @@ class Admin::CalendarsController < OrbitAdminController
@event = Event.new(p)
if @event.present? && @event.save
e = @event.to_json
e = JSON.parse(e)
e["can_edit"] = true
render json: e.to_json
event_json = @event.as_json
event_json["can_edit"] = true
render json: event_json.to_json
else
respond_to do |format|
format.html { render action: "new" }

View File

@ -83,8 +83,7 @@ class Event
if cat_ids.blank?
self.all
else
type_ids = CalendarType.where(:category_id.in=>cat_ids).pluck(:id)
self.where(:calendar_type_id.in => type_ids)
self.where(:calendar_type_id.in => cat_ids)
end
end
def bulletin
@ -107,24 +106,26 @@ class Event
:id => self.id.to_s,
:title => self.title,
:note => self.note || "",
:start => self.start.rfc822,
:end => self.end.rfc822,
:start => self.start.to_json.gsub('"',''),
:end => self.end.to_json.gsub('"',''),
:allDay => self.all_day,
:recurring => self.recurring,
:calendar => self.calendar_type_id.to_s,
:color => (self.calendar_type.color rescue nil)
:color => (self.calendar_type.color rescue nil),
:diff_day => self.all_day
}
else
{
:id => self.id.to_s,
:title => self.title,
:note => self.note || "",
:start => self.start.rfc822,
:end => self.end.rfc822,
:start => self.start.to_json.gsub('"',''),
:end => self.end.to_json.gsub('"',''),
:allDay => self.all_day,
:recurring => self.recurring,
:calendar => self.calendar_type_id.to_s,
:color => (self.calendar_type.color rescue nil),
:diff_day => self.all_day,
:edit_url => Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>self.id),
:delete_url => Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>self.id)
}