modified docs, added all new tests

This commit is contained in:
Adam Shaw 2009-09-14 10:28:23 +00:00
parent 2841a62e74
commit f45246c60c
20 changed files with 1173 additions and 944 deletions

View file

@ -77,6 +77,11 @@ CalEvent:
**title**: String **title**: String
The text on an event's element The text on an event's element
**allDay**: Boolean (optional, defaults to ``true``)
Determines whether the start-date and end-date's times should be ignored.
If ``true``, times will be ignored. If ``false``, times will be considered,
displaying them on each event (like the text '3pm').
**date**: Date **date**: Date
Alias for ``start`` Alias for ``start``
@ -91,18 +96,17 @@ CalEvent:
**end**: Date (optional) **end**: Date (optional)
A javascript Date object indicating the date/time an event ends. A javascript Date object indicating the date/time an event ends.
If the event is an all-day event, specifies the inclusive last day As with ``start``, IETF and ISO8601 strings can be used.
of the event. (This is different from previous versions of FullCalendar).
For example, an all-day event with start on *Nov 10* and end on *Nov 12* **If an event is all-day...**
would span *3 days*.
As with ``start``, IETF and ISO8601 strings can be used with an the end date is *inclusive*. This means an event with ``start`` *Nov 10* and
:ref:`Event Source <event-sources>`. ``end`` *Nov 12* will span *3 days* on the calendar.
**allDay**: Boolean (optional, defaults to ``true``) **If an event is NOT all-day...**
Determines whether an event's time is displayed (such as 3pm).
``false`` will show the time, ``true`` will not. the end date is *exclusive*. This is only a gotcha when your ``end`` has time 00:00.
It means your event ends on midnight, and it will *not* span through the next day.
**className**: String/Array (optional) **className**: String/Array (optional)
A CSS class (or array of classes) that will be attached to this event's A CSS class (or array of classes) that will be attached to this event's

View file

@ -35,8 +35,8 @@ jQuery object:
Renders a new event on the calendar. ``calEvent`` must have Renders a new event on the calendar. ``calEvent`` must have
at least a ``title`` and a ``start``. at least a ``title`` and a ``start``.
By default, the event will disappear once the user switches views By default, the event will disappear once the calendar refetches its event
or clicks prev/next. However, specifying ``stick`` as ``true`` sources (example: when prev/next is clicked). However, specifying ``stick`` as ``true``
will cause the event to be permanently fixed to the calendar. will cause the event to be permanently fixed to the calendar.
**removeEvents** - .fullCalendar('removeEvents', *[idOrFilter]*) **removeEvents** - .fullCalendar('removeEvents', *[idOrFilter]*)

View file

@ -78,7 +78,7 @@ always available (:ref:`more below <view-object>`).
``this`` is set to the event's element ``this`` is set to the event's element
**eventResized**: function(*event, dayDelta, minuteDelta, jsEvent, ui, view*) **eventResize**: function(*calEvent, dayDelta, minuteDelta, jsEvent, ui, view*)
Triggered when an event is resized and *changed in duration*. Triggered when an event is resized and *changed in duration*.
``dayDelta`` holds the number of days the event's end time was moved ``dayDelta`` holds the number of days the event's end time was moved

View file

@ -1,4 +1,20 @@
function segAfters(levels) { // TODO: put in agenda.js
var i, j, k, level, seg, seg2;
for (i=levels.length-1; i>0; i--) {
level = levels[i];
for (j=0; j<level.length; j++) {
seg = level[j];
for (k=0; k<segLevels[i-1].length; k++) {
seg2 = segLevels[i-1][k];
if (segsCollide(seg, seg2)) {
seg2.after = Math.max(seg2.after, seg.after+1);
}
}
}
}
}
/********************************* week view ***********************************/ /********************************* week view ***********************************/
$.fullCalendar.views.week = function(element, options) { $.fullCalendar.views.week = function(element, options) {

View file

@ -6,12 +6,12 @@
width: 100%; width: 100%;
} }
.fc-grid th { .fc .fc-grid th {
border-width: 0 0 0 1px; border-width: 0 0 0 1px;
text-align: center; text-align: center;
} }
.fc-grid td { .fc .fc-grid td {
border-width: 1px 0 0 1px; border-width: 1px 0 0 1px;
} }

View file

@ -212,14 +212,6 @@ table.fc-header {
background-color: blue; background-color: blue;
} }
.fc-event-nobg,
.fc-event-nobg a,
.fc-agenda .fc-event-nobg .fc-event-time {
border-style: none;
background: none;
color: inherit;
}
.fc-event a { .fc-event a {
overflow: hidden; overflow: hidden;
font-size: 11px; font-size: 11px;
@ -239,6 +231,14 @@ table.fc-header {
height: 100%; height: 100%;
} }
/* resizable */
.fc .ui-resizable-handle {
display: block;
position: absolute;
z-index: 99999;
}
/* Horizontal Events /* Horizontal Events
@ -271,8 +271,26 @@ table.fc-header {
border-right-width: 1px; border-right-width: 1px;
} }
/* resizable */
.fc-event-hori .ui-resizable-e {
top: 0;
right: -5px;
width: 7px;
height: 100%;
cursor: e-resize;
}
.fc-event-hori .ui-resizable-w {
top: 0;
left: -5px;
width: 7px;
height: 100%;
cursor: w-resize;
}
.fc-event-hori .ui-resizable-handle { .fc-event-hori .ui-resizable-handle {
_height: 10px; /* IE6 had 0 height */ _height: 14px; /* IE6 had 0 height */
} }

View file

@ -26,12 +26,12 @@
var startStr = entry['gd$when'][0]['startTime']; var startStr = entry['gd$when'][0]['startTime'];
var start = $.fullCalendar.parseDate(startStr); var start = $.fullCalendar.parseDate(startStr);
var end = $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']); var end = $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']);
var hasTime = startStr.indexOf('T') != -1; var allDay = startStr.indexOf('T') == -1;
var classNames = []; var classNames = [];
if (hasTime) { if (allDay) {
classNames.push('fc-event-nobg'); end = new Date(end - 1); // make in inclusive
}else{ }else{
end = new Date(end - 1); classNames.push('fc-event-nobg');
} }
if (options.className) { if (options.className) {
if (typeof options.className == 'string') { if (typeof options.className == 'string') {
@ -48,7 +48,7 @@
end: end, end: end,
location: entry['gd$where'][0]['valueString'], location: entry['gd$where'][0]['valueString'],
description: entry['content']['$t'], description: entry['content']['$t'],
hasTime: hasTime, allDay: allDay,
className: classNames, className: classNames,
editable: options.editable || false editable: options.editable || false
}); });

View file

