Beefed up event sources: Control over all $.ajax options. Event coloring through options. All event-level options available as "source" options. Event fetching more resilient to errors.
This commit is contained in:
parent
f3fcd57530
commit
06e4734b05
7 changed files with 449 additions and 79 deletions
|
@ -1,7 +1,15 @@
|
|||
|
||||
fc.sourceNormalizers = [];
|
||||
fc.sourceFetchers = [];
|
||||
|
||||
var ajaxDefaults = {
|
||||
dataType: 'json',
|
||||
cache: true // because we are using the cacheParam option (TODO: deprecate)
|
||||
};
|
||||
|
||||
var eventGUID = 1;
|
||||
|
||||
function EventManager(options, sources) {
|
||||
function EventManager(options, _sources) {
|
||||
var t = this;
|
||||
|
||||
|
||||
|
@ -24,6 +32,8 @@ function EventManager(options, sources) {
|
|||
|
||||
|
||||
// locals
|
||||
var stickySource = { events: [] };
|
||||
var sources = [ stickySource ];
|
||||
var rangeStart, rangeEnd;
|
||||
var currentFetchID = 0;
|
||||
var pendingSourceCnt = 0;
|
||||
|
@ -31,6 +41,11 @@ function EventManager(options, sources) {
|
|||
var cache = [];
|
||||
|
||||
|
||||
for (var i=0; i<_sources.length; i++) {
|
||||
_addEventSource(_sources[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fetching
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
@ -57,11 +72,13 @@ function EventManager(options, sources) {
|
|||
function fetchEventSource(source, fetchID) {
|
||||
_fetchEventSource(source, function(events) {
|
||||
if (fetchID == currentFetchID) {
|
||||
for (var i=0; i<events.length; i++) {
|
||||
normalizeEvent(events[i]);
|
||||
events[i].source = source;
|
||||
if (events) {
|
||||
for (var i=0; i<events.length; i++) {
|
||||
normalizeEvent(events[i], source);
|
||||
events[i].source = source;
|
||||
}
|
||||
cache = cache.concat(events);
|
||||
}
|
||||
cache = cache.concat(events);
|
||||
pendingSourceCnt--;
|
||||
if (!pendingSourceCnt) {
|
||||
reportEvents(cache);
|
||||
|
@ -72,35 +89,76 @@ function EventManager(options, sources) {
|
|||
|
||||
|
||||
function _fetchEventSource(source, callback) {
|
||||
if (typeof source == 'string') {
|
||||
var params = {};
|
||||
params[options.startParam] = Math.round(rangeStart.getTime() / 1000);
|
||||
params[options.endParam] = Math.round(rangeEnd.getTime() / 1000);
|
||||
if (options.cacheParam) {
|
||||
params[options.cacheParam] = (new Date()).getTime(); // TODO: deprecate cacheParam
|
||||
var i;
|
||||
var fetchers = fc.sourceFetchers;
|
||||
var res;
|
||||
for (i=0; i<fetchers.length; i++) {
|
||||
res = fetchers[i](source, rangeStart, rangeEnd, callback);
|
||||
if (res === true) {
|
||||
// the fetcher is in charge. made its own async request
|
||||
return;
|
||||
}
|
||||
pushLoading();
|
||||
// TODO: respect cache param in ajaxSetup
|
||||
$.ajax({
|
||||
url: source,
|
||||
dataType: 'json',
|
||||
data: params,
|
||||
cache: options.cacheParam || false, // don't let jquery prevent caching if cacheParam is being used
|
||||
success: function(events) {
|
||||
popLoading();
|
||||
else if (typeof res == 'object') {
|
||||
// the fetcher returned a new source. process it
|
||||
_fetchEventSource(res, callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
var events = source.events;
|
||||
if (events) {
|
||||
if ($.isFunction(events)) {
|
||||
pushLoading();
|
||||
events(cloneDate(rangeStart), cloneDate(rangeEnd), function(events) {
|
||||
callback(events);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if ($.isFunction(source)) {
|
||||
pushLoading();
|
||||
source(cloneDate(rangeStart), cloneDate(rangeEnd), function(events) {
|
||||
popLoading();
|
||||
popLoading();
|
||||
});
|
||||
}
|
||||
else if ($.isArray(events)) {
|
||||
callback(events);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback(source); // src is an array
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
}else{
|
||||
var url = source.url;
|
||||
if (url) {
|
||||
var success = source.success;
|
||||
var error = source.error;
|
||||
var complete = source.complete;
|
||||
var data = $.extend({}, source.data || {});
|
||||
var startParam = firstDefined(source.startParam, options.startParam);
|
||||
var endParam = firstDefined(source.endParam, options.endParam);
|
||||
var cacheParam = firstDefined(source.cacheParam, options.cacheParam);
|
||||
if (startParam) {
|
||||
data[startParam] = Math.round(+rangeStart / 1000);
|
||||
}
|
||||
if (endParam) {
|
||||
data[endParam] = Math.round(+rangeEnd / 1000);
|
||||
}
|
||||
if (cacheParam) {
|
||||
data[cacheParam] = +new Date();
|
||||
}
|
||||
pushLoading();
|
||||
$.ajax($.extend({}, ajaxDefaults, source, {
|
||||
data: data,
|
||||
success: function(events) {
|
||||
events = events || [];
|
||||
var res = applyAll(success, this, arguments);
|
||||
if ($.isArray(res)) {
|
||||
events = res;
|
||||
}
|
||||
callback(events);
|
||||
},
|
||||
error: function() {
|
||||
applyAll(error, this, arguments);
|
||||
callback();
|
||||
},
|
||||
complete: function() {
|
||||
applyAll(complete, this, arguments);
|
||||
popLoading();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,25 +167,38 @@ function EventManager(options, sources) {
|
|||
/* Sources
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
// first event source is reserved for "sticky" events
|
||||
sources.unshift([]);
|
||||
|
||||
|
||||
function addEventSource(source) {
|
||||
sources.push(source);
|
||||
pendingSourceCnt++;
|
||||
fetchEventSource(source, currentFetchID); // will eventually call reportEvents
|
||||
source = _addEventSource(source);
|
||||
if (source) {
|
||||
pendingSourceCnt++;
|
||||
fetchEventSource(source, currentFetchID); // will eventually call reportEvents
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _addEventSource(source) {
|
||||
if ($.isFunction(source) || $.isArray(source)) {
|
||||
source = { events: source };
|
||||
}
|
||||
else if (typeof source == 'string') {
|
||||
source = { url: source };
|
||||
}
|
||||
if (typeof source == 'object') {
|
||||
normalizeSource(source);
|
||||
sources.push(source);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeEventSource(source) {
|
||||
sources = $.grep(sources, function(src) {
|
||||
return src != source;
|
||||
return !isSourcesEqual(src, source);
|
||||
});
|
||||
// remove all client events from that source
|
||||
cache = $.grep(cache, function(e) {
|
||||
return e.source != source;
|
||||
return !isSourcesEqual(e.source, source);
|
||||
});
|
||||
reportEvents(cache);
|
||||
}
|
||||
|
@ -163,20 +234,20 @@ function EventManager(options, sources) {
|
|||
e.allDay = event.allDay;
|
||||
e.className = event.className;
|
||||
e.editable = event.editable;
|
||||
normalizeEvent(e);
|
||||
normalizeEvent(e, e.source);
|
||||
}
|
||||
}
|
||||
normalizeEvent(event);
|
||||
normalizeEvent(event, event.source);
|
||||
reportEvents(cache);
|
||||
}
|
||||
|
||||
|
||||
function renderEvent(event, stick) {
|
||||
normalizeEvent(event);
|
||||
normalizeEvent(event, event.source || stickySource);
|
||||
if (!event.source) {
|
||||
if (stick) {
|
||||
sources[0].push(event);
|
||||
event.source = sources[0];
|
||||
stickySource.events.push(event);
|
||||
event.source = stickySource;
|
||||
}
|
||||
cache.push(event);
|
||||
}
|
||||
|
@ -189,8 +260,8 @@ function EventManager(options, sources) {
|
|||
cache = [];
|
||||
// clear all array sources
|
||||
for (var i=0; i<sources.length; i++) {
|
||||
if (typeof sources[i] == 'object') {
|
||||
sources[i] = [];
|
||||
if ($.isArray(sources[i].events)) {
|
||||
sources[i].events = [];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
@ -203,9 +274,8 @@ function EventManager(options, sources) {
|
|||
cache = $.grep(cache, filter, true);
|
||||
// remove events from array sources
|
||||
for (var i=0; i<sources.length; i++) {
|
||||
if (typeof sources[i] == 'object') {
|
||||
sources[i] = $.grep(sources[i], filter, true);
|
||||
// TODO: event objects' sources will no longer be correct reference :(
|
||||
if ($.isArray(sources[i].events)) {
|
||||
sources[i].events = $.grep(sources[i].events, filter, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +321,7 @@ function EventManager(options, sources) {
|
|||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function normalizeEvent(event) {
|
||||
function normalizeEvent(event, source) {
|
||||
event._id = event._id || (event.id === undefined ? '_fc' + eventGUID++ : event.id + '');
|
||||
if (event.date) {
|
||||
if (!event.start) {
|
||||
|
@ -259,14 +329,14 @@ function EventManager(options, sources) {
|
|||
}
|
||||
delete event.date;
|
||||
}
|
||||
event._start = cloneDate(event.start = parseDate(event.start, options.ignoreTimezone));
|
||||
event._start = cloneDate(event.start = parseDate(event.start, firstDefined(source.ignoreTimezone, options.ignoreTimezone)));
|
||||
event.end = parseDate(event.end, options.ignoreTimezone);
|
||||
if (event.end && event.end <= event.start) {
|
||||
event.end = null;
|
||||
}
|
||||
event._end = event.end ? cloneDate(event.end) : null;
|
||||
if (event.allDay === undefined) {
|
||||
event.allDay = options.allDayDefault;
|
||||
event.allDay = firstDefined(source.allDayDefault, options.allDayDefault);
|
||||
}
|
||||
if (event.className) {
|
||||
if (typeof event.className == 'string') {
|
||||
|
@ -277,6 +347,37 @@ function EventManager(options, sources) {
|
|||
}
|
||||
// TODO: if there is no start date, return false to indicate an invalid event
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Utils
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function normalizeSource(source) {
|
||||
if (source.className) {
|
||||
// TODO: repeate code, same code for event classNames
|
||||
if (typeof source.className == 'string') {
|
||||
source.className = source.className.split(/\s+/);
|
||||
}
|
||||
}else{
|
||||
source.className = [];
|
||||
}
|
||||
var normalizers = fc.sourceNormalizers;
|
||||
for (var i=0; i<normalizers.length; i++) {
|
||||
normalizers[i](source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function isSourcesEqual(source1, source2) {
|
||||
return getSourcePrimitive(source1) == getSourcePrimitive(source2);
|
||||
}
|
||||
|
||||
|
||||
function getSourcePrimitive(source) {
|
||||
return ((typeof source == 'object') ? (source.events || source.url) : '') || source;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ function AgendaEventRenderer() {
|
|||
|
||||
var i, segCnt=segs.length, seg,
|
||||
event,
|
||||
className,
|
||||
classes,
|
||||
top, bottom,
|
||||
colI, levelI, forward,
|
||||
leftmost,
|
||||
|
@ -171,12 +171,12 @@ function AgendaEventRenderer() {
|
|||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-vert ';
|
||||
classes = ['fc-event', 'fc-event-vert'];
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-top ';
|
||||
classes.push('fc-corner-top');
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-bottom ';
|
||||
classes.push('fc-corner-bottom');
|
||||
}
|
||||
top = timePosition(seg.start, seg.start);
|
||||
bottom = timePosition(seg.start, seg.end);
|
||||
|
@ -205,7 +205,7 @@ function AgendaEventRenderer() {
|
|||
seg.left = left;
|
||||
seg.outerWidth = outerWidth;
|
||||
seg.outerHeight = bottom - top;
|
||||
html += slotSegHtml(event, seg, className);
|
||||
html += slotSegHtml(event, seg, classes);
|
||||
}
|
||||
slotSegmentContainer[0].innerHTML = html; // faster than html()
|
||||
eventElements = slotSegmentContainer.children();
|
||||
|
@ -278,10 +278,16 @@ function AgendaEventRenderer() {
|
|||
}
|
||||
|
||||
|
||||
function slotSegHtml(event, seg, className) {
|
||||
return "<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;top:" + seg.top + "px;left:" + seg.left + "px'>" +
|
||||
"<a class='fc-event-inner'" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" + // good for escaping quotes?
|
||||
"<div class='fc-event-head'>" +
|
||||
function slotSegHtml(event, seg, classes) {
|
||||
classes = classes.concat(event.className, event.source.className);
|
||||
var skinCss = getSkinCss(event, opt);
|
||||
var skinCssAttr = (skinCss ? " style='" + skinCss + "'" : '');
|
||||
return "<div class='" + classes.join(' ') + "' style='position:absolute;z-index:8;top:" + seg.top + "px;left:" + seg.left + "px;" + skinCss + "'>" +
|
||||
"<a class='fc-event-inner'" +
|
||||
(event.url ? " href='" + htmlEscape(event.url) + "'" : '') + // good for escaping quotes?
|
||||
skinCssAttr +
|
||||
">" +
|
||||
"<div class='fc-event-head'" + skinCssAttr + ">" +
|
||||
"<div class='fc-event-time'>" +
|
||||
htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) +
|
||||
"</div>" +
|
||||
|
@ -293,16 +299,22 @@ function AgendaEventRenderer() {
|
|||
"</div>" +
|
||||
"<div class='fc-event-bg'></div>" +
|
||||
"</a>" +
|
||||
((event.editable || event.editable === undefined && opt('editable')) && !opt('disableResizing') && $.fn.resizable ?
|
||||
((seg.isEnd &&
|
||||
isEventEditable(event) &&
|
||||
!opt('disableResizing') && // TODO: make like other source properties
|
||||
$.fn.resizable)
|
||||
?
|
||||
"<div class='ui-resizable-handle ui-resizable-s'>=</div>"
|
||||
: '') +
|
||||
:
|
||||
''
|
||||
) +
|
||||
"</div>";
|
||||
}
|
||||
|
||||
|
||||
function bindDaySeg(event, eventElement, seg) {
|
||||
eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable === undefined && opt('editable')) {
|
||||
if (isEventEditable(event)) {
|
||||
draggableDayEvent(event, eventElement, seg.isStart);
|
||||
if (seg.isEnd) {
|
||||
resizableDayEvent(event, eventElement, seg);
|
||||
|
@ -313,7 +325,7 @@ function AgendaEventRenderer() {
|
|||
|
||||
function bindSlotSeg(event, eventElement, seg) {
|
||||
eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable === undefined && opt('editable')) {
|
||||
if (isEventEditable(event)) {
|
||||
var timeElement = eventElement.find('span.fc-event-time');
|
||||
draggableSlotEvent(event, eventElement, timeElement);
|
||||
if (seg.isEnd) {
|
||||
|
@ -323,6 +335,11 @@ function AgendaEventRenderer() {
|
|||
}
|
||||
|
||||
|
||||
function isEventEditable(event) {
|
||||
return firstDefined(event.editable, event.source.editable, opt('editable'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Dragging
|
||||
-----------------------------------------------------------------------------------*/
|
||||
|
@ -330,6 +347,10 @@ function AgendaEventRenderer() {
|
|||
|
||||
// when event starts out FULL-DAY
|
||||
|
||||
// TODO: bug when dragging an event that occupies first day, but is not the event's start (no rounded left side)
|
||||
|
||||
// TODO: bug when dragging from day to slot, outer container doesn't seem to change height
|
||||
|
||||
function draggableDayEvent(event, eventElement, isStart) {
|
||||
if (!opt('disableDragging') && eventElement.draggable) {
|
||||
var origWidth;
|
||||
|
|
|
@ -701,10 +701,11 @@ function AgendaView(element, calendar, viewName) {
|
|||
start: startDate,
|
||||
end: endDate,
|
||||
className: [],
|
||||
editable: false
|
||||
editable: false,
|
||||
source: {}
|
||||
},
|
||||
rect,
|
||||
'fc-event fc-event-vert fc-corner-top fc-corner-bottom '
|
||||
['fc-event', 'fc-event-vert', 'fc-corner-top', 'fc-corner-bottom']
|
||||
));
|
||||
if ($.browser.msie) {
|
||||
selectionHelper.find('span.fc-event-bg').hide(); // nested opacities mess up in IE, just hide
|
||||
|
|
|
@ -77,7 +77,7 @@ function BasicEventRenderer() {
|
|||
|
||||
function bindDaySeg(event, eventElement, seg) {
|
||||
eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable === undefined && opt('editable')) {
|
||||
if (firstDefined(event.editable, event.source.editable, opt('editable'))) {
|
||||
draggableDayEvent(event, eventElement);
|
||||
if (seg.isEnd) {
|
||||
resizableDayEvent(event, eventElement, seg);
|
||||
|
|
|
@ -119,25 +119,26 @@ function DayEventRenderer() {
|
|||
var segCnt=segs.length;
|
||||
var seg;
|
||||
var event;
|
||||
var className;
|
||||
var classes;
|
||||
var bounds = allDayBounds();
|
||||
var minLeft = bounds.left;
|
||||
var maxLeft = bounds.right;
|
||||
var cols = []; // don't really like this system (but have to do this b/c RTL works differently in basic vs agenda)
|
||||
var left;
|
||||
var right;
|
||||
var skinCss;
|
||||
var html = '';
|
||||
// calculate desired position/dimensions, create html
|
||||
for (i=0; i<segCnt; i++) {
|
||||
seg = segs[i];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
classes = ['fc-event', 'fc-event-hori'];
|
||||
if (rtl) {
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
classes.push('fc-corner-right');
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-left ';
|
||||
classes.push('fc-corner-left');
|
||||
}
|
||||
cols[0] = dayOfWeekCol(seg.end.getDay()-1);
|
||||
cols[1] = dayOfWeekCol(seg.start.getDay());
|
||||
|
@ -145,19 +146,26 @@ function DayEventRenderer() {
|
|||
right = seg.isStart ? colContentRight(cols[1]) : maxLeft;
|
||||
}else{
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
classes.push('fc-corner-left');
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-right ';
|
||||
classes.push('fc-corner-right');
|
||||
}
|
||||
cols[0] = dayOfWeekCol(seg.start.getDay());
|
||||
cols[1] = dayOfWeekCol(seg.end.getDay()-1);
|
||||
left = seg.isStart ? colContentLeft(cols[0]) : minLeft;
|
||||
right = seg.isEnd ? colContentRight(cols[1]) : maxLeft;
|
||||
}
|
||||
classes = classes.concat(event.className, event.source.className);
|
||||
skinCss = getSkinCss(event, opt);
|
||||
html +=
|
||||
"<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;left:"+left+"px'>" +
|
||||
"<a class='fc-event-inner'" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" +
|
||||
"<div class='" + classes.join(' ') + "' " +
|
||||
"style='position:absolute;z-index:8;left:"+left+"px;" + skinCss + "'" +
|
||||
">" +
|
||||
"<a class='fc-event-inner'" +
|
||||
(event.url ? " href='" + htmlEscape(event.url) + "'" : '') +
|
||||
(skinCss ? " style='" + skinCss + "'" : '') +
|
||||
">" +
|
||||
(!event.allDay && seg.isStart ?
|
||||
"<span class='fc-event-time'>" +
|
||||
htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) +
|
||||
|
@ -165,9 +173,14 @@ function DayEventRenderer() {
|
|||
:'') +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</a>" +
|
||||
(seg.isEnd && (event.editable || event.editable === undefined && opt('editable')) && !opt('disableResizing') ?
|
||||
((seg.isEnd &&
|
||||
firstDefined(event.editable, event.source.editable, opt('editable')) &&
|
||||
!opt('disableResizing')) // TODO: make this like the other source options
|
||||
?
|
||||
"<div class='ui-resizable-handle ui-resizable-" + (rtl ? 'w' : 'e') + "'></div>"
|
||||
: '') +
|
||||
:
|
||||
''
|
||||
) +
|
||||
"</div>";
|
||||
seg.left = left;
|
||||
seg.outerWidth = right - left;
|
||||
|
|
63
src/util.js
63
src/util.js
|
@ -1,4 +1,6 @@
|
|||
|
||||
fc.applyAll = applyAll;
|
||||
|
||||
|
||||
/* Event Date Math
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
@ -305,3 +307,64 @@ function setDayID(cell, date) {
|
|||
}
|
||||
|
||||
|
||||
function getSkinCss(event, opt) {
|
||||
var source = event.source;
|
||||
var eventColor = event.color;
|
||||
var sourceColor = source.color;
|
||||
var optionColor = opt('eventColor');
|
||||
var backgroundColor =
|
||||
event.backgroundColor ||
|
||||
eventColor ||
|
||||
source.backgroundColor ||
|
||||
sourceColor ||
|
||||
opt('eventBackgroundColor') ||
|
||||
optionColor;
|
||||
var borderColor =
|
||||
event.borderColor ||
|
||||
eventColor ||
|
||||
source.borderColor ||
|
||||
sourceColor ||
|
||||
opt('eventBorderColor') ||
|
||||
optionColor;
|
||||
var textColor =
|
||||
event.textColor ||
|
||||
source.textColor ||
|
||||
opt('textColor');
|
||||
var statements = [];
|
||||
if (backgroundColor) {
|
||||
statements.push('background-color:' + backgroundColor);
|
||||
}
|
||||
if (borderColor) {
|
||||
statements.push('border-color:' + borderColor);
|
||||
}
|
||||
if (textColor) {
|
||||
statements.push('color:' + textColor);
|
||||
}
|
||||
return statements.join(';');
|
||||
}
|
||||
|
||||
|
||||
function applyAll(functions, thisObj, args) {
|
||||
if ($.isFunction(functions)) {
|
||||
functions = [ functions ];
|
||||
}
|
||||
if (functions) {
|
||||
var i;
|
||||
var ret;
|
||||
for (i=0; i<functions.length; i++) {
|
||||
ret = functions[i].apply(thisObj, args) || ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function firstDefined() {
|
||||
for (var i=0; i<arguments.length; i++) {
|
||||
if (arguments[i] !== undefined) {
|
||||
return arguments[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
171
tests/sources_new.html
Normal file
171
tests/sources_new.html
Normal file
|
@ -0,0 +1,171 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<script type='text/javascript' src='../src/_loader.js?debug'></script>
|
||||
<script type='text/javascript' src='../src/gcal/_loader.js'></script>
|
||||
<script type='text/javascript'>
|
||||
|
||||
/*
|
||||
|
||||
(main options)
|
||||
startParam
|
||||
endParam
|
||||
cacheParam
|
||||
ignoreTimezone
|
||||
allDayDefault
|
||||
editable
|
||||
eventColor
|
||||
eventTextColor
|
||||
eventBorderColor
|
||||
eventBackgroundColor
|
||||
|
||||
(event source)
|
||||
startParam
|
||||
endParam
|
||||
cacheParam
|
||||
ignoreTimezone
|
||||
allDayDefault
|
||||
className
|
||||
editable
|
||||
color
|
||||
textColor
|
||||
borderColor
|
||||
backgroundColor
|
||||
|
||||
(event)
|
||||
className
|
||||
editable
|
||||
color
|
||||
textColor
|
||||
borderColor
|
||||
backgroundColor
|
||||
|
||||
*/
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var date = new Date();
|
||||
var d = date.getDate();
|
||||
var m = date.getMonth();
|
||||
var y = date.getFullYear();
|
||||
|
||||
$('#calendar').fullCalendar({
|
||||
header: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
|
||||
},
|
||||
editable: true,
|
||||
selectable: true,
|
||||
selectHelper: true,
|
||||
eventSources: [
|
||||
|
||||
{
|
||||
url: 'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
|
||||
color: 'orange',
|
||||
className: 'gcal',
|
||||
success: function(events) {
|
||||
console.log('successfully loaded gcal event data!', events);
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
$.fullCalendar.gcalFeed('http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic', {
|
||||
color: 'orange',
|
||||
className: 'gcal'
|
||||
}),
|
||||
*/
|
||||
|
||||
{
|
||||
url: "../demos/json-events.php",
|
||||
//editable: false,
|
||||
color: 'red',
|
||||
data: {
|
||||
something: 'cool'
|
||||
},
|
||||
success: function() {
|
||||
console.log('json-events.php is done!!!', arguments);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
color: 'purple',
|
||||
events: [
|
||||
{
|
||||
title: 'All Day Event',
|
||||
start: new Date(y, m, 1)
|
||||
},
|
||||
{
|
||||
title: 'Long Event',
|
||||
start: new Date(y, m, d-5),
|
||||
end: new Date(y, m, d-2)
|
||||
},
|
||||
{
|
||||
id: 999,
|
||||
title: 'Repeating Event',
|
||||
start: new Date(y, m, d-3, 16, 0),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
id: 999,
|
||||
title: 'Repeating Event',
|
||||
start: new Date(y, m, d+4, 16, 0),
|
||||
allDay: false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
events: [
|
||||
{
|
||||
title: 'Meeting',
|
||||
start: new Date(y, m, d, 10, 30),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
title: 'Lunch',
|
||||
start: new Date(y, m, d, 12, 5),
|
||||
end: new Date(y, m, d, 14, 43),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
title: 'Birthday Party',
|
||||
start: new Date(y, m, d+1, 19, 0),
|
||||
end: new Date(y, m, d+1, 22, 30),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
title: 'Click for Google',
|
||||
start: new Date(y, m, 28),
|
||||
end: new Date(y, m, 29),
|
||||
url: 'http://google.com/'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<style type='text/css'>
|
||||
|
||||
body {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
|
||||
}
|
||||
|
||||
#calendar {
|
||||
width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='calendar'></div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue