gcal timezone enhancement, cache option, DST parseDate bugfix, quickly adding/removing event source bugfix, destroy method, empty string parseDate bugfix

This commit is contained in:
Adam Shaw 2009-12-21 01:32:03 -08:00
parent 82578fb919
commit 6a5be40d41
11 changed files with 316 additions and 47 deletions

View file

@ -29,13 +29,13 @@ The following options determine *how* events get on the calendar:
start: start.getTime(), start: start.getTime(),
end: end.getTime() end: end.getTime()
}, },
function(result) { function(events) {
// format the result into an array of CalEvents // make sure the events are official CalEvent objects
// (not seen here) // (not seen here)
// then, pass the CalEvent array to the callback // then, pass the events to the callback
callback(calevents); callback(events);
}); });
@ -124,4 +124,4 @@ CalEvent:
**source**: Array/String/Function (automatically populated) **source**: Array/String/Function (automatically populated)
A reference to the original array, JSON URL, or function the event A reference to the original array, JSON URL, or function the event
came from. Do not worry about populating this value, FullCalendar will came from. Do not worry about populating this value, FullCalendar will
do this automatically. do this automatically.

View file

@ -116,7 +116,7 @@ Basic Options
of the calendar. When hidden with ``false``, all-day events will not be displayed of the calendar. When hidden with ``false``, all-day events will not be displayed
in agenda views. in agenda views.
**allDayText**: Boolean, *Default*: ``'all-day'`` **allDayText**: String, *Default*: ``'all-day'``
In the agenda views, the text titling the "all-day" slot at the top of the calendar. In the agenda views, the text titling the "all-day" slot at the top of the calendar.
**firstHour**: Integer, *Default*: 6 **firstHour**: Integer, *Default*: 6

View file

@ -34,6 +34,7 @@
editable: true, editable: true,
events: "json-events.php", events: "json-events.php",
cache: false,
eventDrop: function(event, delta) { eventDrop: function(event, delta) {
alert(event.title + ' was moved ' + delta + ' days\n' + alert(event.title + ' was moved ' + delta + ' days\n' +
@ -77,4 +78,4 @@
<div id='calendar'></div> <div id='calendar'></div>
<p>json-events.php needs to be running in the same directory.</p> <p>json-events.php needs to be running in the same directory.</p>
</body> </body>
</html> </html>

View file

@ -24,8 +24,9 @@
'singleevents': true, 'singleevents': true,
'max-results': 9999 'max-results': 9999
}; };
if (options.currentTimezone) { var ctz = options.currentTimezone;
params.ctz = options.currentTimezone.replace(' ', '_'); if (ctz) {
params.ctz = ctz = ctz.replace(' ', '_');
} }
$.getJSON(feedUrl + "?alt=json-in-script&callback=?", params, function(data) { $.getJSON(feedUrl + "?alt=json-in-script&callback=?", params, function(data) {
var events = []; var events = [];
@ -39,6 +40,9 @@
$.each(entry.link, function() { $.each(entry.link, function() {
if (this.type == 'text/html') { if (this.type == 'text/html') {
url = this.href; url = this.href;
if (ctz) {
url += (url.indexOf('?') == -1 ? '?' : '&') + 'ctz=' + ctz;
}
} }
}); });
if (allDay) { if (allDay) {

View file

@ -28,7 +28,7 @@ var defaults = {
// event ajax // event ajax
startParam: 'start', startParam: 'start',
endParam: 'end', endParam: 'end',
cacheParam: '_', cache: false,
// time formats // time formats
titleFormat: { titleFormat: {
@ -147,9 +147,9 @@ $.fn.fullCalendar = function(options) {
// element // element
var _element = this, var _element = this,
element = $(this).addClass('fc'), element = $(_element).addClass('fc'),
elementWidth, elementWidth,
content = $("<div class='fc-content " + tm + "-widget-content' style='position:relative'/>").appendTo(this), // relative for ie6 content = $("<div class='fc-content " + tm + "-widget-content' style='position:relative'/>").prependTo(_element), // relative for ie6
contentHeight; contentHeight;
if (options.isRTL) { if (options.isRTL) {
element.addClass('fc-rtl'); element.addClass('fc-rtl');
@ -338,16 +338,17 @@ $.fn.fullCalendar = function(options) {
var prevViewName = view.name, var prevViewName = view.name,
prevDate = cloneDate(date), prevDate = cloneDate(date),
reportEvents = function(a) { reportEvents = function(a) {
if (prevViewName == view.name && +prevDate == +date) { // protects from fast switching if (prevViewName == view.name && +prevDate == +date && // protects from fast switching
for (var i=0; i<a.length; i++) { $.inArray(src, eventSources) != -1) { // makes sure source hasn't been removed
normalizeEvent(a[i], options); for (var i=0; i<a.length; i++) {
a[i].source = src; normalizeEvent(a[i], options);
a[i].source = src;
}
events = events.concat(a);
if (callback) {
callback(a);
}
} }
events = events.concat(a);
if (callback) {
callback(a);
}
}
}, },
reportEventsAndPop = function(a) { reportEventsAndPop = function(a) {
reportEvents(a); reportEvents(a);
@ -357,9 +358,17 @@ $.fn.fullCalendar = function(options) {
var params = {}; var params = {};
params[options.startParam] = Math.round(eventStart.getTime() / 1000); params[options.startParam] = Math.round(eventStart.getTime() / 1000);
params[options.endParam] = Math.round(eventEnd.getTime() / 1000); params[options.endParam] = Math.round(eventEnd.getTime() / 1000);
params[options.cacheParam] = (new Date()).getTime(); if (options.cacheParam) {
params[options.cacheParam] = (new Date()).getTime(); // TODO: deprecate cacheParam
}
pushLoading(); pushLoading();
$.getJSON(src, params, reportEventsAndPop); $.ajax({
url: src,
dataType: 'json',
data: params,
cache: options.cache,
success: reportEventsAndPop
});
} }
else if ($.isFunction(src)) { else if ($.isFunction(src)) {
pushLoading(); pushLoading();
@ -422,6 +431,15 @@ $.fn.fullCalendar = function(options) {
} }
}, },
destroy: function() {
$(window).unbind('resize', windowResize);
if (header) {
header.remove();
}
content.remove();
$.removeData(_element, 'fullCalendar');
},
// //
// Navigation // Navigation
// //
@ -739,7 +757,7 @@ $.fn.fullCalendar = function(options) {
} }
} }
$(window).resize(function() { function windowResize() {
if (!contentSizeFixed) { if (!contentSizeFixed) {
if (view.date) { // view has already been rendered if (view.date) { // view has already been rendered
var rcnt = ++resizeCnt; // add a delay var rcnt = ++resizeCnt; // add a delay
@ -758,7 +776,8 @@ $.fn.fullCalendar = function(options) {
// was probably in a 0x0 iframe that has just been resized // was probably in a 0x0 iframe that has just been resized
} }
} }
}); };
$(window).resize(windowResize);
// let's begin... // let's begin...

View file

@ -32,23 +32,29 @@ function addMonths(d, n, keepTime) { // prevents day overflow/underflow
} }
function addDays(d, n, keepTime) { // deals with daylight savings function addDays(d, n, keepTime) { // deals with daylight savings
if (+d) { // prevent infinite looping on invalid dates if (+d) {
var dd = d.getDate() + n, var dd = d.getDate() + n,
check = cloneDate(d); check = cloneDate(d);
check.setHours(12); // set to middle of day check.setHours(9); // set to middle of day
check.setDate(dd); check.setDate(dd);
d.setDate(dd); d.setDate(dd);
if (!keepTime) { if (!keepTime) {
clearTime(d); clearTime(d);
} }
while (d.getDate() != check.getDate()) { fixDate(d, check);
d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
}
} }
return d; return d;
} }
fc.addDays = addDays; fc.addDays = addDays;
function fixDate(d, check) { // force d to be on check's YMD, for daylight savings purposes
if (+d) { // prevent infinite looping on invalid dates
while (d.getDate() != check.getDate()) {
d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
}
}
}
function addMinutes(d, n) { function addMinutes(d, n) {
d.setMinutes(d.getMinutes() + n); d.setMinutes(d.getMinutes() + n);
return d; return d;
@ -101,31 +107,50 @@ var parseDate = fc.parseDate = function(s) {
if (s.match(/^\d+$/)) { // a UNIX timestamp if (s.match(/^\d+$/)) { // a UNIX timestamp
return new Date(parseInt(s) * 1000); return new Date(parseInt(s) * 1000);
} }
return parseISO8601(s, true) || new Date(s) || null; return parseISO8601(s, true) || (s ? new Date(s) : null);
} }
return null; return null;
} }
var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) { var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) {
// derived from http://delete.me.uk/2005/03/iso8601.html // derived from http://delete.me.uk/2005/03/iso8601.html
var d = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/); var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/);
if (!d) return null; if (!m) {
var offset = 0; return null;
var date = new Date(d[1], 0, 1); }
if (d[3]) { date.setMonth(d[3] - 1); } var date = new Date(m[1], 0, 1),
if (d[5]) { date.setDate(d[5]); } check = new Date(m[1], 0, 1, 9, 0),
if (d[7]) { date.setHours(d[7]); } offset = 0;
if (d[8]) { date.setMinutes(d[8]); } if (m[3]) {
if (d[10]) { date.setSeconds(d[10]); } date.setMonth(m[3] - 1);
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } check.setMonth(m[3] - 1);
}
if (m[5]) {
date.setDate(m[5]);
check.setDate(m[5]);
}
fixDate(date, check);
if (m[7]) {
date.setHours(m[7]);
}
if (m[8]) {
date.setMinutes(m[8]);
}
if (m[10]) {
date.setSeconds(m[10]);
}
if (m[12]) {
date.setMilliseconds(Number("0." + m[12]) * 1000);
}
fixDate(date, check);
if (!ignoreTimezone) { if (!ignoreTimezone) {
if (d[14]) { if (m[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]); offset = Number(m[16]) * 60 + Number(m[17]);
offset *= ((d[15] == '-') ? 1 : -1); offset *= m[15] == '-' ? 1 : -1;
} }
offset -= date.getTimezoneOffset(); offset -= date.getTimezoneOffset();
} }
return new Date(Number(date) + (offset * 60 * 1000)); return new Date(+date + (offset * 60 * 1000));
} }
var parseTime = fc.parseTime = function(s) { // returns minutes since start of day var parseTime = fc.parseTime = function(s) { // returns minutes since start of day

View file

@ -22,10 +22,10 @@
} }
), ),
$.fullCalendar.gcalFeed( $.fullCalendar.gcalFeed(
"http://www.google.com/calendar/feeds/b62ul6i1vvfh9vqabsal835028%40group.calendar.google.com/public/basic", "http://www.google.com/calendar/feeds/b62ul6i1vvfh9vqabsal835028%40group.calendar.google.com/public/basic", // most recent event in Nov 2009
{ {
editable: true, editable: true,
currentTimezone: 'America/Los_Angeles' //'America/Los Angeles' currentTimezone: 'America/Edmonton' // 'America/Los_Angeles' 'America/Los Angeles'
} }
) )
], ],