@ -81,15 +81,16 @@ function Grid(element, options, methods) {
// initialize superclass // initialize superclass
view = $.extend(this, viewMethods, methods, { view = $.extend(this, viewMethods, methods, {
renderGrid: renderGrid, renderGrid: renderGrid,
renderEvents: renderEvents,
rerenderEvents: rerenderEvents, rerenderEvents: rerenderEvents,
updateSize: updateSize, updateSize: updateSize,
eventEnd: function(event) { defaultEventEnd: function(event) {
return event.end || cloneDate(event.start); return cloneDate(event.start);
}, },
visEventEnd: function(event) { visEventEnd: function(event) {
if (event.end) { if (event.end) {
var end = cloneDate(event.end); var end = cloneDate(event.end);
return (!event.hasTime || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end; return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
}else{ }else{
return addDays(cloneDate(event.start), 1); return addDays(cloneDate(event.start), 1);
} }
@ -108,13 +109,12 @@ function Grid(element, options, methods) {
} }
function renderGrid(r, c, colFormat, showNumbers, fetchEvents) { function renderGrid(r, c, colFormat, showNumbers, fetchEvents) {
//console.log('renderGrid!');
rowCnt = r; rowCnt = r;
colCnt = c; colCnt = c;
var month = view.start.getMonth(), var month = view.start.getMonth(),
today = clearTime(new Date()), today = clearTime(new Date()),
s, s2, s3, i, j, d = cloneDate(view.visStart); s, i, j, d = cloneDate(view.visStart);
// update option-derived variables // update option-derived variables
tm = options.theme ? 'ui' : 'fc'; tm = options.theme ? 'ui' : 'fc';
@ -131,28 +131,23 @@ function Grid(element, options, methods) {
var table = $("<table/>").appendTo(element); var table = $("<table/>").appendTo(element);
s = ''; s = "<thead><tr>";
for (i=0; i<colCnt; i++) { for (i=0; i<colCnt; i++) {
s2 = "<th class='fc-" + s += "<th class='fc-" +
dayIDs[d.getDay()] + ' ' + // needs to be first dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default ' + tm + '-state-default' +
(i==dit ? ' fc-left' : '') + (i==dit ? ' fc-left' : '') +
"'>" + formatDate(d, colFormat, options) + "</th>"; // TODO: optionize "'>" + formatDate(d, colFormat, options) + "</th>";
//if (rtl) {
// s = s2 + s;
//}else{
s += s2;
//}
addDays(d, 1); addDays(d, 1);
} }
thead = $("<thead><tr>" + s + "</tr></thead>").appendTo(table); thead = $(s + "</tr></thead>").appendTo(table);
s = "<tbody>"; s = "<tbody>";
d = cloneDate(view.visStart); d = cloneDate(view.visStart);
for (i=0; i<rowCnt; i++) { for (i=0; i<rowCnt; i++) {
s2 = ''; s += "<tr class='fc-week" + i + "'>";
for (j=0; j<colCnt; j++) { for (j=0; j<colCnt; j++) {
s3 = "<td class='fc-" + s += "<td class='fc-" +
dayIDs[d.getDay()] + ' ' + // needs to be first dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default fc-day' + (i*colCnt+j) + tm + '-state-default fc-day' + (i*colCnt+j) +
(j==dit ? ' fc-left' : '') + (j==dit ? ' fc-left' : '') +
@ -162,14 +157,9 @@ function Grid(element, options, methods) {
' fc-not-today') + "'>" + ' fc-not-today') + "'>" +
(showNumbers ? "<div class='fc-day-number'>" + d.getDate() + "</div>" : '') + (showNumbers ? "<div class='fc-day-number'>" + d.getDate() + "</div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div></td>"; "<div class='fc-day-content'><div>&nbsp;</div></div></td>";
//if (rtl) {
// s2 = s3 + s2;
//}else{
s2 += s3;
//}
addDays(d, 1); addDays(d, 1);
} }
s += "<tr class='fc-week" + i + "'>" + s2 + "</tr>"; s += "</tr>";
} }
tbody = $(s + "</tbody>").appendTo(table); tbody = $(s + "</tbody>").appendTo(table);
tbody.find('td').click(dayClick); tbody.find('td').click(dayClick);
@ -182,60 +172,67 @@ function Grid(element, options, methods) {
if (rowCnt < prevRowCnt) { if (rowCnt < prevRowCnt) {
tbody.find('tr:gt(' + (rowCnt-1) + ')').remove(); // remove extra rows tbody.find('tr:gt(' + (rowCnt-1) + ')').remove(); // remove extra rows
} }
else if (rowCnt > prevRowCnt) { else if (rowCnt > prevRowCnt) { // needs to create new rows...
s = ''; s = '';
for (i=prevRowCnt; i<rowCnt; i++) { for (i=prevRowCnt; i<rowCnt; i++) {
s2 = ''; s += "<tr class='fc-week" + i + "'>";
for (j=0; j<colCnt; j++) { for (j=0; j<colCnt; j++) {
s3 = "<td class='fc-" + s += "<td class='fc-" +
dayIDs[(j * dis + dit + weekStart) % 7] + ' ' + // needs to be first dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default fc-new fc-day' + (i*colCnt + j) + tm + '-state-default fc-new fc-day' + (i*colCnt+j) +
(j==dit ? ' fc-left' : '') + "'>" + (j==dit ? ' fc-left' : '') + "'>" +
(showNumbers ? "<div class='fc-day-number'></div>" : '') + (showNumbers ? "<div class='fc-day-number'></div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div>" + "<div class='fc-day-content'><div>&nbsp;</div></div>" +
"</td>"; "</td>";
//if (rtl) { addDays(d, 1);
// s2 = s3 + s2;
//}else{
s2 += s3;
//}
} }
s += "<tr class='fc-week" + i + "'>" + s2 + "</tr>"; s += "</tr>";
} }
tbody.append(s); tbody.append(s);
} }
tbody.find('td.fc-new').removeClass('fc-new').click(dayClick); tbody.find('td.fc-new').removeClass('fc-new').click(dayClick);
// re-label and re-class existing cells // re-label and re-class existing cells
tbody.find('tr').each(function() { d = cloneDate(view.visStart);
for (i=0; i<colCnt; i++) { tbody.find('td').each(function() {
var td = $(this.childNodes[i]); // * dis + dit TODO: clean var td = $(this);
if (rowCnt > 1) { if (rowCnt > 1) {
if (d.getMonth() == month) { if (d.getMonth() == month) {
td.removeClass('fc-other-month'); td.removeClass('fc-other-month');
}else{
td.addClass('fc-other-month');
}
}
if (+d == +today) {
td.removeClass('fc-not-today')
.addClass('fc-today')
.addClass(tm + '-state-highlight');
}else{ }else{
td.addClass('fc-not-today') td.addClass('fc-other-month');
.removeClass('fc-today')
.removeClass(tm + '-state-highlight');
} }
td.find('div.fc-day-number').text(d.getDate());
addDays(d, 1);
} }
if (+d == +today) {
td.removeClass('fc-not-today')
.addClass('fc-today')
.addClass(tm + '-state-highlight');
}else{
td.addClass('fc-not-today')
.removeClass('fc-today')
.removeClass(tm + '-state-highlight');
}
td.find('div.fc-day-number').text(d.getDate());
addDays(d, 1);
}); });
if (colCnt == 1) { if (rowCnt == 1) { // more likely changed (week or day view)
var startDay = this.visStart.getDay();
var td = tbody.find('td')[0]; // redo column header text and class
td.className = td.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[startDay]); d = cloneDate(view.visStart);
thead.find('th').text(formatDate(this.start, colFormat, options)); thead.find('th').each(function() {
$(this).text(formatDate(d, colFormat, options));
this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
addDays(d, 1);
});
// redo cell day-of-weeks
d = cloneDate(view.visStart);
tbody.find('td').each(function() {
this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
addDays(d, 1);
});
} }
} }
@ -297,7 +294,7 @@ function Grid(element, options, methods) {
function renderEvents(events) { function renderEvents(events) {
view.reportEvents(events); view.reportEvents(events);
renderSegs(cachedSegs = compileSegs(events)); // view.visibleEvents( renderSegs(cachedSegs = compileSegs(events));
} }
@ -388,10 +385,9 @@ function Grid(element, options, methods) {
} }
eventElement = $("<div class='" + eventClasses.join(' ') + "'/>") eventElement = $("<div class='" + eventClasses.join(' ') + "'/>")
.append(eventAnchor = $("<a/>") .append(eventAnchor = $("<a/>")
.append(event.hasTime ? .append(event.allDay ? null :
$("<span class='fc-event-time'/>") $("<span class='fc-event-time'/>")
.html(formatDate(event.start, options.eventTimeFormat, options)) : .html(formatDates(event.start, event.end, options.timeFormat, options)))
null)
.append($("<span class='fc-event-title'/>") .append($("<span class='fc-event-title'/>")
.text(event.title))); .text(event.title)));
if (event.url) { if (event.url) {

View file

@ -12,9 +12,9 @@ var defaults = {
defaultView: 'month', defaultView: 'month',
aspectRatio: 1.35, aspectRatio: 1.35,
header: { header: {
left: 'prev,next today', left: 'title',
center: 'title', center: '',
right: 'month,basicWeek,basicDay' right: 'today prev,next'
}, },
// event ajax // event ajax
@ -23,7 +23,7 @@ var defaults = {
cacheParam: '_', cacheParam: '_',
// time formats // time formats
eventTimeFormat: 'h(:mm)t', timeFormat: 'h(:mm)t', // for events
titleFormat: { titleFormat: {
month: 'MMMM yyyy', month: 'MMMM yyyy',
week: "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}", week: "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}",
@ -62,9 +62,9 @@ var defaults = {
// right-to-left defaults // right-to-left defaults
var rtlDefaults = { var rtlDefaults = {
header: { header: {
left: 'basicDay,basicWeek,month', left: 'next,prev today',
center: 'title', center: '',
right: 'today next,prev' right: 'title'
}, },
buttonText: { buttonText: {
prev: '&#9658;', prev: '&#9658;',
@ -254,7 +254,7 @@ $.fn.fullCalendar = function(options) {
// Fetch from a particular source. Append to the 'events' array // Fetch from a particular source. Append to the 'events' array
function fetchEventSource(src, callback) { function fetchEventSource(src, callback) {
var prevDate = cloneDate(date), var prevDate = cloneDate(date),
reportEvents = function(a, dontPopLoading) { reportEvents = function(a) {
if (+date == +prevDate) { if (+date == +prevDate) {
for (var i=0; i<a.length; i++) { for (var i=0; i<a.length; i++) {
normalizeEvent(a[i]); normalizeEvent(a[i]);
@ -262,12 +262,13 @@ $.fn.fullCalendar = function(options) {
} }
events = events.concat(a); events = events.concat(a);
} }
if (!dontPopLoading) {
popLoading();
}
if (callback) { if (callback) {
callback(a); callback(a);
} }
},
reportPopEvents = function(a) {
reportEvents(a);
popLoading();
}; };
if (typeof src == 'string') { if (typeof src == 'string') {
var params = {}; var params = {};
@ -275,14 +276,14 @@ $.fn.fullCalendar = function(options) {
params[options.endParam] = Math.round(eventEnd.getTime() / 1000); params[options.endParam] = Math.round(eventEnd.getTime() / 1000);
params[options.cacheParam] = (new Date()).getTime(); params[options.cacheParam] = (new Date()).getTime();
pushLoading(); pushLoading();
$.getJSON(src, params, reportEvents); $.getJSON(src, params, reportPopEvents);
} }
else if ($.isFunction(src)) { else if ($.isFunction(src)) {
pushLoading(); pushLoading();
src(cloneDate(eventStart), cloneDate(eventEnd), reportEvents); src(cloneDate(eventStart), cloneDate(eventEnd), reportPopEvents);
} }
else { else {
reportEvents(src, true); // src is an array reportEvents(src); // src is an array
} }
} }
@ -329,73 +330,123 @@ $.fn.fullCalendar = function(options) {
render(); render();
}, },
gotoDate: function() { gotoDate: function(year, month, dateNum) {
if (typeof year != 'undefined') {
date.setYear(year);
}
if (typeof month != 'undefined') {
date.setMonth(month);
}
if (typeof dateNum != 'undefined') {
date.setDate(dateNum);
}
render();
}, },
moveDate: function() { moveDate: function(years, months, days) {
if (typeof years != 'undefined') {
addYears(date, years);
}
if (typeof months != 'undefined') {
addMonths(date, months);
}
if (typeof days != 'undefined') {
addDays(date, days);
}
render();
}, },
// //
// Event Rendering // Event Rendering
// //
renderEvent: function(event, stick) { updateEvent: function(event) {
if (typeof event != 'object') {
event = eventsByID(event)[0]; // assumed to be ID
if (!event) return;
}else{
normalizeEvent(event);
}
var startDelta = event.start - event._start, var startDelta = event.start - event._start,
msDuration = event.end - event.start, endDelta = event.end ? (event.end - (event._end || view.defaultEventEnd(event))) : 0,
i, len = events.length, e, i, len = events.length, e;
found = false;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
e = events[i]; e = events[i];
if (e._id == event._id) { if (e._id == event._id && e != event) {
if (e != event) { e.start = new Date(+e.start + startDelta);
e._start = cloneDate(e.start = new Date(+e.start + startDelta)); if (event.end) {
e.end = new Date(+e.start + msDuration); if (e.end) {
e.title = event.title; e.end = new Date(+e.end + endDelta);
e.hasTime = event.hasTime; }else{
if (stick && !event.source) { e.end = new Date(+view.defaultEventEnd(e) + endDelta);
(event.source = eventSources[0]).push(event);
} }
}else{
e.end = null;
} }
found = true; e.title = event.title;
e.allDay = event.allDay;
normalizeEvent(e);
} }
} }
if (!found) { normalizeEvent(event);
eventsChanged();
},
renderEvent: function(event, stick) {
normalizeEvent(event);
if (!event.source) {
if (stick) {
(event.source = eventSources[0]).push(event);
}
events.push(event); events.push(event);
} }
eventsChanged(); eventsChanged();
}, },
removeEvent: function(id) { removeEvents: function(filter) {
if (typeof id == 'object') { if (!filter) { // remove all
id = id._id; events = [];
// clear all array sources
for (var i=0; i<eventSources.length; i++) {
if (typeof eventSources[i] == 'object') {
eventSources[i] = [];
}
}
}else{ }else{
id += ''; if (!$.isFunction(filter)) { // an event ID
var id = filter + '';
filter = function(e) {
return e._id == id;
};
}
events = filterArray(events, function(e) {
return !filter(e);
});
// remove events from array sources
for (var i=0; i<eventSources.length; i++) {
if (typeof eventSources[i] == 'object') {
eventSources[i] = filterArray(eventSources[i], function(e) {
return !filter(e);
});
}
}
} }
removeEvents(function(e) { eventsChanged();
return e._id != id;
});
}, },
clientEvents: function(filter) { clientEvents: function(filter) {
if (filter) { if ($.isFunction(filter)) {
return filterArray(events, filter); return filterArray(events, filter);
}else{ }
else if (filter) { // an event ID
filter += '';
return filterArray(events, function(e) {
return e._id == filter;
});
}
else {
return events; return events;
} }
}, },
rerender: function() { rerenderEvents: function() {
view.rerenderEvents();
}, },
clientEventsByID: eventsByID,
removeEvents: removeEvents,
// //
// Event Source // Event Source
// //
@ -418,46 +469,14 @@ $.fn.fullCalendar = function(options) {
eventsChanged(); eventsChanged();
}, },
refetch: function() { refetchEvents: function() {
fetchEvents(eventsChanged);
} }
}; };
$.data(this, 'fullCalendar', publicMethods); $.data(this, 'fullCalendar', publicMethods);
function eventsByID(id) {
id += '';
return filterArray(events, function(e) {
e._id == id;
});
}
function removeEvents(filter) {
var i, len = eventSources.length;
if (filter) {
events = filterArray(events, function(e) {
return !filter(e);
});
// remove events from array sources
for (i=0; i<len; i++) {
if (typeof eventSources[i] == 'object') {
eventSources[i] = filterArray(eventSources[i], function(e) {
return !filter(e);
});
}
}
}else{
events = [];
// clear all array sources
for (i=0; i<len; i++) {
if (typeof eventSources[i] == 'object') {
eventSources[i] = [];
}
}
}
eventsChanged();
}
/* Header /* Header
@ -489,47 +508,58 @@ $.fn.fullCalendar = function(options) {
tr.append("<td><h2 class='fc-header-title'/></td>"); tr.append("<td><h2 class='fc-header-title'/></td>");
prevTitle = true; prevTitle = true;
}else{ }else{
var button, var buttonClick;
icon = options.theme ? options.buttonIcons[buttonNameShort] : null, if (publicMethods[buttonNameShort]) {
text = options.buttonText[buttonNameShort]; buttonClick = publicMethods[buttonNameShort];
if (icon) {
button = $("<div class='fc-button-" + buttonName + " ui-state-default'>" +
"<a><span class='ui-icon ui-icon-" + icon + "'/></a></div>");
} }
else if (text) { else if (views[buttonName]) {
button = $("<div class='fc-button-" + buttonName + " " + tm + "-state-default'>" + buttonClick = function() { switchView(buttonName) };
"<a><span>" + text + "</span></a></div>");
} }
if (button) { if (buttonClick) {
button var button,
.mousedown(function() { icon = options.theme ? options.buttonIcons[buttonNameShort] : null,
button.addClass(tm + '-state-down'); text = options.buttonText[buttonNameShort];
}) if (icon) {
.mouseup(function() { button = $("<div class='fc-button-" + buttonName + " ui-state-default'>" +
button.removeClass(tm + '-state-down'); "<a><span class='ui-icon ui-icon-" + icon + "'/></a></div>");
})
.hover(function() {
button.addClass(tm + '-state-hover');
},
function() {
button.removeClass(tm + '-state-hover')
.removeClass(tm + '-state-down');
})
.appendTo($("<td/>").appendTo(tr));
if (publicMethods[buttonNameShort]) {
button.click(publicMethods[buttonNameShort]);
} }
else if (views[buttonName]) { else if (text) {
button.click(function() { button = $("<div class='fc-button-" + buttonName + " " + tm + "-state-default'>" +
switchView(buttonName); "<a><span>" + text + "</span></a></div>");
});
} }
if (j == 0 || prevTitle) { if (button) {
button.addClass(tm + '-corner-left'); button
}else{ .mousedown(function() {
button.addClass(tm + '-no-left'); button.addClass(tm + '-state-down');
})
.mouseup(function() {
button.removeClass(tm + '-state-down');
})
.hover(
function() {
button.addClass(tm + '-state-hover');
},
function() {
button.removeClass(tm + '-state-hover')
.removeClass(tm + '-state-down');
}
)
.appendTo($("<td/>").appendTo(tr));
if (publicMethods[buttonNameShort]) {
button.click(publicMethods[buttonNameShort]);
}
else if (views[buttonName]) {
button.click(function() {
switchView(buttonName);
});
}
if (j == 0 || prevTitle) {
button.addClass(tm + '-corner-left');
}else{
button.addClass(tm + '-no-left');
}
prevTitle = false;
} }
prevTitle = false;
} }
} }
}); });
@ -572,6 +602,8 @@ $.fn.fullCalendar = function(options) {
}); });
return this;
}; };
@ -583,7 +615,20 @@ var fakeID = 0;
function normalizeEvent(event) { function normalizeEvent(event) {
event._id = event._id || (typeof event.id == 'undefined' ? '_fc' + fakeID++ : event.id + ''); event._id = event._id || (typeof event.id == 'undefined' ? '_fc' + fakeID++ : event.id + '');
if (event.date) {
if (!event.start) {
event.start = event.date;
}
delete event.date;
}
event._start = cloneDate(event.start = parseDate(event.start)); event._start = cloneDate(event.start = parseDate(event.start));
event.end = parseDate(event.end); event.end = parseDate(event.end);
if (event.end && event.end < event.start) {
event.end = cloneDate(event.start);
}
event._end = event.end ? cloneDate(event.end) : null;
if (typeof event.allDay == 'undefined') {
event.allDay = true;
}
} }

View file

@ -4,14 +4,14 @@
var DAY_MS = 86400000; var DAY_MS = 86400000;
function addMonths(d, n, keepTime) { function addYears(d, n, keepTime) {
d.setMonth(d.getMonth() + n); d.setFullYear(d.getFullYear() + n);
if (keepTime) return d; if (keepTime) return d;
return clearTime(d); return clearTime(d);
} }
function addYears(d, n, keepTime) { function addMonths(d, n, keepTime) {
d.setFullYear(d.getFullYear() + n); d.setMonth(d.getMonth() + n);
if (keepTime) return d; if (keepTime) return d;
return clearTime(d); return clearTime(d);
} }

View file

@ -8,7 +8,7 @@ var viewMethods = {
// - end // - end
// - visStart // - visStart
// - visEnd // - visEnd
// - eventEnd(event) // - defaultEventEnd(event)
// - visEventEnd(event) // - visEventEnd(event)
// //
// - render // - render
@ -26,6 +26,8 @@ var viewMethods = {
// trigger event handlers, always append view as last arg
trigger: function(name, thisObj) { trigger: function(name, thisObj) {
if (this.options[name]) { if (this.options[name]) {
return this.options[name].apply(thisObj || this, Array.prototype.slice.call(arguments, 2).concat([this])); return this.options[name].apply(thisObj || this, Array.prototype.slice.call(arguments, 2).concat([this]));
@ -34,6 +36,14 @@ var viewMethods = {
//
eventEnd: function(event) {
return event.end || this.defaultEventEnd(event);
},
// event/element creation reporting // event/element creation reporting
reportEvents: function(events) { reportEvents: function(events) {
@ -64,21 +74,6 @@ var viewMethods = {
// get events within visStart and visEnd TODO: need this? move it somewhere else?
visibleEvents: function(events) {
var res=[], i, len=events.length, event;
for (i=0; i<len; i++) {
event = events[i];
if (this.visEventEnd(event) > this.visStart && event.start < this.visEnd) {
res.push(event);
}
}
return res;
},
// event element manipulation // event element manipulation
clearEvents: function() { // just remove ELEMENTS clearEvents: function() { // just remove ELEMENTS
@ -115,7 +110,7 @@ var viewMethods = {
var i, event2, events = this.eventsByID[event._id]; var i, event2, events = this.eventsByID[event._id];
for (i=0; i<events.length; i++) { for (i=0; i<events.length; i++) {
event2 = events[i]; event2 = events[i];
event2.hasTime = event.hasTime; event2.allDay = event.allDay;
addMinutes(addDays(event2.start, days, true), minutes); addMinutes(addDays(event2.start, days, true), minutes);
if (event.end) { if (event.end) {
event2.end = addMinutes(addDays(this.eventEnd(event2), days, true), minutes); event2.end = addMinutes(addDays(this.eventEnd(event2), days, true), minutes);
@ -239,27 +234,11 @@ function stackSegs(segs) {
}else{ }else{
levels[j] = [seg]; levels[j] = [seg];
} }
seg.after = 0; //seg.after = 0;
} }
return levels; return levels;
} }
function segAfters(levels) { // TODO: put in agenda.js
var i, j, k, level, seg, seg2;
for (i=levels.length-1; i>0; i--) {
level = levels[i];
for (j=0; j<level.length; j++) {
seg = level[j];
for (k=0; k<segLevels[i-1].length; k++) {
seg2 = segLevels[i-1][k];
if (segsCollide(seg, seg2)) {
seg2.after = Math.max(seg2.after, seg.after+1);
}
}
}
}
}
function segCmp(a, b) { function segCmp(a, b) {
return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start); return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
} }

View file

@ -1,134 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$('#calendar').fullCalendar({
monthDisplay: function(year, month, monthTitle) {
$.jGrowl("<b>monthDisplay</b><br />" +
year + "-" + month + "<br />" +
monthTitle);
},
loading: function(bool) {
$.jGrowl("<b>loading</b>: " + bool);
},
resize: function() {
$.jGrowl("<b>resize</b>");
},
dayClick: function(date) {
$.jGrowl("<b>dayClick</b><br />" +
date + "<br />" +
this.nodeName);
},
eventRender: function(event, element) {
if (event.id == 3) {
//return false;
return $("<div style='background:red' />").text(event.title);
}
},
eventClick: function(event, ev) {
$.jGrowl("<b>eventClick</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
//return false;
},
/*eventMouseover: function(event, ev) {
$.jGrowl("<b>eventMouseover</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
},
eventMouseout: function(event, ev) {
$.jGrowl("<b>eventMouseout</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
},*/
eventDragStart: function(event, ev, ui) {
$.jGrowl("<b>eventDragStart</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
eventDragStop: function(event, ev, ui) {
$.jGrowl("<b>eventDragStop</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
eventDrop: function(event, delta, ev, ui) {
$.jGrowl("<b>eventDrop</b><br />" +
delta + "<br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
draggable: true,
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6, 14, 0),
end: new Date(y, m, 11)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0)
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27, 16),
end: new Date(y, m, 29),
url: "http://facebook.com/"
}
]
});
});
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div id='calendar' style='width:75%'></div>
</body>
</html>

115
test/gcal.html Executable file
View file

@ -0,0 +1,115 @@
<!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='loader.js'></script>
<script type='text/javascript'>
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$(document).ready(function() {
$('#calendar').fullCalendar({
editable: true,
eventSources: [
$.fullCalendar.gcalFeed(
"http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
{
//editable: true,
className: 'holiday'
}
),
/*$.fullCalendar.gcalFeed(
"http://www.google.com/calendar/feeds/mike%40maddogsportsbar.com/private-4ad75f9427058f8fe6525c0857c59fbc/basic",
{
className: 'maddog'
}
),*/
[
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
end: new Date(y, m, 10)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0),
end: new Date(y, m, 20, 10, 0),
allDay: false
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
end: new Date(y, m, 28),
url: "http://facebook.com/"
},
{
id: 5,
title: "timed event1",
start: new Date (y, m, 31, 17, 30),
allDay: false
},
{
id: 6,
title: "timed event1",
start: new Date (y, m+1, 2, 14, 15),
allDay: false
},
{
id: 7,
title: "timed event1",
start: new Date (y, m+1, 4, 15, 00),
end: new Date(y, m+1, 4, 17, 00),
allDay: false
}
]
]
});
});
</script>
<style>
.holiday,
.holiday a {
background: green;
border-color: green;
}
.maddog,
.maddog a {
background: red;
border-color: red;
}
/* rescued from fullcalendar.css (not used here) */
.fc-event-nobg,
.fc-event-nobg a,
.fc-agenda .fc-event-nobg .fc-event-time {
border-style: none;
background: none;
color: inherit;
}
</style>
</head>
<body style='font-size:12px'>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

View file

@ -1,89 +1,82 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <html>
<head> <head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' /> <script type='text/javascript' src='loader.js'></script>
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' /> <script type='text/javascript'>
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script> var d = new Date();
<script type='text/javascript' src='../jquery/ui.draggable.js'></script> var y = d.getFullYear();
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script> var m = d.getMonth();
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'> $(document).ready(function() {
$('#calendar').fullCalendar({
$(document).ready(function() { header: {
center: 'month,basicWeek,basicDay'
$.fullCalendar.monthNames = ["januari", "februari", "maart", "april", "mei", "juni","juli", "augustus", "september", "oktober", "november", "december"]; },
$.fullCalendar.monthAbbrevs = ["jan", "feb", "maa", "apr", "mei", "jun", "jul", "aug","sep", "okt", "nov", "dec"]; editable: true,
$.fullCalendar.dayNames = ['zondag', 'maandag', 'dinsdag', 'woensdag','donderdag', 'vrijdag', 'zaterdag'];
$.fullCalendar.dayAbbrevs = ["zo", "ma", "di", "wo", "do", "vr", "za", "zo"]; isRTL: true,
weekMode: 'variable',
var d = new Date();
var y = d.getFullYear(); // TODO: add drag & resize tests
var m = d.getMonth();
events: [
$('#calendar').fullCalendar({ {
id: 1,
abbrevDayHeadings: false, title: "Long Event",
start: new Date(y, m, 6),
weekStart: 1, end: new Date(y, m, 10)
},
//rightToLeft: true, {
id: 2,
events: [ title: "Repeating",
{ start: new Date(y, m, 2)
id: 1, },
title: "Long Event", {
start: new Date(y, m, 6, 14, 0), id: 2,
end: new Date(y, m, 11) title: "Repeating",
}, start: new Date(y, m, 9)
{ },
id: 2, {
title: "Repeating Event", id: 3,
start: new Date(y, m, 2) title: "Meeting",
}, start: new Date(y, m, 20, 9, 0),
{ end: new Date(y, m, 20, 10, 0),
id: 2, allDay: false
title: "Repeating Event", },
start: new Date(y, m, 9) {
}, id: 4,
{ title: "Click for Facebook",
id: 3, start: new Date(y, m, 27),
title: "Meeting", end: new Date(y, m, 28),
start: new Date(y, m, 20, 9, 0) url: "http://facebook.com/"
}, },
{ {
id: 4, id: 5,
title: "Click for Facebook", title: "timed event1",
start: new Date(y, m, 27, 16), start: new Date (y, m, 31, 17, 30),
end: new Date(y, m, 29), allDay: false
url: "http://facebook.com/" },
} {
], id: 6,
title: "timed event1",
draggable: true, start: new Date (y, m+1, 2, 14, 15),
allDay: false
dayClick: function(date) { },
$(this).css('background', 'lightblue'); {
$.jGrowl("<b>dayClick</b><br />" + id: 7,
date + "<br />" + title: "timed event1",
this.nodeName); start: new Date (y, m+1, 4, 15, 00),
}, end: new Date(y, m+1, 4, 17, 00),
allDay: false
eventDrop: function(event, delta, ev, ui) { }
$.jGrowl("<b>eventDrop</b><br />" + ]
delta + "<br />" + });
event.title + "<br />" + });
ev.pageX + "," + ev.pageY + "<br />" +
ui); </script>
} </head>
<body style='font-size:12px'>
}); <div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
}); </html>
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div id='calendar' style='width:75%'></div>
</body>
</html>

View file

@ -1,110 +1,150 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <html>
<head> <head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' /> <script type='text/javascript' src='loader.js'></script>
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' /> <script type='text/javascript'>
<style type='text/css'>
var cal;
.newclass { color: red } var d = new Date();
var y = d.getFullYear();
</style> var m = d.getMonth();
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script> var staticEvents;
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script> $(document).ready(function() {
<script type='text/javascript' src='jgrowl/jgrowl.js'></script> cal = $('#calendar').fullCalendar({
<script type='text/javascript'> editable: true,
header: {
$(document).ready(function() { left: 'prev,next today',
center: 'title',
$('#calendar').fullCalendar({ right: 'month,basicWeek,basicDay'
},
title: false, events: staticEvents = [
buttons: false, {
monthDisplay: function(year, month, title) { id: 1,
$('h3').text(title); title: "Long Event",
}, start: new Date(y, m, 6),
end: new Date(y, m, 10)
draggable: true },
{
}); id: 2,
title: "Repeating",
}); start: new Date(y, m, 2)
},
function addTestEvents() { {
id: 2,
var d = new Date(); title: "Repeating",
var y = d.getFullYear(); start: new Date(y, m, 9)
var m = d.getMonth()+1; },
if (m<10) m = '0' + m; {
id: 3,
$('#calendar').fullCalendar('addEvent', { title: "Meeting",
id: 99, start: new Date(y, m, 20, 9, 0),
title: 'Some event', end: new Date(y, m, 21, 0, 0),
start: y+'-'+m+'-02' allDay: false
}); },
{
$('#calendar').fullCalendar('addEvent', { id: 4,
id: 99, title: "Click for Facebook",
title: 'Some event', start: new Date(y, m, 27),
start: y+'-'+m+'-09' end: new Date(y, m, 28),
}); url: "http://facebook.com/"
},
$('#calendar').fullCalendar('addEvent', { {
id: 5, id: 5,
title: 'Birthday', title: "timed event1",
start: y+'-'+m+'-20' start: new Date (y, m, 31, 17, 30),
}); allDay: false
},
} {
id: 6,
function updateTestEvents() { title: "timed event1",
start: new Date (y, m+1, 2, 14, 15),
var d = new Date(); allDay: false
var y = d.getFullYear(); },
var m = d.getMonth()+1; {
if (m<10) m = '0' + m; id: 7,
title: "timed event1",
var reps = $('#calendar').fullCalendar('getEventsById', 99); start: new Date (y, m+1, 4, 15, 00),
var e = reps[1]; end: new Date(y, m+1, 4, 17, 00),
e.title = "Better Title!"; allDay: false
e.start = y+'-'+m+'-11'; }
e.end = y+'-'+m+'-13'; ]
e.className = 'newclass'; });
e.draggable = false; });
e.showTime = true;
$('#calendar').fullCalendar('updateEvent', e); function updateEventStart() {
var event = cal.fullCalendar('clientEvents', 3)[0];
} event.start = new Date(y, m, 25, 10, 30);
event.end = new Date(y, m, 26);
function removeTestEvents(therepeating) { cal.fullCalendar('updateEvent', event);
if (therepeating) { }
$('#calendar').fullCalendar('removeEvent', 99);
}else{ function updateRepeatingEvent() {
$('#calendar').fullCalendar('removeEvent', 5); var event = cal.fullCalendar('clientEvents', 2)[0];
} event.start = new Date(y, m, 4, 13, 30);
} event.end = new Date(y, m, 5, 1, 0);
event.allDay = false;
</script> event.title = "repeat yo";
</head> cal.fullCalendar('updateEvent', event);
<body style='font-size:14px;font-family:Arial'> console.log(cal.fullCalendar('clientEvents', 2));
}
<div style='float:right'>
<input type='button' value='add test events' onclick='addTestEvents()' /><br /> function renderEvent(stick) {
<input type='button' value='update test events' onclick='updateTestEvents()' /><br /> cal.fullCalendar('renderEvent', {
<input type='button' value='delete repeating events' onclick='removeTestEvents(true)' /><br /> start: new Date(y, m, 16),
<input type='button' value='delete single event' onclick='removeTestEvents(false)' /><br /> title: 'heyman'
</div> }, stick);
}
<h3></h3>
<p> var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
<a href='#' onclick="$('#calendar').fullCalendar('today')">today</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('prevMonth')">prev</a> &nbsp; var jsonFeed = "../examples/json_events.php";
<a href='#' onclick="$('#calendar').fullCalendar('nextMonth')">next</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('prevYear')">prevyear</a> &nbsp; </script>
<a href='#' onclick="$('#calendar').fullCalendar('nextYear')">nextyear</a> &nbsp; <style>
<a href='#' onclick="$('#calendar').fullCalendar('gotoMonth', 1986, 5)">June 1986</a>
</p> button {
<div id='calendar' style='width:75%'></div> font-size: 11px;
</body> }
</html>
</style>
</head>
<body style='font-size:12px'>
<p>
<button onclick="cal.fullCalendar('prev')">prev</button>
<button onclick="cal.fullCalendar('next')">next</button>
<button onclick="cal.fullCalendar('today')">today</button>
<button onclick="cal.fullCalendar('gotoDate', 1999, 9, 31)">Oct 31 1999</button>
<button onclick="cal.fullCalendar('moveDate', 1, 1, 1)">+1 +1 +1</button>
<button onclick="cal.fullCalendar('moveDate', -1, -1, -1)">-1 -1 -1</button>
<button onclick="updateEventStart()">update event start</button>
<button onclick="updateRepeatingEvent()">update repeating event</button>
<button onclick="renderEvent(false)">render new event</button>
<button onclick="renderEvent(true)">render new sticky event</button>
<br />
<button onclick="cal.fullCalendar('removeEvents')">remove all</button>
<button onclick="cal.fullCalendar('removeEvents', 2)">remove repeating events</button>
<button onclick="cal.fullCalendar('removeEvents', function(e){return !e.allDay})">remove timed events</button>
<button onclick="console.log(cal.fullCalendar('clientEvents'))">log events</button>
<button onclick="console.log(cal.fullCalendar('clientEvents', '2'))">log repeating events</button>
<button onclick="console.log(cal.fullCalendar('clientEvents', function(e){return e.allDay}))">log all-day events</button>
<br />
<button onclick="cal.fullCalendar('addEventSource', staticEvents)">+ static events</button>
<button onclick="cal.fullCalendar('removeEventSource', staticEvents)">- static events</button>
<button onclick="cal.fullCalendar('addEventSource', gcalFeed)">+ gcal</button>
<button onclick="cal.fullCalendar('removeEventSource', gcalFeed)">- gcal</button>
<button onclick="cal.fullCalendar('addEventSource', jsonFeed)">+ json</button>
<button onclick="cal.fullCalendar('removeEventSource', jsonFeed)">- json</button>
<button onclick="cal.fullCalendar('rerenderEvents')">rerender</button>
<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
</p>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

View file

@ -1,119 +0,0 @@
<!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='loader.js'></script>
<script type='text/javascript'>
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$(document).ready(function() {
$('#calendar').fullCalendar({
windowResize: function() {
//alert('resize');
},
theme: false,
isRTL: false,
weekStart: 1,
weekMode: 'fixed',
//defaultView: 'dayBasic',
viewDisplay: function(date, view) {
//console.log(date + ', ' + view.name);
},
dayClick: function(date, view) {
//console.log(date + ', ' + view.name);
},
eventRender: function(event, element) {
//console.log(event.title + ' RENDER');
},
eventMouseover: function(event) {
//console.log('OVER ' + event.title);
},
eventMouseout: function(event) {
//console.log('OUT ' + event.title);
},
eventClick: function(event) {
//console.log('CLICK ' + event.title + ' /// ' + this.className);
//return false;
},
eventDragStart: function(event) {
console.log('DRAG START ' + event.title);
},
eventDragStop: function(event) {
console.log('DRAG STOP ' + event.title);
},
eventDrop: function(event, dayDelta, minuteDelta) {
console.log(dayDelta + ' ' + minuteDelta + ' --- ' + event.title);
},
eventResizeStart: function(event) {
//console.log('resize START');
},
eventResizeStop: function(event) {
//console.log('resize STOP');
},
eventResize: function(event, dayDelta, minuteDelta) {
//console.log(dayDelta + ' ' + minuteDelta + ' --- ' + event.title);
},
editable: true,
eventSources: [
$.fullCalendar.gcalFeed('http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic')
],
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
end: new Date(y, m, 10)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0),
hasTime: true
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
end: new Date(y, m, 28),
url: "http://facebook.com/"
},
{
id: 5,
title: "timed event1",
start: new Date (y, m, 31, 17, 30),
hasTime: true
},
{
id: 6,
title: "timed event1",
start: new Date (y, m+1, 2, 14, 15),
hasTime: true
},
{
id: 7,
title: "timed event1",
start: new Date (y, m+1, 4, 15, 00),
end: new Date(y, m+1, 4, 17, 00),
hasTime: true
}
]
});
});
</script>
</head>
<body style='font-size:12px'>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>

View file

@ -1,99 +1,109 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <html>
<head> <head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' /> <script type='text/javascript' src='loader.js'></script>
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' /> <script type='text/javascript'>
<style type='text/css'>
var d = new Date();
.full-calendar-month .rep td { background: green } var y = d.getFullYear();
.full-calendar-month .cool td { color: yellow } var m = d.getMonth();
.full-calendar-month .long td { background: red }
$(document).ready(function() {
</style> $('#calendar').fullCalendar({
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script> /*
<script type='text/javascript' src='../jquery/ui.draggable.js'></script> year: 2010,
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script> month: 2,
<script type='text/javascript' src='jgrowl/jgrowl.js'></script> date: 1,
<script type='text/javascript'>
defaultView: 'basicDay',
$(document).ready(function() {
aspectRatio: 1,
$('#calendar').fullCalendar({ */
year: 2009, header: {
month: 3, left: 'title',
center: 'prev,month,basicWeek,basicDay,next',
draggable: true, right: 'today'
},
fixedWeeks: true,
editable: true,
abbrevDayHeadings: false, //disableDragging: true,
//disableResizing: true,
//title: false, dragOpacity: .5,
titleFormat: 'm/Y', //'n/Y', //'M y', dragRevertDuration: 100,
//buttons: false, weekMode: 'liquid', //'variable'
//buttons: { today:false },
//buttons: { today:false, prevMonth:"prev", nextMonth:"next" }, /*
//buttons: { today:true, prevMonth:false, nextMonth:"next" }, titleFormat: {
//buttons: { prevYear:true, nextYear:true }, month: "'hey!'"
//buttons: { today:true, prevYear:"py", prevMonth:true, nextMonth:true, nextYear:"ny" }, },
*/
showTime: true,
timeFormat: 'ha', //'H:i', //'GA', //'gX', columnFormat: {
month: "dddd"
eventDragOpacity: .5, },
eventRevertDuration: 2000,
timeFormat: "H(:mm)[T]{ - H(:mm)T}",
// test for CalEvent.source
eventDrop: function(event) { events: [
$.jGrowl(event.source); {
}, id: 1,
title: "Long Event",
events: [ start: new Date(y, m, 6),
{ end: new Date(y, m, 10)
id: 1, },
title: "Long Event", {
start: new Date(2009, 3, 6, 14, 0), id: 2,
end: new Date(2009, 3, 11), title: "Repeating",
showTime: false, // showTime start: new Date(y, m, 2)
className: 'long', },
draggable: false // draggable {
}, id: 2,
{ title: "Repeating",
id: 2, start: new Date(y, m, 9)
title: "Repeating Event", },
start: new Date(2009, 3, 2), {
className: 'rep cool' id: 3,
}, title: "Meeting",
{ start: new Date(y, m, 20, 9, 0),
id: 2, end: new Date(y, m, 20, 10, 0),
title: "Repeating Event", allDay: false
start: new Date(2009, 3, 9), },
className: ['rep', 'cool'] {
}, id: 4,
{ title: "Click for Facebook",
id: 3, start: new Date(y, m, 27),
title: "Meeting", end: new Date(y, m, 28),
date: new Date(2009, 3, 20, 9, 30) // date alias url: "http://facebook.com/"
}, },
{ {
id: 4, id: 5,
title: "Click for Facebook", title: "timed event1",
start: new Date(2009, 3, 27, 16), start: new Date (y, m, 31, 17, 30),
end: new Date(2009, 3, 29), allDay: false
url: "http://facebook.com/" },
} {
] id: 6,
title: "timed event1",
}); start: new Date (y, m+1, 2, 14, 15),
allDay: false
}); },
{
</script> id: 7,
</head> title: "timed event1",
<body style='font-size:14px;font-family:Arial'> start: new Date (y, m+1, 4, 15, 00),
<div id='calendar' style='width:75%'></div> end: new Date(y, m+1, 4, 17, 00),
</body> allDay: false
</html> }
]
});
});
</script>
</head>
<body style='font-size:12px'>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

