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);
}); });

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' +

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,7 +338,8 @@ $.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
$.inArray(src, eventSources) != -1) { // makes sure source hasn't been removed
for (var i=0; i<a.length; i++) { for (var i=0; i<a.length; i++) {
normalizeEvent(a[i], options); normalizeEvent(a[i], options);
a[i].source = src; a[i].source = src;
@ -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>