View file

@ -0,0 +1,58 @@
<!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'>
// set your time to Tehran time (GMT+03:30)
// (recreated on a Windows XP machine, after restarting)
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
year: 2010,
month: 2,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
},
editable: true,
events: [
{
title: 'Yay Tehran!',
start: '2010-03-21' // should NOT show up on the 20th
//allDay: false // if uncommented, will show 1am
}
]
});
});
</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>

View file

@ -0,0 +1,63 @@
<!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 date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
$(document).ready(function() {
var cal = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
},
loading: function(bool) {
if (bool) {
$('#loading').show();
}else{
$('#loading').hide();
}
}
});
cal.fullCalendar('addEventSource', gcalFeed);
cal.fullCalendar('removeEventSource', gcalFeed);
// events should not be rendered when jsonp returns!
});
</script>
<style>
.red-event a {
background: red;
}
.yellow-event a {
background: yellow;
}
.black-text-event a {
color: #000;
}
button {
font-size: 11px;
}
</style>
</head>
<body style='font-size:12px'>
<div id='loading' style='position:absolute;top:0;left:0;display:none'>loading...</div>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

View file

@ -0,0 +1,53 @@
<!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'>
$(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,
events: [
{
title: 'All Day Event',
start: new Date(y, m, 1),
end: 'h' // shouldn't choke on empty string
}
]
});
});
</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>

46
tests/method_destroy.html Normal file
View file

@ -0,0 +1,46 @@
<!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'>
$(document).ready(function() {
var cal = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
}
});
console.log(cal.data('fullCalendar'));
cal.fullCalendar('destroy');
console.log(cal.data('fullCalendar'));
});
</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'>some text in here</div>
</body>
</html>