View file

@ -1,145 +1,144 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <html>
<head> <head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' /> <script type='text/javascript' src='loader.js'></script>
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' /> <script type='text/javascript'>
<style type='text/css'>
var cal;
.full-calendar-month .static td { var d = new Date();
background: blue; var y = d.getFullYear();
color: yellow; var m = d.getMonth();
}
var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
.full-calendar-month .gcal td {
background: lightgreen; var jsonFeed = "../examples/json_events.php";
}
var staticEvents = [
</style> {
id: 1,
<!-- title: "Long Event",
<script type='text/javascript' src='legacy_jquery/jquery.js'></script> date: new Date(y, m, 6), //!
<script type='text/javascript' src='legacy_jquery/ui.core.js'></script> end: new Date(y, m, 10),
<script type='text/javascript' src='legacy_jquery/ui.draggable.js'></script> className: 'red-event'
--> },
{
<script type='text/javascript' src='../jquery/jquery.js'></script> id: 2,
<script type='text/javascript' src='../jquery/ui.core.js'></script> title: "Repeating",
<script type='text/javascript' src='../jquery/ui.draggable.js'></script> start: new Date(y, m, 2)
},
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script> {
<!--<script type='text/javascript' src='../build/fullcalendar.min.js'></script>--> id: 2,
<script type='text/javascript' src='../fullcalendar/gcal.js'></script> title: "Repeating",
<script type='text/javascript' src='jgrowl/jgrowl.js'></script> start: new Date(y, m, 9)
<script type='text/javascript'> },
{
$(document).ready(function() { id: 3,
title: "Meeting",
var d = new Date(); start: new Date(y, m, 20, 9, 0),
var y = d.getFullYear(); end: new Date(y, m, 21, 0, 0),
var m = d.getMonth(); allDay: false,
//className: 'yellow-event black-text-event',
var gcalSource = $.fullCalendar.gcalFeed( className: ['yellow-event', 'black-text-event'],
'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic', editable: false
{draggable: true, className: 'gcal'} },
); {
id: 4,
var staticSource = [ title: "Click for Facebook",
{ start: new Date(y, m, 27),
id: 1, end: new Date(y, m, 28),
title: "Long Event", url: "http://facebook.com/"
start: new Date(y, m, 6, 14, 0), },
end: new Date(y, m, 11), {
className: 'static' id: 5,
}, title: "timed event1",
{ start: new Date (y, m, 31, 17, 30),
id: 2, allDay: false
title: "Repeating Event", },
start: new Date(y, m, 2), {
className: 'static' id: 6,
}, title: "timed event1",
{ start: new Date (y, m+1, 2, 14, 15),
id: 2, allDay: false
title: "Repeating Event", },
start: new Date(y, m, 9), {
className: 'static' id: 7,
}, title: "timed event1",
{ start: new Date (y, m+1, 4, 15, 00),
id: 3, end: new Date(y, m+1, 4, 17, 00),
title: "Meeting", allDay: false
start: new Date(y, m, 20, 9, 0), }
className: 'static' ];
},
{ var customSource = function(start, end, callback) {
id: 4, callback([
title: "Click for Facebook", {
start: new Date(y, m, 27, 16), title: 'FIRST',
end: new Date(y, m, 29), start: start
url: "http://facebook.com/", },
className: 'static' {
} title: 'LAST',
]; start: new Date(end - 1)
}
var jsonSource = "../examples/json_events.php"; ]);
};
$('#calendar').fullCalendar({
$(document).ready(function() {
draggable: true, cal = $('#calendar').fullCalendar({
editable: true,
eventSources: [staticSource, gcalSource], header: {
left: 'prev,next today',
loading: function(bool) { center: 'title',
if (bool) { right: 'month,basicWeek,basicDay'
$('#loading').css('visibility', 'visible'); },
}else{ //events: staticEvents,
$('#loading').css('visibility', 'hidden'); eventSources: [
} staticEvents,
} jsonFeed,
gcalFeed,
}); customSource
],
window.addStaticSource = function() { loading: function(bool) {
$('#calendar').fullCalendar('addEventSource', staticSource); if (bool) {
}; $('#loading').show();
}else{
window.addJsonSource = function() { $('#loading').hide();
$('#calendar').fullCalendar('addEventSource', jsonSource); }
}; }
/*
window.addGcalSource = function() { ,
$('#calendar').fullCalendar('addEventSource', gcalSource); startParam: 'mystart',
}; endParam: 'myend',
cacheParam: 'uniq'
window.removeStaticSource = function() { */
$('#calendar').fullCalendar('removeEventSource', staticSource); });
}; });
window.removeJsonSource = function() { </script>
$('#calendar').fullCalendar('removeEventSource', jsonSource); <style>
};
.red-event a {
window.removeGcalSource = function() { background: red;
$('#calendar').fullCalendar('removeEventSource', gcalSource); }
};
.yellow-event a {
}); background: yellow;
}
</script>
</head> .black-text-event a {
<body style='font-size:14px;font-family:Arial'> color: #000;
}
<div style='float:right'>
<input type='button' value='add static event source' onclick='addStaticSource()' /><br /> button {
<input type='button' value='* add json event source' onclick='addJsonSource()' /><br /> font-size: 11px;
<input type='button' value='add gcal event source' onclick='addGcalSource()' /><br /> }
<br />
<input type='button' value='remove static event source' onclick='removeStaticSource()' /><br /> </style>
<input type='button' value='remove json event source' onclick='removeJsonSource()' /><br /> </head>
<input type='button' value='remove gcal event source' onclick='removeGcalSource()' /><br /> <body style='font-size:12px'>
<br /> <div id='loading' style='position:absolute;top:0;left:0;display:none'>loading...</div>
<input type='button' value='refresh' onclick="$('#calendar').fullCalendar('refresh')" /> <p>
</div> <button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
</p>
<div style='visibility:hidden' id='loading'>loading...</div> <div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
<div id='calendar' style='float:left;width:75%'></div> </body>
</body> </html>
</html>

