This commit is contained in:
Adam Shaw 2009-10-31 23:51:30 +00:00
parent d1bc5dc529
commit 23d99323cc
16 changed files with 247 additions and 156 deletions

View file

@ -1,4 +1,12 @@
version 1.4.1 (10/31/09)
- can exclude weekends with new 'weekends' option
- gcal feed 'currentTimezone' option
- bugfixes
- year/month/date option sometimes wouldn't set correctly (depending on current date)
- daylight savings issue caused agenda views to start at 1am (for BST users)
- cleanup of gcal.js code
version 1.4 (10/19/09)
- agendaWeek and agendaDay views
- added some options for agenda views:

View file

@ -46,4 +46,23 @@ Here is a list of available options:
* **editable** - whether to allow dragging/resizing (default: ``false``)
* **currentTimezone** - a string like "America/Chicago". Consult http://php.net/manual/en/timezones.php for a full list.
See *gcal.html* in the *examples* directory for a complete example.
Timezones Gotchas
-----------------
Sometimes it can be confusing as to why FullCalendar displays event times differently
than the Google Calendar interface. There are the two factors involved in this:
* **the calendar's timezone**, accessed through "Calendar settings" after clicking the arrow next to the calendar's name
* **your Google Account's timezone**, accessed through the "Settings" link at the top right
of the Google Calendar screen (near the "Sign out" link)
When both timezones are the same, you should have no problems. When they are different, FullCalendar will display
times in the *calendar's* timezone. Thus, times will be different than what you see in the Google Calendar interface
because they are being adjusted to the GMT of the calendar. The solution is to use the ``currentTimezone`` option.
If this is set to the same timezone as your Google Account, all dates should appear consistent.

View file

@ -82,6 +82,9 @@ Basic Options
Determines the default value for each :ref:`CalEvent's <CalEvent>` ``allDay`` property,
when it is unspecified.
**weekends**: Boolean, *Default*: ``true``
Whether to include Saturday/Sunday columns in any of the views.
**weekMode**: String, *Default*: ``'fixed'``
Determines the number of weeks displayed in a month view.
Also determines each week's height. Available options:

View file

