version 1.3.1
This commit is contained in:
parent
ef2713aed0
commit
1cb53661fd
15 changed files with 200 additions and 76 deletions
|
@ -1,4 +1,14 @@
|
|||
|
||||
version 1.3.1 (9/30/09)
|
||||
- Important Bugfixes (please upgrade from 1.3!)
|
||||
- When current date was late in the month, for long months, and prev/next buttons
|
||||
were clicked in month-view, some months would be skipped/repeated
|
||||
- In certain time zones, daylight savings time would cause certain days
|
||||
to be misnumbered in month-view
|
||||
- Subtle change in way week interval is chosen when switching from month to basicWeek/basicDay view
|
||||
- Added 'allDayDefault' option
|
||||
- Added 'changeView' and 'render' methods
|
||||
|
||||
version 1.3 (9/21/09)
|
||||
- different 'views': month/basicWeek/basicDay
|
||||
- more flexible 'header' system for buttons
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
body {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
body {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
body {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
body {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
|
||||
text-align: left;
|
||||
}
|
||||
|
|
|
@ -221,10 +221,10 @@ table.fc-header {
|
|||
|
||||
.fc-event,
|
||||
.fc-event a {
|
||||
color: #fff;
|
||||
border-style: solid;
|
||||
border-color: #36c; /* DEFAULT EVENT COLOR */
|
||||
background-color: #36c; /* */
|
||||
border-style: solid;
|
||||
border-color: #36c; /* default BORDER color (probably the same as background-color) */
|
||||
background-color: #36c; /* default BACKGROUND color */
|
||||
color: #fff; /* default TEXT color */
|
||||
}
|
||||
|
||||
/* Use the 'className' CalEvent property and the following
|
||||
|
@ -232,8 +232,9 @@ table.fc-header {
|
|||
*
|
||||
* .my-event-class,
|
||||
* .my-event-class a {
|
||||
* border-color: red;
|
||||
* background-color: red;
|
||||
* border-color: black;
|
||||
* background-color: black;
|
||||
* color: red;
|
||||
* }
|
||||
*/
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ views.month = function(element, options) {
|
|||
render: function(date, delta, fetchEvents) {
|
||||
if (delta) {
|
||||
addMonths(date, delta);
|
||||
date.setDate(1);
|
||||
}
|
||||
var start = this.start = cloneDate(date, true);
|
||||
start.setDate(1);
|
||||
|
|
101
src/main.js
101
src/main.js
|
@ -22,6 +22,8 @@ var defaults = {
|
|||
//disableDragging: false,
|
||||
//disableResizing: false,
|
||||
|
||||
allDayDefault: true,
|
||||
|
||||
// event ajax
|
||||
startParam: 'start',
|
||||
endParam: 'end',
|
||||
|
@ -163,7 +165,7 @@ $.fn.fullCalendar = function(options) {
|
|||
/* View Rendering
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
function switchView(v) {
|
||||
function changeView(v) {
|
||||
if (v != viewName) {
|
||||
prevView = view;
|
||||
if (viewInstances[v]) {
|
||||
|
@ -193,45 +195,47 @@ $.fn.fullCalendar = function(options) {
|
|||
}
|
||||
|
||||
function render(inc) {
|
||||
if (inc || !view.date || +view.date != +date) { // !view.date means it hasn't been rendered yet
|
||||
ignoreWindowResizes = true;
|
||||
view.render(date, inc || 0, function(callback) {
|
||||
// dont refetch if new view contains the same events (or a subset)
|
||||
if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) {
|
||||
fetchEvents(callback);
|
||||
}else{
|
||||
callback(events); // no refetching
|
||||
}
|
||||
});
|
||||
ignoreWindowResizes = false;
|
||||
view.date = cloneDate(date);
|
||||
if (header) {
|
||||
// enable/disable 'today' button
|
||||
var today = new Date();
|
||||
if (today >= view.start && today < view.end) {
|
||||
header.find('div.fc-button-today').addClass(tm + '-state-disabled');
|
||||
}else{
|
||||
header.find('div.fc-button-today').removeClass(tm + '-state-disabled');
|
||||
if (_element.offsetWidth !== 0) { // visible on the screen
|
||||
if (inc || !view.date || +view.date != +date) { // !view.date means it hasn't been rendered yet
|
||||
ignoreWindowResizes = true;
|
||||
view.render(date, inc || 0, function(callback) {
|
||||
// dont refetch if new view contains the same events (or a subset)
|
||||
if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) {
|
||||
fetchEvents(callback);
|
||||
}else{
|
||||
callback(events); // no refetching
|
||||
}
|
||||
});
|
||||
ignoreWindowResizes = false;
|
||||
view.date = cloneDate(date);
|
||||
if (header) {
|
||||
// enable/disable 'today' button
|
||||
var today = new Date();
|
||||
if (today >= view.start && today < view.end) {
|
||||
header.find('div.fc-button-today').addClass(tm + '-state-disabled');
|
||||
}else{
|
||||
header.find('div.fc-button-today').removeClass(tm + '-state-disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (view.sizeDirty) {
|
||||
view.updateSize();
|
||||
view.rerenderEvents();
|
||||
}
|
||||
else if (view.eventsDirty) {
|
||||
// ensure events are rerendered if another view messed with them
|
||||
// pass in 'events' b/c event might have been added/removed
|
||||
view.clearEvents();
|
||||
view.renderEvents(events);
|
||||
}
|
||||
if (header) {
|
||||
// update title text
|
||||
header.find('h2.fc-header-title').html(view.title);
|
||||
}
|
||||
view.sizeDirty = false;
|
||||
view.eventsDirty = false;
|
||||
view.trigger('viewDisplay', _element);
|
||||
}
|
||||
else if (view.sizeDirty) {
|
||||
view.updateSize();
|
||||
view.rerenderEvents();
|
||||
}
|
||||
else if (view.eventsDirty) {
|
||||
// ensure events are rerendered if another view messed with them
|
||||
// pass in 'events' b/c event might have been added/removed
|
||||
view.clearEvents();
|
||||
view.renderEvents(events);
|
||||
}
|
||||
if (header) {
|
||||
// update title text
|
||||
header.find('h2.fc-header-title').html(view.title);
|
||||
}
|
||||
view.sizeDirty = false;
|
||||
view.eventsDirty = false;
|
||||
view.trigger('viewDisplay', _element);
|
||||
}
|
||||
|
||||
// marks other views' events as dirty
|
||||
|
@ -292,7 +296,7 @@ $.fn.fullCalendar = function(options) {
|
|||
reportEvents = function(a) {
|
||||
if (prevViewName == view.name && +prevDate == +date) { // protects from fast switching
|
||||
for (var i=0; i<a.length; i++) {
|
||||
normalizeEvent(a[i]);
|
||||
normalizeEvent(a[i], options);
|
||||
a[i].source = src;
|
||||
}
|
||||
events = events.concat(a);
|
||||
|
@ -348,6 +352,9 @@ $.fn.fullCalendar = function(options) {
|
|||
|
||||
var publicMethods = {
|
||||
|
||||
render: render,
|
||||
changeView: changeView,
|
||||
|
||||
//
|
||||
// Navigation
|
||||
//
|
||||
|
@ -419,15 +426,15 @@ $.fn.fullCalendar = function(options) {
|
|||
e.allDay = event.allDay;
|
||||
e.className = event.className;
|
||||
e.editable = event.editable;
|
||||
normalizeEvent(e);
|
||||
normalizeEvent(e, options);
|
||||
}
|
||||
}
|
||||
normalizeEvent(event);
|
||||
normalizeEvent(event, options);
|
||||
eventsChanged();
|
||||
},
|
||||
|
||||
renderEvent: function(event, stick) { // render a new event
|
||||
normalizeEvent(event);
|
||||
normalizeEvent(event, options);
|
||||
if (!event.source) {
|
||||
if (stick) {
|
||||
(event.source = eventSources[0]).push(event);
|
||||
|
@ -549,7 +556,7 @@ $.fn.fullCalendar = function(options) {
|
|||
buttonClick = publicMethods[buttonNameShort];
|
||||
}
|
||||
else if (views[buttonName]) {
|
||||
buttonClick = function() { switchView(buttonName) };
|
||||
buttonClick = function() { changeView(buttonName) };
|
||||
}
|
||||
if (buttonClick) {
|
||||
if (prevButton) {
|
||||
|
@ -589,7 +596,7 @@ $.fn.fullCalendar = function(options) {
|
|||
}
|
||||
else if (views[buttonName]) {
|
||||
button.click(function() {
|
||||
switchView(buttonName);
|
||||
changeView(buttonName);
|
||||
});
|
||||
}
|
||||
if (prevButton) {
|
||||
|
@ -620,7 +627,7 @@ $.fn.fullCalendar = function(options) {
|
|||
resizeCnt = 0;
|
||||
|
||||
$(window).resize(function() {
|
||||
if (!ignoreWindowResizes) {
|
||||
if (!ignoreWindowResizes && view.date) { // view.date means the view has been rendered
|
||||
var rcnt = ++resizeCnt; // add a delay
|
||||
setTimeout(function() {
|
||||
if (rcnt == resizeCnt) {
|
||||
|
@ -639,7 +646,7 @@ $.fn.fullCalendar = function(options) {
|
|||
|
||||
|
||||
// let's begin...
|
||||
switchView(options.defaultView);
|
||||
changeView(options.defaultView);
|
||||
elementWidth = element.width();
|
||||
|
||||
});
|
||||
|
@ -655,7 +662,7 @@ $.fn.fullCalendar = function(options) {
|
|||
|
||||
var fakeID = 0;
|
||||
|
||||
function normalizeEvent(event) {
|
||||
function normalizeEvent(event, options) {
|
||||
event._id = event._id || (event.id == undefined ? '_fc' + fakeID++ : event.id + '');
|
||||
if (event.date) {
|
||||
if (!event.start) {
|
||||
|
@ -670,7 +677,7 @@ function normalizeEvent(event) {
|
|||
}
|
||||
event._end = event.end ? cloneDate(event.end) : null;
|
||||
if (event.allDay == undefined) {
|
||||
event.allDay = true;
|
||||
event.allDay = options.allDayDefault;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
43
src/util.js
43
src/util.js
|
@ -2,24 +2,45 @@
|
|||
/* Date Math
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
var DAY_MS = 86400000;
|
||||
var DAY_MS = 86400000,
|
||||
HOUR_MS = 3600000;
|
||||
|
||||
function addYears(d, n, keepTime) {
|
||||
d.setFullYear(d.getFullYear() + n);
|
||||
if (keepTime) return d;
|
||||
return clearTime(d);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
function addMonths(d, n, keepTime) {
|
||||
d.setMonth(d.getMonth() + n);
|
||||
if (keepTime) return d;
|
||||
return clearTime(d);
|
||||
function addMonths(d, n, keepTime) { // prevents day overflow/underflow
|
||||
var m = d.getMonth() + n,
|
||||
check = cloneDate(d);
|
||||
check.setDate(1);
|
||||
check.setMonth(m);
|
||||
d.setMonth(m);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
while (d.getMonth() != check.getMonth()) {
|
||||
d.setDate(d.getDate() + (d < check ? 1 : -1));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
function addDays(d, n, keepTime) {
|
||||
d.setDate(d.getDate() + n);
|
||||
if (keepTime) return d;
|
||||
return clearTime(d);
|
||||
function addDays(d, n, keepTime) { // deals with daylight savings
|
||||
var dd = d.getDate() + n,
|
||||
check = cloneDate(d);
|
||||
check.setHours(12); // set to middle of day
|
||||
check.setDate(dd);
|
||||
d.setDate(dd);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
while (d.getDate() != check.getDate()) {
|
||||
d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
function addMinutes(d, n) {
|
||||
|
|
|
@ -131,7 +131,7 @@ var viewMethods = {
|
|||
if (e.end) {
|
||||
e.end = addMinutes(addDays(e.end, days, true), minutes);
|
||||
}
|
||||
normalizeEvent(e);
|
||||
normalizeEvent(e, this.options);
|
||||
}
|
||||
this.eventsChanged = true;
|
||||
},
|
||||
|
@ -143,7 +143,7 @@ var viewMethods = {
|
|||
for (i=0; i<len; i++) {
|
||||
e = events[i];
|
||||
e.end = addMinutes(addDays(this.eventEnd(e), days, true), minutes);
|
||||
normalizeEvent(e);
|
||||
normalizeEvent(e, this.options);
|
||||
}
|
||||
this.eventsChanged = true;
|
||||
},
|
||||
|
|
79
tests/basic.html
Executable file
79
tests/basic.html
Executable file
|
@ -0,0 +1,79 @@
|
|||
<!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'>
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var d = new Date();
|
||||
var y = d.getFullYear();
|
||||
var m = d.getMonth();
|
||||
|
||||
$('#calendar').fullCalendar({
|
||||
editable: true,
|
||||
header: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'month,basicWeek,basicDay'
|
||||
},
|
||||
events: [
|
||||
{
|
||||
id: 1,
|
||||
title: "Long Event",
|
||||
start: new Date(y, m, 6, 14, 0),
|
||||
end: new Date(y, m, 11),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Repeating Event",
|
||||
start: new Date(y, m, 2),
|
||||
allDay: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Repeating Event",
|
||||
start: new Date(y, m, 9),
|
||||
allDay: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Meeting",
|
||||
start: new Date(y, m, 20, 9, 0),
|
||||
allDay: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "Click for Facebook",
|
||||
start: new Date(y, m, 27, 16),
|
||||
end: new Date(y, m, 29),
|
||||
url: "http://facebook.com/",
|
||||
allDay: false
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</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>
|
|
@ -83,10 +83,7 @@ if (_build) {
|
|||
includeJS('../src/gcal.js');
|
||||
}
|
||||
|
||||
var _userAgent = navigator.userAgent.toLowerCase();
|
||||
if (!/mozilla/.test(_userAgent) || /(compatible|webkit)/.test(_userAgent) || !window.console || !window.console.log) {
|
||||
includeJS('firebug-lite/firebug-lite-compressed.js');
|
||||
}
|
||||
includeJS('firebug-lite/firebug-lite-compressed.js');
|
||||
|
||||
window.onload = function() {
|
||||
$('body').append(
|
||||
|
|
|
@ -153,6 +153,12 @@
|
|||
|
||||
<button onclick="cal.fullCalendar('rerenderEvents')">rerender</button>
|
||||
<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
|
||||
<br />
|
||||
|
||||
<button onclick="cal.fullCalendar('changeView', 'month')">change to month</button>
|
||||
<button onclick="cal.fullCalendar('changeView', 'basicWeek')">change to basicWeek</button>
|
||||
<button onclick="cal.fullCalendar('changeView', 'basicDay')">change to basicDay</button>
|
||||
<button onclick="cal.fullCalendar('render')">render</button>
|
||||
|
||||
</p>
|
||||
<div id='loading' style='position:absolute;display:none'>loading...</div>
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
weekMode: 'variable',
|
||||
|
||||
//allDayDefault: false,
|
||||
|
||||
/*
|
||||
titleFormat: {
|
||||
month: "'hey!'"
|
||||
|
@ -45,7 +47,7 @@
|
|||
month: "dddd"
|
||||
},
|
||||
|
||||
timeFormat: "H(:mm)[T]{ - H(:mm)T}",
|
||||
timeFormat: "h(:mm)[T]{ - h(:mm)T}",
|
||||
|
||||
events: [
|
||||
{
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.3
|
||||
1.3.1
|
Loading…
Reference in a new issue