87
test/theming.html Executable file
View file

@ -0,0 +1,87 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../examples/redmond/theme.css' />
<script type='text/javascript' src='loader.js'></script>
<script type='text/javascript'>
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$(document).ready(function() {
$('#calendar').fullCalendar({
theme: true,
editable: true,
header: {
center: 'month,basicWeek,basicDay'
},
buttonIcons: {
prev: 'triangle-1-w',
next: 'triangle-1-e',
today: 'home'
},
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
end: new Date(y, m, 10)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0),
end: new Date(y, m, 20, 10, 0),
allDay: false
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
end: new Date(y, m, 28),
url: "http://facebook.com/"
},
{
id: 5,
title: "timed event1",
start: new Date (y, m, 31, 17, 30),
allDay: false
},
{
id: 6,
title: "timed event1",
start: new Date (y, m+1, 2, 14, 15),
allDay: false
},
{
id: 7,
title: "timed event1",
start: new Date (y, m+1, 4, 15, 00),
end: new Date(y, m+1, 4, 17, 00),
allDay: false
}
]
});
});
</script>
</head>
<body style='font-size:12px'>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

180
test/triggers.html Executable file
View file

@ -0,0 +1,180 @@
<!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='loader.js'></script>
<script type='text/javascript'>
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
weekMode: 'variable',
viewDisplay: function(view) {
console.log('viewDisplay');
console.log(view);
console.log(this);
},
//loading: // see sources.html
windowResize: function(view) {
console.log('windowResize - ' + view.title);
console.log(this);
},
dayClick: function(dayDate, view) {
console.log('dayClick - ' + dayDate + ' - ' + view.title);
console.log(this);
},
eventRender: function(event, element, view) {
if (event.id == 555) {
return false;
}
else if (event.id == 666) {
return $("<div style='background:green'/>").text(event.title);
}
else if (event.id == 1) {
element.css('border-color', 'red');
console.log('renderEvent (' + event.title + ') - ' + view.title);
}
},
eventClick: function(event, jsEvent, view) {
console.log('EVENT CLICK ' + event.title);
console.log(jsEvent);
console.log(view);
console.log(this);
return false;
},
/*
eventMouseover: function(event, jsEvent, view) {
console.log('MOUSEOVER ' + event.title);
console.log(jsEvent);
console.log(view);
console.log(this);
},
eventMouseout: function(event, jsEvent, view) {
console.log('MOUSEOUT ' + event.title);
console.log(jsEvent);
console.log(view);
console.log(this);
},
*/
eventDragStart: function(event, jsEvent, ui, view) {
console.log('DRAG START ' + event.title);
console.log(this);
},
eventDragStop: function(event, jsEvent, ui, view) {
console.log('DRAG STOP ' + event.title);
console.log(this);
},
eventDrop: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
console.log('DROP ' + event.title);
console.log(dayDelta + ' days');
console.log(minuteDelta + ' minutes');
console.log(jsEvent);
console.log(ui);
console.log(view.title);
console.log(this);
},
eventResizeStart: function(event, jsEvent, ui, view) {
console.log('RESIZE START ' + event.title);
console.log(this);
},
eventResizeStop: function(event, jsEvent, ui, view) {
console.log('RESIZE STOP ' + event.title);
console.log(this);
},
eventResize: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
console.log('RESIZE!! ' + event.title);
console.log(dayDelta + ' days');
console.log(minuteDelta + ' minutes');
console.log(jsEvent);
console.log(ui);
console.log(view.title);
console.log(this);
},
events: [
{
id: 555,
title: "Rejected Event",
start: new Date(y, m, 5)
},
{
id: 666,
title: "Homemade Elm Event",
start: new Date(y, m, 6)
},
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
end: new Date(y, m, 10)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating",
start: new Date(y, m, 9),
end: new Date(y, m, 10)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0),
end: new Date(y, m, 20, 10, 0),
allDay: false
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
end: new Date(y, m, 28),
url: "http://facebook.com/"
},
{
id: 5,
title: "timed event1",
start: new Date (y, m, 31, 17, 30),
allDay: false
},
{
id: 6,
title: "timed event1",
start: new Date (y, m+1, 2, 14, 15),
allDay: false
},
{
id: 7,
title: "timed event1",
start: new Date (y, m+1, 4, 15, 00),
end: new Date(y, m+1, 4, 17, 00),
allDay: false
}
]
});
});
</script>
</head>
<body style='font-size:12px'>
<div id='calendar' style='width:75%;margin:20px auto 0;font-family:arial'></div>
</body>
</html>