@ -23,13 +23,23 @@ views.agendaWeek = function(element, options) {
if (delta) {
addDays(date, delta * 7);
}
var visStart = this.visStart = cloneDate(
this.start = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7))
),
visEnd = this.visEnd = cloneDate(
this.end = addDays(cloneDate(visStart), 7)
);
if (!options.weekends) {
skipWeekend(visStart);
skipWeekend(visEnd, -1, true);
}
this.title = formatDates(
this.start = this.visStart = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7)),
addDays(cloneDate(this.end = this.visEnd = addDays(cloneDate(this.start), 7)), -1),
visStart,
addDays(cloneDate(visEnd), -1),
this.option('titleFormat'),
options
);
this.renderAgenda(7, this.option('columnFormat'), fetchEvents);
this.renderAgenda(options.weekends ? 7 : 5, this.option('columnFormat'), fetchEvents);
}
});
};
@ -39,6 +49,9 @@ views.agendaDay = function(element, options) {
render: function(date, delta, fetchEvents) {
if (delta) {
addDays(date, delta);
if (!options.weekends) {
skipWeekend(date, delta < 0 ? -1 : 1);
}
}
this.title = formatDate(date, this.option('titleFormat'), options);
this.start = this.visStart = cloneDate(date, true);
@ -55,6 +68,7 @@ function Agenda(element, options, methods) {
axisWidth, colWidth, slotHeight,
cachedDaySegs, cachedSlotSegs,
tm, firstDay,
nwe, // no weekends (int)
rtl, dis, dit, // day index sign / translate
// ...
@ -105,6 +119,7 @@ function Agenda(element, options, methods) {
// update option-derived variables
tm = options.theme ? 'ui' : 'fc';
nwe = options.weekends ? 0 : 1;
firstDay = options.firstDay;
if (rtl = options.isRTL) {
dis = -1;
@ -136,6 +151,9 @@ function Agenda(element, options, methods) {
tm + '-state-default' +
"'>" + formatDate(d, colFormat, options) + "</th>";
addDays(d, dis);
if (nwe) {
skipWeekend(d, dis);
}
}
s += "<th class='" + tm + "-state-default'>&nbsp;</th></tr>";
if (options.allDaySlot) {
@ -152,7 +170,7 @@ function Agenda(element, options, methods) {
head.find('td').click(slotClick);
// body
d = new Date(1970, 0, 1);
d = zeroDate();
s = "<table>";
for (i=0; d.getDate() != 2; i++) {
minutes = d.getMinutes();
@ -183,6 +201,9 @@ function Agenda(element, options, methods) {
(+d == +today ? tm + '-state-highlight fc-today' : 'fc-not-today') +
"'><div class='fc-day-content'><div>&nbsp;</div></div></td>";
addDays(d, dis);
if (nwe) {
skipWeekend(d, dis);
}
}
s += "</tr></table></div>";
bg = $(s).appendTo(element);
@ -196,6 +217,9 @@ function Agenda(element, options, methods) {
$(this).text(formatDate(d, colFormat, options));
this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
addDays(d, dis);
if (nwe) {
skipWeekend(d, dis);
}
});
// change classes of background stripes
@ -214,6 +238,9 @@ function Agenda(element, options, methods) {
.removeClass(tm + '-state-highlight');
}
addDays(d, dis);
if (nwe) {
skipWeekend(d, dis);
}
});
}
@ -226,7 +253,7 @@ function Agenda(element, options, methods) {
function resetScroll() {
var d0 = new Date(1970, 0, 1),
var d0 = zeroDate(),
scrollDate = cloneDate(d0);
scrollDate.setHours(options.firstHour);
var go = function() {
@ -394,13 +421,13 @@ function Agenda(element, options, methods) {
}
if (leftRounded) {
className += 'fc-corner-left ';
left = bg.find('td:eq('+(((leftDay-firstDay+colCnt)%colCnt)*dis+dit)+') div div').position().left + axisWidth;
left = bg.find('td:eq('+(((leftDay-Math.max(firstDay,nwe)+colCnt)%colCnt)*dis+dit)+') div div').position().left + axisWidth;
}else{
left = axisWidth;
}
if (rightRounded) {
className += 'fc-corner-right ';
right = bg.find('td:eq('+(((rightDay-firstDay+colCnt)%colCnt)*dis+dit)+') div div');
right = bg.find('td:eq('+(((rightDay-Math.max(firstDay,nwe)+colCnt)%colCnt)*dis+dit)+') div div');
right = right.position().left + right.width() + axisWidth;
}else{
right = axisWidth + bg.width();

View file

@ -16,22 +16,23 @@
options = options || {};
return function(start, end, callback) {
$.getJSON(feedUrl + "?alt=json-in-script&callback=?",
{
var params = {
'start-min': $.fullCalendar.formatDate(start, 'u'),
'start-max': $.fullCalendar.formatDate(end, 'u'),
'singleevents': true,
'max-results': 9999
},
function(data) {
};
if (options.currentTimezone) {
params.ctz = options.currentTimezone.replace(' ', '_');
}
$.getJSON(feedUrl + "?alt=json-in-script&callback=?", params, function(data) {
var events = [];
if (data.feed.entry) {
$.each(data.feed.entry, function(i, entry) {
var startStr = entry['gd$when'][0]['startTime'],
start = $.fullCalendar.parseDate(startStr),
end = $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']),
start = $.fullCalendar.parseISO8601(startStr, true),
end = $.fullCalendar.parseISO8601(entry['gd$when'][0]['endTime'], true),
allDay = startStr.indexOf('T') == -1,
classNames = [],
url;
$.each(entry.link, function() {
if (this.type == 'text/html') {
@ -39,13 +40,13 @@
}
});
if (allDay) {
end = new Date(end - 1); // make inclusive
$.fullCalendar.addDays(end, -1); // make inclusive
}
events.push({
id: entry['gCal$uid']['value'],
title: entry['title']['$t'],
url: url,
start: $.fullCalendar.parseDate(entry['gd$when'][0]['startTime']),
start: start,
end: end,
allDay: allDay,
location: entry['gd$where'][0]['valueString'],

View file

@ -13,22 +13,39 @@ views.month = function(element, options) {
addMonths(date, delta);
date.setDate(1);
}
// start/end
var start = this.start = cloneDate(date, true);
start.setDate(1);
this.title = formatDates(
this.end = addMonths(cloneDate(start), 1);
// visStart/visEnd
var visStart = this.visStart = cloneDate(start),
visEnd = this.visEnd = cloneDate(this.end),
nwe = options.weekends ? 0 : 1;
if (nwe) {
skipWeekend(visStart);
skipWeekend(visEnd, -1, true);
}
addDays(visStart, -((visStart.getDay() - Math.max(options.firstDay, nwe) + 7) % 7));
addDays(visEnd, (7 - visEnd.getDay() + Math.max(options.firstDay, nwe)) % 7);
// row count
var rowCnt = Math.round((visEnd - visStart) / (DAY_MS * 7));
if (options.weekMode == 'fixed') {
addDays(visEnd, (6 - rowCnt) * 7);
rowCnt = 6;
}
// title
this.title = formatDate(
start,
addDays(cloneDate(this.end = addMonths(cloneDate(start), 1)), -1),
this.option('titleFormat'),
options
);
addDays(this.visStart = cloneDate(start), -((start.getDay() - options.firstDay + 7) % 7));
addDays(this.visEnd = cloneDate(this.end), (7 - this.visEnd.getDay() + options.firstDay) % 7);
var rowCnt = Math.round((this.visEnd - this.visStart) / (DAY_MS * 7));
if (options.weekMode == 'fixed') {
addDays(this.visEnd, (6 - rowCnt) * 7);
rowCnt = 6;
}
this.renderGrid(rowCnt, 7, this.option('columnFormat'), true, fetchEvents);
// render
this.renderGrid(
rowCnt, options.weekends ? 7 : 5,
this.option('columnFormat'),
true,
fetchEvents
);
}
});
}
@ -39,13 +56,28 @@ views.basicWeek = function(element, options) {
if (delta) {
addDays(date, delta * 7);
}
var visStart = this.visStart = cloneDate(
this.start = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7))
),
visEnd = this.visEnd = cloneDate(
this.end = addDays(cloneDate(visStart), 7)
);
if (!options.weekends) {
skipWeekend(visStart);
skipWeekend(visEnd, -1, true);
}
this.title = formatDates(
this.start = this.visStart = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7)),
addDays(cloneDate(this.end = this.visEnd = addDays(cloneDate(this.start), 7)), -1),
visStart,
addDays(cloneDate(visEnd), -1),
this.option('titleFormat'),
options
);
this.renderGrid(1, 7, this.option('columnFormat'), false, fetchEvents);
this.renderGrid(
1, options.weekends ? 7 : 5,
this.option('columnFormat'),
false,
fetchEvents
);
}
});
};
@ -55,6 +87,9 @@ views.basicDay = function(element, options) {
render: function(date, delta, fetchEvents) {
if (delta) {
addDays(date, delta);
if (!options.weekends) {
skipWeekend(date, delta < 0 ? -1 : 1);
}
}
this.title = formatDate(date, this.option('titleFormat'), options);
this.start = this.visStart = cloneDate(date, true);
@ -73,6 +108,7 @@ var tdHeightBug, rtlLeftDiff;
function Grid(element, options, methods) {
var tm, firstDay,
nwe, // no weekends (int)
rtl, dis, dit, // day index sign / translate
rowCnt, colCnt,
colWidth,
@ -116,6 +152,7 @@ function Grid(element, options, methods) {
// update option-derived variables
tm = options.theme ? 'ui' : 'fc';
nwe = options.weekends ? 0 : 1;
firstDay = options.firstDay;
if (rtl = options.isRTL) {
dis = -1;
@ -141,6 +178,9 @@ function Grid(element, options, methods) {
(i==dit ? ' fc-leftmost' : '') +
"'>" + formatDate(d, colFormat, options) + "</th>";
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
}
thead = $(s + "</tr></thead>").appendTo(table);
@ -160,6 +200,9 @@ function Grid(element, options, methods) {
(showNumbers ? "<div class='fc-day-number'>" + d.getDate() + "</div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div></td>";
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
}
s += "</tr>";
}
@ -187,6 +230,9 @@ function Grid(element, options, methods) {
"<div class='fc-day-content'><div>&nbsp;</div></div>" +
"</td>";
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
}
s += "</tr>";
}
@ -216,6 +262,9 @@ function Grid(element, options, methods) {
}
td.find('div.fc-day-number').text(d.getDate());
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
});
if (rowCnt == 1) { // more changes likely (week or day view)
@ -226,6 +275,9 @@ function Grid(element, options, methods) {
$(this).text(formatDate(d, colFormat, options));
this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
});
// redo cell day-of-weeks
@ -233,6 +285,9 @@ function Grid(element, options, methods) {
tbody.find('td').each(function() {
this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
addDays(d, 1);
if (nwe) {
skipWeekend(d);
}
});
}
@ -246,9 +301,10 @@ function Grid(element, options, methods) {
function dayClick(ev) {
var date = addDays(
var n = parseInt(this.className.match(/fc\-day(\d+)/)[1]),
date = addDays(
cloneDate(view.visStart),
parseInt(this.className.match(/fc\-day(\d+)/)[1])
Math.floor(n/colCnt) * 7 + n % colCnt
);
view.trigger('dayClick', this, date, true, ev);
}
@ -359,10 +415,10 @@ function Grid(element, options, methods) {
event = seg.event;
className = 'fc-event fc-event-hori ';
startElm = seg.isStart ?
tr.find('td:eq('+((seg.start.getDay()-firstDay+colCnt)%colCnt)+') div div') :
tr.find('td:eq('+((seg.start.getDay()-Math.max(firstDay,nwe)+colCnt)%colCnt)+') div div') :
tbody;
endElm = seg.isEnd ?
tr.find('td:eq('+((seg.end.getDay()-firstDay+colCnt-1)%colCnt)+') div div') :
tr.find('td:eq('+((seg.end.getDay()-Math.max(firstDay,nwe)+colCnt-1)%colCnt)+') div div') :
tbody;
if (rtl) {
left = endElm.position().left;

View file

@ -16,6 +16,7 @@ var defaults = {
center: '',
right: 'today prev,next'
},
weekends: true,
// editing
//editable: false,
@ -159,10 +160,14 @@ $.fn.fullCalendar = function(options) {
var date = new Date(),
viewName, view, // the current view
viewInstances = {};
if (options.year != undefined) {
date.setYear(options.year);
if (options.year != undefined && options.year != date.getFullYear()) {
date.setDate(1);
date.setMonth(0);
date.setFullYear(options.year);
}
if (options.month != undefined) {
if (options.month != undefined && options.month != date.getMonth()) {
date.setDate(1);
date.setMonth(options.month);
}
if (options.date != undefined) {
@ -396,7 +401,7 @@ $.fn.fullCalendar = function(options) {
date = cloneDate(year); // provided 1 argument, a Date
}else{
if (year != undefined) {
date.setYear(year);
date.setFullYear(year);
}
if (month != undefined) {
date.setMonth(month);

View file

@ -47,6 +47,7 @@ function addDays(d, n, keepTime) { // deals with daylight savings
}
return d;
}
fc.addDays = addDays;
function addMinutes(d, n) {
d.setMinutes(d.getMinutes() + n);
@ -68,6 +69,22 @@ function cloneDate(d, dontKeepTime) {
return new Date(+d);
}
function zeroDate() { // returns a Date with time 00:00:00 and dateOfMonth=1
var i=0, d;
do {
d = new Date(1970, i++, 1);
} while (d.getHours() != 0);
return d;
}
function skipWeekend(date, inc, excl) {
inc = inc || 1;
while (date.getDay()==0 || (excl && date.getDay()==1 || !excl && date.getDay()==6)) {
addDays(date, inc);
}
return date;
}
/* Date Parsing

View file

@ -4,13 +4,9 @@
<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();
$(document).ready(function() {
$('#calendar').fullCalendar({
//weekends: false,
header: {
left: 'prev,next today',
center: 'title',
@ -25,59 +21,19 @@
className: ['holiday']
}
),
/*$.fullCalendar.gcalFeed(
"http://www.google.com/calendar/feeds/mike%40maddogsportsbar.com/private-4ad75f9427058f8fe6525c0857c59fbc/basic",
$.fullCalendar.gcalFeed(
"http://www.google.com/calendar/feeds/b62ul6i1vvfh9vqabsal835028%40group.calendar.google.com/public/basic",
{
className: 'maddog'
editable: true,
currentTimezone: 'America/Los_Angeles' //'America/Los Angeles'
}
),*/
[
{
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
},
{
title: 'Meeting',
start: new Date(y, m, d, 10, 30),
allDay: false
},
{
title: 'Lunch',
start: new Date(y, m, d, 12, 0),
end: new Date(y, m, d, 14, 0),
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/'
)
],
eventClick: function(event) {
console.log(event.start);
console.log(event.end);
return false;
}
]
]
});
});
@ -92,24 +48,6 @@
color: yellow;
}
.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'>

View file

@ -21,6 +21,7 @@
isRTL: true,
firstDay: 1,
//weekends: false,
monthNames: ["januari", "februari", "maart", "april", "mei", "juni","juli", "augustus", "september", "oktober", "november", "december"],
monthNamesShort: ["jan", "feb", "maa", "apr", "mei", "jun", "jul", "aug","sep", "okt", "nov", "dec"],

View file

@ -14,6 +14,7 @@
$(document).ready(function() {
cal = $('#calendar').fullCalendar({
editable: true,
weekends: false,
header: {
left: 'prev,next today',
center: 'title',

View file

@ -16,9 +16,18 @@
//month: 0,
//date: 1,
/*
//previous bug, should NOT be march
year: 2009,
month: 1,
date: 15,
*/
//defaultView: 'basicDay',
//aspectRatio: 1,
//aspectRatio: 2,
weekends: false,
header: {
@ -34,7 +43,7 @@
//dragOpacity: { agendaWeek: .1 },
dragRevertDuration: 100,
weekMode: 'variable',
//weekMode: 'variable',
//allDaySlot: false,
allDayText: 'ALLDAY',

View file

@ -15,6 +15,7 @@
theme: true,
editable: true,
//weekends: false,
header: {
left: 'prevYear,prev,next,nextYear today',

View file

@ -11,6 +11,8 @@
$(document).ready(function() {
$('#calendar').fullCalendar({
weekends: false,
header: {
left: 'prev,next today',
center: 'title',
@ -21,6 +23,8 @@
viewDisplay: function(view) {
console.log('viewDisplay');
console.log(view.start + ' - ' + view.end);
console.log(view.visStart + ' - ' + view.visEnd);
//console.log(view);
//console.log(this);
},
@ -33,7 +37,8 @@
},
dayClick: function(dayDate, allDay, ev, view) {
console.log('dayClick - ' + dayDate + ', allDay:' + allDay + ' - ' + view.title);
alert(dayDate);
//console.log('dayClick - ' + dayDate + ', allDay:' + allDay + ' - ' + view.title);
//console.log(ev);
//console.log(this);
},

View file

@ -1 +1 @@
1.4
1.4.1