2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
var fc = $.fullCalendar = {};
|
|
|
|
var views = fc.views = {};
|
|
|
|
|
|
|
|
|
|
|
|
/* Defaults
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var defaults = {
|
|
|
|
|
|
|
|
// display
|
|
|
|
defaultView: 'month',
|
|
|
|
aspectRatio: 1.35,
|
|
|
|
header: {
|
2009-10-19 07:33:14 +02:00
|
|
|
left: 'title',
|
|
|
|
center: '',
|
|
|
|
right: 'today prev,next'
|
2009-09-08 05:01:28 +02:00
|
|
|
},
|
2009-11-01 00:51:30 +01:00
|
|
|
weekends: true,
|
2009-09-08 05:01:28 +02:00
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
// editing
|
|
|
|
//editable: false,
|
|
|
|
//disableDragging: false,
|
|
|
|
//disableResizing: false,
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
allDayDefault: true,
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
// event ajax
|
2010-02-22 01:35:45 +01:00
|
|
|
lazyFetching: true,
|
2009-09-08 05:01:28 +02:00
|
|
|
startParam: 'start',
|
|
|
|
endParam: 'end',
|
|
|
|
|
|
|
|
// time formats
|
|
|
|
titleFormat: {
|
|
|
|
month: 'MMMM yyyy',
|
2009-09-14 00:25:49 +02:00
|
|
|
week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}",
|
2009-09-08 05:01:28 +02:00
|
|
|
day: 'dddd, MMM d, yyyy'
|
|
|
|
},
|
|
|
|
columnFormat: {
|
|
|
|
month: 'ddd',
|
|
|
|
week: 'ddd M/d',
|
|
|
|
day: 'dddd M/d'
|
|
|
|
},
|
2009-10-10 10:12:40 +02:00
|
|
|
timeFormat: { // for event elements
|
|
|
|
'': 'h(:mm)t' // default
|
|
|
|
},
|
2009-09-08 05:01:28 +02:00
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
// locale
|
2009-09-08 05:01:28 +02:00
|
|
|
isRTL: false,
|
2009-09-21 06:57:20 +02:00
|
|
|
firstDay: 0,
|
2009-09-08 05:01:28 +02:00
|
|
|
monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
|
|
|
monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
|
|
|
|
dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
|
|
|
|
dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
|
|
|
|
buttonText: {
|
2009-09-21 06:57:20 +02:00
|
|
|
prev: ' ◄ ',
|
|
|
|
next: ' ► ',
|
2009-10-19 07:33:14 +02:00
|
|
|
prevYear: ' << ',
|
|
|
|
nextYear: ' >> ',
|
2009-09-08 05:01:28 +02:00
|
|
|
today: 'today',
|
|
|
|
month: 'month',
|
|
|
|
week: 'week',
|
|
|
|
day: 'day'
|
|
|
|
},
|
|
|
|
|
|
|
|
// jquery-ui theming
|
|
|
|
theme: false,
|
|
|
|
buttonIcons: {
|
|
|
|
prev: 'circle-triangle-w',
|
|
|
|
next: 'circle-triangle-e'
|
2010-04-23 05:27:14 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
//selectable: false,
|
2010-07-06 01:07:40 +02:00
|
|
|
unselectAuto: true,
|
|
|
|
|
|
|
|
dropAccept: '*'
|
2009-09-21 06:57:20 +02:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// right-to-left defaults
|
|
|
|
var rtlDefaults = {
|
|
|
|
header: {
|
2009-10-19 07:33:14 +02:00
|
|
|
left: 'next,prev today',
|
|
|
|
center: '',
|
|
|
|
right: 'title'
|
2009-09-08 05:01:28 +02:00
|
|
|
},
|
|
|
|
buttonText: {
|
2009-09-21 06:57:20 +02:00
|
|
|
prev: ' ► ',
|
2009-10-19 07:33:14 +02:00
|
|
|
next: ' ◄ ',
|
|
|
|
prevYear: ' >> ',
|
|
|
|
nextYear: ' << '
|
2009-10-19 10:53:07 +02:00
|
|
|
},
|
|
|
|
buttonIcons: {
|
|
|
|
prev: 'circle-triangle-e',
|
|
|
|
next: 'circle-triangle-w'
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// function for adding/overriding defaults
|
|
|
|
var setDefaults = fc.setDefaults = function(d) {
|
|
|
|
$.extend(true, defaults, d);
|
2010-03-14 02:06:13 +01:00
|
|
|
};
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* .fullCalendar jQuery function
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
$.fn.fullCalendar = function(options) {
|
|
|
|
|
|
|
|
// method calling
|
|
|
|
if (typeof options == 'string') {
|
2009-09-21 06:57:20 +02:00
|
|
|
var args = Array.prototype.slice.call(arguments, 1),
|
|
|
|
res;
|
2009-09-08 05:01:28 +02:00
|
|
|
this.each(function() {
|
2010-02-21 02:44:24 +01:00
|
|
|
var data = $.data(this, 'fullCalendar');
|
|
|
|
if (data) {
|
2010-05-03 06:47:23 +02:00
|
|
|
var meth = data[options];
|
|
|
|
if (meth) {
|
|
|
|
var r = meth.apply(this, args);
|
|
|
|
if (res === undefined) {
|
|
|
|
res = r;
|
|
|
|
}
|
2010-02-21 02:44:24 +01:00
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
});
|
2010-03-14 02:06:13 +01:00
|
|
|
if (res !== undefined) {
|
2009-09-08 05:01:28 +02:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// pluck the 'events' and 'eventSources' options
|
|
|
|
var eventSources = options.eventSources || [];
|
|
|
|
delete options.eventSources;
|
|
|
|
if (options.events) {
|
|
|
|
eventSources.push(options.events);
|
2009-10-05 07:47:26 +02:00
|
|
|
delete options.events;
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// first event source reserved for 'sticky' events
|
|
|
|
eventSources.unshift([]);
|
|
|
|
|
|
|
|
// initialize options
|
|
|
|
options = $.extend(true, {},
|
|
|
|
defaults,
|
2010-03-14 02:06:13 +01:00
|
|
|
(options.isRTL || options.isRTL===undefined && defaults.isRTL) ? rtlDefaults : {},
|
2009-09-08 05:01:28 +02:00
|
|
|
options
|
|
|
|
);
|
2009-09-21 06:57:20 +02:00
|
|
|
var tm = options.theme ? 'ui' : 'fc'; // for making theme classes
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
this.each(function() {
|
|
|
|
|
|
|
|
|
|
|
|
/* Instance Initialization
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
// element
|
|
|
|
var _element = this,
|
2009-12-21 10:32:03 +01:00
|
|
|
element = $(_element).addClass('fc'),
|
2010-02-16 07:32:43 +01:00
|
|
|
elementOuterWidth,
|
|
|
|
content = $("<div class='fc-content " + tm + "-widget-content' style='position:relative'/>").prependTo(_element),
|
|
|
|
suggestedViewHeight,
|
|
|
|
resizeUID = 0,
|
|
|
|
ignoreWindowResize = 0,
|
|
|
|
date = new Date(),
|
|
|
|
viewName, // the current view name (TODO: look into getting rid of)
|
|
|
|
view, // the current view
|
2010-02-22 04:17:40 +01:00
|
|
|
viewInstances = {},
|
|
|
|
absoluteViewElement;
|
2010-02-16 07:32:43 +01:00
|
|
|
|
|
|
|
|
2009-12-31 03:45:39 +01:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
if (options.isRTL) {
|
|
|
|
element.addClass('fc-rtl');
|
|
|
|
}
|
|
|
|
if (options.theme) {
|
|
|
|
element.addClass('ui-widget');
|
|
|
|
}
|
2010-07-04 01:15:34 +02:00
|
|
|
|
|
|
|
setYMD(date, options.year, options.month, options.date);
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* View Rendering
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
function changeView(v) {
|
2009-09-08 05:01:28 +02:00
|
|
|
if (v != viewName) {
|
2010-02-22 01:35:45 +01:00
|
|
|
ignoreWindowResize++; // because setMinHeight might change the height before render (and subsequently setSize) is reached
|
2010-05-03 06:47:23 +02:00
|
|
|
|
2010-05-23 02:30:16 +02:00
|
|
|
viewUnselect();
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2010-02-19 06:10:53 +01:00
|
|
|
var oldView = view,
|
|
|
|
newViewElement;
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
if (oldView) {
|
|
|
|
if (oldView.eventsChanged) {
|
|
|
|
eventsDirty();
|
|
|
|
oldView.eventDirty = oldView.eventsChanged = false;
|
2009-10-05 07:47:26 +02:00
|
|
|
}
|
2010-02-21 02:44:24 +01:00
|
|
|
if (oldView.beforeHide) {
|
|
|
|
oldView.beforeHide(); // called before changing min-height. if called after, scroll state is reset (in Opera)
|
|
|
|
}
|
|
|
|
setMinHeight(content, content.height());
|
2010-02-16 07:32:43 +01:00
|
|
|
oldView.element.hide();
|
2010-02-21 02:44:24 +01:00
|
|
|
}else{
|
|
|
|
setMinHeight(content, 1); // needs to be 1 (not 0) for IE7, or else view dimensions miscalculated
|
2009-10-05 07:47:26 +02:00
|
|
|
}
|
2010-02-21 02:44:24 +01:00
|
|
|
content.css('overflow', 'hidden');
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
if (viewInstances[v]) {
|
|
|
|
(view = viewInstances[v]).element.show();
|
|
|
|
}else{
|
2010-05-23 02:30:16 +02:00
|
|
|
view = viewInstances[v] = fc.views[v](
|
2010-02-22 04:17:40 +01:00
|
|
|
newViewElement = absoluteViewElement =
|
|
|
|
$("<div class='fc-view fc-view-" + v + "' style='position:absolute'/>")
|
|
|
|
.appendTo(content),
|
2010-07-04 03:00:38 +02:00
|
|
|
options,
|
|
|
|
v // the view's name
|
2010-02-19 06:10:53 +01:00
|
|
|
);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
if (header) {
|
2009-09-21 06:57:20 +02:00
|
|
|
// update 'active' view button
|
2009-09-08 05:01:28 +02:00
|
|
|
header.find('div.fc-button-' + viewName).removeClass(tm + '-state-active');
|
|
|
|
header.find('div.fc-button-' + v).addClass(tm + '-state-active');
|
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2010-07-04 03:00:38 +02:00
|
|
|
viewName = v;
|
2010-02-22 04:17:40 +01:00
|
|
|
render(); // after height has been set, will make absoluteViewElement's position=relative, then set to null
|
2010-02-21 02:44:24 +01:00
|
|
|
content.css('overflow', '');
|
2010-02-16 07:32:43 +01:00
|
|
|
if (oldView) {
|
2010-02-22 01:35:45 +01:00
|
|
|
setMinHeight(content, 1);
|
2010-02-16 07:32:43 +01:00
|
|
|
}
|
2010-02-20 08:11:44 +01:00
|
|
|
if (!newViewElement && view.afterShow) {
|
|
|
|
view.afterShow(); // called after setting min-height/overflow, so in final scroll state (for Opera)
|
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
|
|
|
|
ignoreWindowResize--;
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-22 01:35:45 +01:00
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
function render(inc) {
|
2010-02-22 01:35:45 +01:00
|
|
|
if (elementVisible()) {
|
|
|
|
ignoreWindowResize++; // because view.renderEvents might temporarily change the height before setSize is reached
|
2010-05-03 06:47:23 +02:00
|
|
|
|
2010-05-23 02:30:16 +02:00
|
|
|
viewUnselect();
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2010-03-14 02:06:13 +01:00
|
|
|
if (suggestedViewHeight === undefined) {
|
2010-02-21 02:44:24 +01:00
|
|
|
calcSize();
|
|
|
|
}
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
if (!view.start || inc || date < view.start || date >= view.end) {
|
|
|
|
view.render(date, inc || 0); // responsible for clearing events
|
2010-02-20 08:11:44 +01:00
|
|
|
setSize(true);
|
2010-02-22 01:35:45 +01:00
|
|
|
if (!eventStart || !options.lazyFetching || view.visStart < eventStart || view.visEnd > eventEnd) {
|
|
|
|
fetchAndRenderEvents();
|
2010-02-16 07:32:43 +01:00
|
|
|
}else{
|
|
|
|
view.renderEvents(events); // don't refetch
|
|
|
|
}
|
2009-10-01 07:39:02 +02:00
|
|
|
}
|
2010-02-22 01:35:45 +01:00
|
|
|
else if (view.sizeDirty || view.eventsDirty || !options.lazyFetching) {
|
2009-10-01 07:39:02 +02:00
|
|
|
view.clearEvents();
|
2010-02-16 07:32:43 +01:00
|
|
|
if (view.sizeDirty) {
|
|
|
|
setSize();
|
|
|
|
}
|
2010-02-22 01:35:45 +01:00
|
|
|
if (options.lazyFetching) {
|
|
|
|
view.renderEvents(events); // don't refetch
|
|
|
|
}else{
|
|
|
|
fetchAndRenderEvents();
|
|
|
|
}
|
2009-10-01 07:39:02 +02:00
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
elementOuterWidth = element.outerWidth();
|
|
|
|
view.sizeDirty = false;
|
|
|
|
view.eventsDirty = false;
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
if (header) {
|
2009-10-01 07:39:02 +02:00
|
|
|
// update title text
|
|
|
|
header.find('h2.fc-header-title').html(view.title);
|
2009-10-13 06:22:40 +02:00
|
|
|
// enable/disable 'today' button
|
|
|
|
var today = new Date();
|
|
|
|
if (today >= view.start && today < view.end) {
|
|
|
|
header.find('div.fc-button-today').addClass(tm + '-state-disabled');
|
|
|
|
}else{
|
|
|
|
header.find('div.fc-button-today').removeClass(tm + '-state-disabled');
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
|
|
|
|
ignoreWindowResize--;
|
2010-02-22 01:35:45 +01:00
|
|
|
view.trigger('viewDisplay', _element);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-21 02:44:24 +01:00
|
|
|
|
|
|
|
function elementVisible() {
|
|
|
|
return _element.offsetWidth !== 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function bodyVisible() {
|
|
|
|
return $('body')[0].offsetWidth !== 0;
|
|
|
|
}
|
2010-05-03 06:47:23 +02:00
|
|
|
|
2010-05-23 02:30:16 +02:00
|
|
|
function viewUnselect() {
|
|
|
|
if (view) {
|
|
|
|
view.unselect();
|
2010-05-03 06:47:23 +02:00
|
|
|
}
|
|
|
|
}
|
2010-02-21 02:44:24 +01:00
|
|
|
|
|
|
|
|
2009-11-29 09:12:36 +01:00
|
|
|
// called when any event objects have been added/removed/changed, rerenders
|
|
|
|
function eventsChanged() {
|
2010-02-16 07:32:43 +01:00
|
|
|
eventsDirty();
|
2010-02-21 02:44:24 +01:00
|
|
|
if (elementVisible()) {
|
|
|
|
view.clearEvents();
|
|
|
|
view.renderEvents(events);
|
|
|
|
view.eventsDirty = false;
|
|
|
|
}
|
2009-11-29 09:12:36 +01:00
|
|
|
}
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
// marks other views' events as dirty
|
|
|
|
function eventsDirty() {
|
2009-09-21 12:11:08 +02:00
|
|
|
$.each(viewInstances, function() {
|
2010-02-16 07:32:43 +01:00
|
|
|
this.eventsDirty = true;
|
2009-09-21 12:11:08 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2009-11-29 09:12:36 +01:00
|
|
|
// called when we know the element size has changed
|
2010-02-16 07:32:43 +01:00
|
|
|
function sizeChanged() {
|
|
|
|
sizesDirty();
|
2010-02-21 02:44:24 +01:00
|
|
|
if (elementVisible()) {
|
|
|
|
calcSize();
|
|
|
|
setSize();
|
2010-05-29 07:11:26 +02:00
|
|
|
viewUnselect();
|
2010-02-21 02:44:24 +01:00
|
|
|
view.rerenderEvents();
|
2010-02-22 01:35:45 +01:00
|
|
|
view.sizeDirty = false;
|
2010-02-21 02:44:24 +01:00
|
|
|
}
|
2009-11-29 09:12:36 +01:00
|
|
|
}
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
// marks other views' sizes as dirty
|
|
|
|
function sizesDirty() {
|
|
|
|
$.each(viewInstances, function() {
|
|
|
|
this.sizeDirty = true;
|
|
|
|
});
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
/* Event Sources and Fetching
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var events = [],
|
|
|
|
eventStart, eventEnd;
|
|
|
|
|
|
|
|
// Fetch from ALL sources. Clear 'events' array and populate
|
|
|
|
function fetchEvents(callback) {
|
|
|
|
events = [];
|
|
|
|
eventStart = cloneDate(view.visStart);
|
|
|
|
eventEnd = cloneDate(view.visEnd);
|
|
|
|
var queued = eventSources.length,
|
|
|
|
sourceDone = function() {
|
2010-03-14 02:06:13 +01:00
|
|
|
if (!--queued) {
|
2009-09-08 05:01:28 +02:00
|
|
|
if (callback) {
|
|
|
|
callback(events);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, i=0;
|
|
|
|
for (; i<eventSources.length; i++) {
|
|
|
|
fetchEventSource(eventSources[i], sourceDone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch from a particular source. Append to the 'events' array
|
|
|
|
function fetchEventSource(src, callback) {
|
2009-09-21 06:57:20 +02:00
|
|
|
var prevViewName = view.name,
|
|
|
|
prevDate = cloneDate(date),
|
2009-09-14 12:28:23 +02:00
|
|
|
reportEvents = function(a) {
|
2009-12-21 10:32:03 +01:00
|
|
|
if (prevViewName == view.name && +prevDate == +date && // protects from fast switching
|
|
|
|
$.inArray(src, eventSources) != -1) { // makes sure source hasn't been removed
|
|
|
|
for (var i=0; i<a.length; i++) {
|
|
|
|
normalizeEvent(a[i], options);
|
|
|
|
a[i].source = src;
|
|
|
|
}
|
|
|
|
events = events.concat(a);
|
|
|
|
if (callback) {
|
|
|
|
callback(a);
|
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
},
|
2009-09-21 06:57:20 +02:00
|
|
|
reportEventsAndPop = function(a) {
|
2009-09-14 12:28:23 +02:00
|
|
|
reportEvents(a);
|
|
|
|
popLoading();
|
2009-09-08 05:01:28 +02:00
|
|
|
};
|
|
|
|
if (typeof src == 'string') {
|
|
|
|
var params = {};
|
|
|
|
params[options.startParam] = Math.round(eventStart.getTime() / 1000);
|
|
|
|
params[options.endParam] = Math.round(eventEnd.getTime() / 1000);
|
2009-12-21 10:32:03 +01:00
|
|
|
if (options.cacheParam) {
|
|
|
|
params[options.cacheParam] = (new Date()).getTime(); // TODO: deprecate cacheParam
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
pushLoading();
|
2009-12-21 10:32:03 +01:00
|
|
|
$.ajax({
|
|
|
|
url: src,
|
|
|
|
dataType: 'json',
|
|
|
|
data: params,
|
2010-01-27 08:58:43 +01:00
|
|
|
cache: options.cacheParam || false, // don't let jquery prevent caching if cacheParam is being used
|
2009-12-21 10:32:03 +01:00
|
|
|
success: reportEventsAndPop
|
|
|
|
});
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
else if ($.isFunction(src)) {
|
|
|
|
pushLoading();
|
2009-09-21 06:57:20 +02:00
|
|
|
src(cloneDate(eventStart), cloneDate(eventEnd), reportEventsAndPop);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
else {
|
2009-09-14 12:28:23 +02:00
|
|
|
reportEvents(src); // src is an array
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-22 01:35:45 +01:00
|
|
|
// for convenience
|
|
|
|
function fetchAndRenderEvents() {
|
|
|
|
fetchEvents(function(events) {
|
|
|
|
view.renderEvents(events); // maintain `this` in view
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
/* Loading State
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var loadingLevel = 0;
|
|
|
|
|
|
|
|
function pushLoading() {
|
2009-09-14 00:25:49 +02:00
|
|
|
if (!loadingLevel++) {
|
|
|
|
view.trigger('loading', _element, true);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function popLoading() {
|
2009-09-14 00:25:49 +02:00
|
|
|
if (!--loadingLevel) {
|
|
|
|
view.trigger('loading', _element, false);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Public Methods
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var publicMethods = {
|
|
|
|
|
2009-11-29 05:43:02 +01:00
|
|
|
render: function() {
|
2010-02-21 02:44:24 +01:00
|
|
|
calcSize();
|
2010-02-16 07:32:43 +01:00
|
|
|
sizesDirty();
|
|
|
|
eventsDirty();
|
|
|
|
render();
|
2009-11-29 05:43:02 +01:00
|
|
|
},
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
changeView: changeView,
|
|
|
|
|
2009-11-29 05:43:02 +01:00
|
|
|
getView: function() {
|
|
|
|
return view;
|
|
|
|
},
|
|
|
|
|
2009-11-23 10:50:53 +01:00
|
|
|
getDate: function() {
|
|
|
|
return date;
|
|
|
|
},
|
|
|
|
|
2009-11-29 09:12:36 +01:00
|
|
|
option: function(name, value) {
|
2010-03-14 02:06:13 +01:00
|
|
|
if (value === undefined) {
|
2009-11-23 10:50:53 +01:00
|
|
|
return options[name];
|
|
|
|
}
|
2009-11-29 09:12:36 +01:00
|
|
|
if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
|
2010-02-22 01:35:45 +01:00
|
|
|
options[name] = value;
|
|
|
|
sizeChanged();
|
2009-11-29 09:12:36 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2009-12-21 10:32:03 +01:00
|
|
|
destroy: function() {
|
|
|
|
$(window).unbind('resize', windowResize);
|
|
|
|
if (header) {
|
|
|
|
header.remove();
|
|
|
|
}
|
|
|
|
content.remove();
|
|
|
|
$.removeData(_element, 'fullCalendar');
|
|
|
|
},
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
//
|
|
|
|
// Navigation
|
|
|
|
//
|
|
|
|
|
|
|
|
prev: function() {
|
|
|
|
render(-1);
|
|
|
|
},
|
|
|
|
|
|
|
|
next: function() {
|
|
|
|
render(1);
|
|
|
|
},
|
|
|
|
|
2009-10-12 09:01:26 +02:00
|
|
|
prevYear: function() {
|
|
|
|
addYears(date, -1);
|
|
|
|
render();
|
|
|
|
},
|
|
|
|
|
|
|
|
nextYear: function() {
|
|
|
|
addYears(date, 1);
|
|
|
|
render();
|
|
|
|
},
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
today: function() {
|
|
|
|
date = new Date();
|
|
|
|
render();
|
|
|
|
},
|
|
|
|
|
2009-09-14 12:28:23 +02:00
|
|
|
gotoDate: function(year, month, dateNum) {
|
2009-10-14 09:01:55 +02:00
|
|
|
if (typeof year == 'object') {
|
|
|
|
date = cloneDate(year); // provided 1 argument, a Date
|
|
|
|
}else{
|
2010-07-04 01:15:34 +02:00
|
|
|
setYMD(date, year, month, dateNum);
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
2010-01-20 19:19:10 +01:00
|
|
|
render();
|
2009-09-14 00:25:49 +02:00
|
|
|
},
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
incrementDate: function(years, months, days) {
|
2010-03-14 02:06:13 +01:00
|
|
|
if (years !== undefined) {
|
2009-09-14 12:28:23 +02:00
|
|
|
addYears(date, years);
|
|
|
|
}
|
2010-03-14 02:06:13 +01:00
|
|
|
if (months !== undefined) {
|
2009-09-14 12:28:23 +02:00
|
|
|
addMonths(date, months);
|
|
|
|
}
|
2010-03-14 02:06:13 +01:00
|
|
|
if (days !== undefined) {
|
2009-09-14 12:28:23 +02:00
|
|
|
addDays(date, days);
|
|
|
|
}
|
|
|
|
render();
|
2009-09-14 00:25:49 +02:00
|
|
|
},
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
//
|
2009-09-21 06:57:20 +02:00
|
|
|
// Event Manipulation
|
2009-09-08 05:01:28 +02:00
|
|
|
//
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
updateEvent: function(event) { // update an existing event
|
|
|
|
var i, len = events.length, e,
|
|
|
|
startDelta = event.start - event._start,
|
|
|
|
endDelta = event.end ?
|
|
|
|
(event.end - (event._end || view.defaultEventEnd(event))) // event._end would be null if event.end
|
|
|
|
: 0; // was null and event was just resized
|
2009-09-08 05:01:28 +02:00
|
|
|
for (i=0; i<len; i++) {
|
|
|
|
e = events[i];
|
2009-09-14 12:28:23 +02:00
|
|
|
if (e._id == event._id && e != event) {
|
|
|
|
e.start = new Date(+e.start + startDelta);
|
|
|
|
if (event.end) {
|
|
|
|
if (e.end) {
|
|
|
|
e.end = new Date(+e.end + endDelta);
|
|
|
|
}else{
|
|
|
|
e.end = new Date(+view.defaultEventEnd(e) + endDelta);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
}else{
|
|
|
|
e.end = null;
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
e.title = event.title;
|
2009-09-21 12:11:08 +02:00
|
|
|
e.url = event.url;
|
2009-09-14 12:28:23 +02:00
|
|
|
e.allDay = event.allDay;
|
2009-09-21 06:57:20 +02:00
|
|
|
e.className = event.className;
|
|
|
|
e.editable = event.editable;
|
2009-10-01 07:39:02 +02:00
|
|
|
normalizeEvent(e, options);
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
2009-10-01 07:39:02 +02:00
|
|
|
normalizeEvent(event, options);
|
2009-09-14 12:28:23 +02:00
|
|
|
eventsChanged();
|
|
|
|
},
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
renderEvent: function(event, stick) { // render a new event
|
2009-10-01 07:39:02 +02:00
|
|
|
normalizeEvent(event, options);
|
2009-09-14 12:28:23 +02:00
|
|
|
if (!event.source) {
|
|
|
|
if (stick) {
|
|
|
|
(event.source = eventSources[0]).push(event);
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
events.push(event);
|
|
|
|
}
|
|
|
|
eventsChanged();
|
|
|
|
},
|
|
|
|
|
2009-09-14 12:28:23 +02:00
|
|
|
removeEvents: function(filter) {
|
|
|
|
if (!filter) { // remove all
|
|
|
|
events = [];
|
|
|
|
// clear all array sources
|
|
|
|
for (var i=0; i<eventSources.length; i++) {
|
|
|
|
if (typeof eventSources[i] == 'object') {
|
|
|
|
eventSources[i] = [];
|
|
|
|
}
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}else{
|
2009-09-14 12:28:23 +02:00
|
|
|
if (!$.isFunction(filter)) { // an event ID
|
|
|
|
var id = filter + '';
|
|
|
|
filter = function(e) {
|
|
|
|
return e._id == id;
|
|
|
|
};
|
|
|
|
}
|
2009-09-17 08:30:10 +02:00
|
|
|
events = $.grep(events, filter, true);
|
2009-09-14 12:28:23 +02:00
|
|
|
// remove events from array sources
|
|
|
|
for (var i=0; i<eventSources.length; i++) {
|
|
|
|
if (typeof eventSources[i] == 'object') {
|
2009-09-17 08:30:10 +02:00
|
|
|
eventSources[i] = $.grep(eventSources[i], filter, true);
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
eventsChanged();
|
2009-09-08 05:01:28 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
clientEvents: function(filter) {
|
2009-09-14 12:28:23 +02:00
|
|
|
if ($.isFunction(filter)) {
|
2009-09-17 08:30:10 +02:00
|
|
|
return $.grep(events, filter);
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
|
|
|
else if (filter) { // an event ID
|
|
|
|
filter += '';
|
2009-09-17 08:30:10 +02:00
|
|
|
return $.grep(events, function(e) {
|
2009-09-14 12:28:23 +02:00
|
|
|
return e._id == filter;
|
|
|
|
});
|
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
return events; // else, return all
|
2009-09-08 05:01:28 +02:00
|
|
|
},
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
rerenderEvents: eventsChanged, // TODO: think of renaming eventsChanged
|
2009-09-14 00:25:49 +02:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
//
|
|
|
|
// Event Source
|
|
|
|
//
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
addEventSource: function(source) {
|
|
|
|
eventSources.push(source);
|
2010-02-22 01:35:45 +01:00
|
|
|
fetchEventSource(source, eventsChanged);
|
2009-09-08 05:01:28 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
removeEventSource: function(source) {
|
2009-09-17 08:30:10 +02:00
|
|
|
eventSources = $.grep(eventSources, function(src) {
|
2009-09-08 05:01:28 +02:00
|
|
|
return src != source;
|
|
|
|
});
|
|
|
|
// remove all client events from that source
|
2009-09-17 08:30:10 +02:00
|
|
|
events = $.grep(events, function(e) {
|
2009-09-08 05:01:28 +02:00
|
|
|
return e.source != source;
|
|
|
|
});
|
|
|
|
eventsChanged();
|
2009-09-14 00:25:49 +02:00
|
|
|
},
|
|
|
|
|
2009-09-14 12:28:23 +02:00
|
|
|
refetchEvents: function() {
|
|
|
|
fetchEvents(eventsChanged);
|
2010-05-23 02:30:16 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
//
|
|
|
|
// selection
|
|
|
|
//
|
|
|
|
|
|
|
|
select: function(start, end, allDay) {
|
2010-05-29 07:11:26 +02:00
|
|
|
view.select(start, end, allDay===undefined ? true : allDay);
|
2010-05-23 02:30:16 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
unselect: function() {
|
|
|
|
view.unselect();
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2010-05-29 07:11:26 +02:00
|
|
|
$.data(this, 'fullCalendar', publicMethods); // TODO: look into memory leak implications
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Header
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var header,
|
|
|
|
sections = options.header;
|
|
|
|
if (sections) {
|
|
|
|
header = $("<table class='fc-header'/>")
|
|
|
|
.append($("<tr/>")
|
|
|
|
.append($("<td class='fc-header-left'/>").append(buildSection(sections.left)))
|
|
|
|
.append($("<td class='fc-header-center'/>").append(buildSection(sections.center)))
|
|
|
|
.append($("<td class='fc-header-right'/>").append(buildSection(sections.right))))
|
|
|
|
.prependTo(element);
|
|
|
|
}
|
|
|
|
function buildSection(buttonStr) {
|
|
|
|
if (buttonStr) {
|
2009-09-21 06:57:20 +02:00
|
|
|
var tr = $("<tr/>");
|
2009-09-08 05:01:28 +02:00
|
|
|
$.each(buttonStr.split(' '), function(i) {
|
|
|
|
if (i > 0) {
|
|
|
|
tr.append("<td><span class='fc-header-space'/></td>");
|
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
var prevButton;
|
2009-10-19 10:53:07 +02:00
|
|
|
$.each(this.split(','), function(j, buttonName) {
|
2009-09-08 05:01:28 +02:00
|
|
|
if (buttonName == 'title') {
|
2009-11-29 09:12:36 +01:00
|
|
|
tr.append("<td><h2 class='fc-header-title'> </h2></td>");
|
2009-09-21 06:57:20 +02:00
|
|
|
if (prevButton) {
|
|
|
|
prevButton.addClass(tm + '-corner-right');
|
|
|
|
}
|
|
|
|
prevButton = null;
|
2009-09-08 05:01:28 +02:00
|
|
|
}else{
|
2009-09-14 12:28:23 +02:00
|
|
|
var buttonClick;
|
2009-10-12 08:35:33 +02:00
|
|
|
if (publicMethods[buttonName]) {
|
|
|
|
buttonClick = publicMethods[buttonName];
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
else if (views[buttonName]) {
|
2009-10-19 07:33:14 +02:00
|
|
|
buttonClick = function() {
|
|
|
|
button.removeClass(tm + '-state-hover');
|
2010-03-14 02:06:13 +01:00
|
|
|
changeView(buttonName);
|
2009-10-19 07:33:14 +02:00
|
|
|
};
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
if (buttonClick) {
|
2009-09-21 06:57:20 +02:00
|
|
|
if (prevButton) {
|
|
|
|
prevButton.addClass(tm + '-no-right');
|
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
var button,
|
2009-10-13 06:22:40 +02:00
|
|
|
icon = options.theme ? smartProperty(options.buttonIcons, buttonName) : null,
|
|
|
|
text = smartProperty(options.buttonText, buttonName);
|
2009-09-14 12:28:23 +02:00
|
|
|
if (icon) {
|
|
|
|
button = $("<div class='fc-button-" + buttonName + " ui-state-default'>" +
|
|
|
|
"<a><span class='ui-icon ui-icon-" + icon + "'/></a></div>");
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
else if (text) {
|
|
|
|
button = $("<div class='fc-button-" + buttonName + " " + tm + "-state-default'>" +
|
|
|
|
"<a><span>" + text + "</span></a></div>");
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-09-14 12:28:23 +02:00
|
|
|
if (button) {
|
|
|
|
button
|
2009-10-13 06:22:40 +02:00
|
|
|
.click(function() {
|
|
|
|
if (!button.hasClass(tm + '-state-disabled')) {
|
|
|
|
buttonClick();
|
|
|
|
}
|
|
|
|
})
|
2009-09-14 12:28:23 +02:00
|
|
|
.mousedown(function() {
|
2009-10-19 07:33:14 +02:00
|
|
|
button
|
|
|
|
.not('.' + tm + '-state-active')
|
|
|
|
.not('.' + tm + '-state-disabled')
|
|
|
|
.addClass(tm + '-state-down');
|
2009-09-14 12:28:23 +02:00
|
|
|
})
|
|
|
|
.mouseup(function() {
|
|
|
|
button.removeClass(tm + '-state-down');
|
|
|
|
})
|
|
|
|
.hover(
|
|
|
|
function() {
|
2009-10-19 07:33:14 +02:00
|
|
|
button
|
|
|
|
.not('.' + tm + '-state-active')
|
|
|
|
.not('.' + tm + '-state-disabled')
|
|
|
|
.addClass(tm + '-state-hover');
|
2009-09-14 12:28:23 +02:00
|
|
|
},
|
|
|
|
function() {
|
2009-10-19 07:33:14 +02:00
|
|
|
button
|
|
|
|
.removeClass(tm + '-state-hover')
|
2009-09-14 12:28:23 +02:00
|
|
|
.removeClass(tm + '-state-down');
|
|
|
|
}
|
|
|
|
)
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
2009-09-21 06:57:20 +02:00
|
|
|
if (prevButton) {
|
|
|
|
prevButton.addClass(tm + '-no-right');
|
2009-09-14 12:28:23 +02:00
|
|
|
}else{
|
2009-09-21 06:57:20 +02:00
|
|
|
button.addClass(tm + '-corner-left');
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
prevButton = button;
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2009-09-21 06:57:20 +02:00
|
|
|
if (prevButton) {
|
|
|
|
prevButton.addClass(tm + '-corner-right');
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
});
|
|
|
|
return $("<table/>").append(tr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Resizing
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
2009-10-05 07:47:26 +02:00
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
function calcSize() {
|
|
|
|
if (options.contentHeight) {
|
|
|
|
suggestedViewHeight = options.contentHeight;
|
|
|
|
}
|
|
|
|
else if (options.height) {
|
|
|
|
suggestedViewHeight = options.height - (header ? header.height() : 0) - vsides(content[0]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
suggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5));
|
2009-10-10 10:12:40 +02:00
|
|
|
}
|
2009-10-05 07:47:26 +02:00
|
|
|
}
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2010-02-20 08:11:44 +01:00
|
|
|
function setSize(dateChanged) {
|
2010-02-16 07:32:43 +01:00
|
|
|
ignoreWindowResize++;
|
2010-02-20 08:11:44 +01:00
|
|
|
view.setHeight(suggestedViewHeight, dateChanged);
|
2010-02-22 04:17:40 +01:00
|
|
|
if (absoluteViewElement) {
|
|
|
|
absoluteViewElement.css('position', 'relative');
|
|
|
|
absoluteViewElement = null;
|
|
|
|
}
|
2010-02-20 08:11:44 +01:00
|
|
|
view.setWidth(content.width(), dateChanged);
|
2010-02-16 07:32:43 +01:00
|
|
|
ignoreWindowResize--;
|
2009-10-10 10:12:40 +02:00
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2009-12-21 10:32:03 +01:00
|
|
|
function windowResize() {
|
2010-02-16 07:32:43 +01:00
|
|
|
if (!ignoreWindowResize) {
|
|
|
|
if (view.start) { // view has already been rendered
|
|
|
|
var uid = ++resizeUID;
|
|
|
|
setTimeout(function() { // add a delay
|
2010-02-21 02:44:24 +01:00
|
|
|
if (uid == resizeUID && !ignoreWindowResize && elementVisible()) {
|
2010-02-16 07:32:43 +01:00
|
|
|
if (elementOuterWidth != (elementOuterWidth = element.outerWidth())) {
|
2010-02-22 01:35:45 +01:00
|
|
|
ignoreWindowResize++; // in case the windowResize callback changes the height
|
2010-02-16 07:32:43 +01:00
|
|
|
sizeChanged();
|
2009-11-29 05:43:02 +01:00
|
|
|
view.trigger('windowResize', _element);
|
2010-02-16 07:32:43 +01:00
|
|
|
ignoreWindowResize--;
|
2009-11-29 05:43:02 +01:00
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2009-11-29 05:43:02 +01:00
|
|
|
}, 200);
|
|
|
|
}else{
|
2010-02-21 02:44:24 +01:00
|
|
|
// calendar must have been initialized in a 0x0 iframe that has just been resized
|
|
|
|
lateRender();
|
2009-11-29 05:43:02 +01:00
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2010-03-14 02:06:13 +01:00
|
|
|
}
|
2010-01-27 08:58:43 +01:00
|
|
|
$(window).resize(windowResize);
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
|
2010-07-04 02:09:14 +02:00
|
|
|
|
|
|
|
/* External event dropping
|
|
|
|
--------------------------------------------------------*/
|
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
if (options.droppable) {
|
2010-07-04 02:09:14 +02:00
|
|
|
var _dragElement;
|
2010-06-29 06:51:13 +02:00
|
|
|
$(document)
|
|
|
|
.bind('dragstart', function(ev, ui) {
|
2010-07-04 02:09:14 +02:00
|
|
|
var _e = ev.target;
|
|
|
|
var e = $(_e);
|
|
|
|
if (!e.parents('.fc').length) { // not already inside a calendar
|
|
|
|
var accept = options.dropAccept;
|
2010-07-06 01:07:40 +02:00
|
|
|
if ($.isFunction(accept) ? accept.call(_e, e) : e.is(accept)) {
|
2010-07-04 02:09:14 +02:00
|
|
|
_dragElement = _e;
|
|
|
|
view.dragStart(_dragElement, ev, ui);
|
|
|
|
}
|
2010-06-29 06:51:13 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.bind('dragstop', function(ev, ui) {
|
2010-07-04 02:09:14 +02:00
|
|
|
if (_dragElement) {
|
|
|
|
view.dragStop(_dragElement, ev, ui);
|
|
|
|
_dragElement = null;
|
2010-06-29 06:51:13 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-04 02:09:14 +02:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
// let's begin...
|
2009-10-01 07:39:02 +02:00
|
|
|
changeView(options.defaultView);
|
2009-11-23 10:50:53 +01:00
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2010-02-21 02:44:24 +01:00
|
|
|
// needed for IE in a 0x0 iframe, b/c when it is resized, never triggers a windowResize
|
|
|
|
if (!bodyVisible()) {
|
|
|
|
lateRender();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// called when we know the calendar couldn't be rendered when it was initialized,
|
|
|
|
// but we think it's ready now
|
|
|
|
function lateRender() {
|
|
|
|
setTimeout(function() { // IE7 needs this so dimensions are calculated correctly
|
2010-02-22 01:35:45 +01:00
|
|
|
if (!view.start && bodyVisible()) { // !view.start makes sure this never happens more than once
|
2010-02-21 02:44:24 +01:00
|
|
|
render();
|
|
|
|
}
|
|
|
|
},0);
|
2009-11-23 10:50:53 +01:00
|
|
|
}
|
2010-02-16 07:32:43 +01:00
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2009-09-14 12:28:23 +02:00
|
|
|
return this;
|
|
|
|
|
2009-09-08 05:01:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Important Event Utilities
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var fakeID = 0;
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
function normalizeEvent(event, options) {
|
2010-03-14 02:06:13 +01:00
|
|
|
event._id = event._id || (event.id === undefined ? '_fc' + fakeID++ : event.id + '');
|
2009-09-14 12:28:23 +02:00
|
|
|
if (event.date) {
|
|
|
|
if (!event.start) {
|
|
|
|
event.start = event.date;
|
|
|
|
}
|
|
|
|
delete event.date;
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
event._start = cloneDate(event.start = parseDate(event.start));
|
|
|
|
event.end = parseDate(event.end);
|
2009-10-10 10:12:40 +02:00
|
|
|
if (event.end && event.end <= event.start) {
|
2009-09-21 06:57:20 +02:00
|
|
|
event.end = null;
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
|
|
|
event._end = event.end ? cloneDate(event.end) : null;
|
2010-03-14 02:06:13 +01:00
|
|
|
if (event.allDay === undefined) {
|
2009-10-01 07:39:02 +02:00
|
|
|
event.allDay = options.allDayDefault;
|
2009-09-14 12:28:23 +02:00
|
|
|
}
|
2009-10-12 08:35:33 +02:00
|
|
|
if (event.className) {
|
|
|
|
if (typeof event.className == 'string') {
|
|
|
|
event.className = event.className.split(/\s+/);
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
event.className = [];
|
|
|
|
}
|
2009-09-08 05:01:28 +02:00
|
|
|
}
|
2010-05-29 07:11:26 +02:00
|
|
|
// TODO: if there is no start date, return false to indicate an invalid event
|
2009-09-08 05:01:28 +02:00
|
|
|
|