This commit is contained in:
Adam Shaw 2009-09-21 04:57:20 +00:00
parent fc27aedcca
commit 363ad2c67f
23 changed files with 1255 additions and 1122 deletions

View file

@ -5,7 +5,8 @@ version 1.3 (9/15/09)
- themable by jQuery UI themes
- resizable events (require jQuery UI resizable plugin)
- rescoped & rewritten CSS, enhanced default look
- reworked options & API to support multiple views / be consistent with jQuery UI datepicker
- cleaner css & rendering techniques for right-to-left
- reworked options & API to support multiple views / be consistent with jQuery UI
- refactoring of entire codebase
- broken into different JS & CSS files, assembled w/ build scripts
- new test suite for new features, uses firebug-lite
@ -37,10 +38,12 @@ version 1.3 (9/15/09)
+ eventResize
x monthDisplay -> viewDisplay
x resize -> windowResize
'eventDrop' params changed, can revert if ajax cuts out
- CalEvent Properties
x showTime -> allDay
x draggable -> editable
'end' is now INCLUSIVE when allDay=true
'url' now produces a real <a> tag, more native clicking/tab behavior
- Methods:
+ renderEvent
x prevMonth -> prev
@ -54,6 +57,8 @@ version 1.3 (9/15/09)
'formatDates' added to support date-ranges
- Google Calendar Options:
x draggable -> editable
- Bugfixes
- gcal extension fetched 25 results max, now fetches all
version 1.2.1 (6/29/09)
- bugfixes

View file

@ -27,8 +27,8 @@ Locale Options
Text that will be displayed on buttons of the header. Default::
{
prev: '&#9668;', // left triangle
next: '&#9658;', // right triangle
prev: '&nbsp;&#9668;&nbsp;', // left triangle
next: '&nbsp;&#9658;&nbsp;', // right triangle
today: 'today',
month: 'month',
week: 'week',

View file

@ -19,12 +19,12 @@ jQuery object:
``month`` is 0-based, meaning January=0, February=1, etc.
**moveDate** - .fullCalendar('moveDate', *years, [months, [days]]*)
**incrementDate** - .fullCalendar('incrementDate', *years, [months, [days]]*)
Moves the calendar forward/backward an arbitrary amount of time.
**updateEvent** - .fullCalendar('updateEvent', *calEvent*)
Reports changes about a modified :ref:`CalEvent <CalEvent>`. This will cause the event
to be rerendered on the calendar.
Reports changes to a :ref:`CalEvent's <CalEvent>` standard properties.
This will cause the event to be rerendered on the calendar.
If there are repeating events on the calendar with the
same ID, these events will be changed as well.

View file

@ -57,7 +57,7 @@ always available (:ref:`more below <view-object>`).
``this`` is set to the event's element
**eventDrop**: function(*calEvent, dayDelta, minuteDelta, jsEvent, ui, view*)
**eventDrop**: function(*calEvent, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view*)
Triggered when dragging stops and the event has moved to a *different* day.
``dayDelta`` holds the number of days the event was moved forward (a positive number)
@ -70,6 +70,9 @@ always available (:ref:`more below <view-object>`).
repeating events. If updating a remote database, just add these values to the
start and end times of all events with the given ``calEvent.id``
``revertFunc`` is a function that, if called, reverts the event's start/end date to
the values *before* the drag. This is useful if an ajax call should fail.
**eventResizeStart**, **eventResizeStop**: function(*calEvent, jsEvent, ui, view*)
Triggered before/after an event is resized (but not necessarily changed).
``calEvent`` holds that event's information (date, title, etc).
@ -78,7 +81,7 @@ always available (:ref:`more below <view-object>`).
``this`` is set to the event's element
**eventResize**: function(*calEvent, dayDelta, minuteDelta, jsEvent, ui, view*)
**eventResize**: function(*calEvent, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view*)
Triggered when an event is resized and *changed in duration*.
``dayDelta`` holds the number of days the event's end time was moved
@ -87,6 +90,9 @@ always available (:ref:`more below <view-object>`).
``minuteDelta`` will always be ``0`` and is reserved for a future release
of FullCalendar where there will be an agenda view.
``revertFunc`` is a function that, if called, reverts the event's start/end date to
the values *before* the drag. This is useful if an ajax call should fail.
.. _view-object:

View file

@ -4,7 +4,6 @@
<!--<src>-->
<link rel='stylesheet' type='text/css' href='../src/css/main.css' />
<link rel='stylesheet' type='text/css' href='../src/css/grid.css' />
<link rel='stylesheet' type='text/css' href='../src/css/agenda.css' />
<script type='text/javascript' src='../src/jquery/jquery.js'></script>
<script type='text/javascript' src='../src/jquery/ui.core.js'></script>
<script type='text/javascript' src='../src/jquery/ui.draggable.js'></script>

View file

@ -4,7 +4,6 @@
<!--<src>-->
<link rel='stylesheet' type='text/css' href='../src/css/main.css' />
<link rel='stylesheet' type='text/css' href='../src/css/grid.css' />
<link rel='stylesheet' type='text/css' href='../src/css/agenda.css' />
<script type='text/javascript' src='../src/jquery/jquery.js'></script>
<script type='text/javascript' src='../src/main.js'></script>
<script type='text/javascript' src='../src/grid.js'></script>

View file

@ -4,7 +4,6 @@
<!--<src>-->
<link rel='stylesheet' type='text/css' href='../src/css/main.css' />
<link rel='stylesheet' type='text/css' href='../src/css/grid.css' />
<link rel='stylesheet' type='text/css' href='../src/css/agenda.css' />
<script type='text/javascript' src='../src/jquery/jquery.js'></script>
<script type='text/javascript' src='../src/jquery/ui.core.js'></script>
<script type='text/javascript' src='../src/jquery/ui.draggable.js'></script>

View file

@ -5,7 +5,6 @@
<!--<src>-->
<link rel='stylesheet' type='text/css' href='../src/css/main.css' />
<link rel='stylesheet' type='text/css' href='../src/css/grid.css' />
<link rel='stylesheet' type='text/css' href='../src/css/agenda.css' />
<script type='text/javascript' src='../src/jquery/jquery.js'></script>
<script type='text/javascript' src='../src/jquery/ui.core.js'></script>
<script type='text/javascript' src='../src/jquery/ui.draggable.js'></script>
@ -36,6 +35,11 @@
$('#calendar').fullCalendar({
theme: true,
editable: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
events: [
{
id: 1,

View file

@ -4,7 +4,6 @@
<!--<src>-->
<link rel='stylesheet' type='text/css' href='../src/css/main.css' />
<link rel='stylesheet' type='text/css' href='../src/css/grid.css' />
<link rel='stylesheet' type='text/css' href='../src/css/agenda.css' />
<script type='text/javascript' src='../src/jquery/jquery.js'></script>
<script type='text/javascript' src='../src/jquery/ui.core.js'></script>
<script type='text/javascript' src='../src/jquery/ui.draggable.js'></script>
@ -86,6 +85,7 @@
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
text-align: left;
}
#calendar {

View file

@ -1,4 +1,15 @@
.fc-event,
.fc-event a,
.fc-agenda .fc-event-time {
color: #fff;
border-style: solid;
border-color: blue;
background-color: blue;
}
/* header styles */

View file

@ -15,8 +15,8 @@
border-width: 1px 0 0 1px;
}
.fc-grid th.fc-left,
.fc-grid td.fc-left {
.fc-grid th.fc-leftmost,
.fc-grid td.fc-leftmost {
border-left: 0;
}
@ -27,7 +27,10 @@
.fc-grid .fc-other-month .fc-day-number {
opacity: 0.3;
filter: alpha(opacity=30);
filter: alpha(opacity=30); /* for IE */
/* opacity with small font can sometimes look too faded
might want to set the 'color' property instead
making day-numbers bold also fixes the problem */
}
.fc-grid .fc-day-content {
@ -54,3 +57,4 @@
.fc-rtl .fc-grid .fc-event-time {
float: right;
}

View file

@ -1,3 +1,12 @@
/*
* FullCalendar Stylesheet
*
* Feel free to edit this file to customize the look of FullCalendar.
* When upgrading to newer versions, please upgrade this file as well,
* porting over any customizations afterwards.
*
*/
.fc,
.fc .fc-header,
@ -63,25 +72,60 @@ table.fc-header {
direction: rtl;
}
/* button rounded corners */
/* Buttons
------------------------------------------------------------------------*/
.fc-header .fc-state-default,
.fc-header .ui-state-default {
margin-bottom: 1em;
cursor: pointer;
}
.fc-header .fc-state-default {
border-width: 1px 0;
padding: 0 1px;
}
.fc-header .fc-state-default,
.fc-header .fc-state-default a {
border-style: solid;
}
.fc-header .fc-state-default a {
display: block;
position: relative;
margin: 0 -1px;
border-width: 0 1px;
margin: 0 -1px;
width: 100%;
text-decoration: none;
}
.fc-header .fc-state-default span {
display: block;
border-style: solid;
border-width: 1px 0 1px 1px;
padding: 3px 5px;
}
.fc-header .ui-state-default {
padding: 4px 6px;
}
/* for adjacent buttons */
.fc-header .fc-no-right {
padding-right: 0;
border-right: 0;
}
.fc-header .ui-no-right {
border-right: 0;
}
/* for fake rounded corners */
.fc-header .fc-corner-left {
margin-left: 1px;
padding-left: 0;
@ -92,73 +136,45 @@ table.fc-header {
padding-right: 0;
}
.fc-header .fc-no-left {
padding-left: 0;
}
.fc-header .ui-no-left {
border-left: 0;
}
/* default button state */
.fc-header .fc-state-default,
.fc-header .ui-state-default {
margin-bottom: 10px;
cursor: pointer;
}
/* DEFAULT button COLORS */
.fc-header .fc-state-default,
.fc-header .fc-state-default a {
border-style: solid;
border-color: #6E6E6E;
border-color: #777; /* outer border */
color: #333;
}
.fc-header .fc-state-default span {
border-width: 1px 0 0 1px;
border-style: solid;
border-color: #fff;
background: #F0F0F0;
border-color: #fff #fff #cecece; /* inner border */
background: #e8e8e8;
}
.fc-header .fc-state-default span,
.fc-header .ui-state-default {
padding: 4px 6px;
}
/* active button state */
/* PRESSED button COLORS (down and active) */
.fc-header .fc-state-active a {
color: #fff;
}
.fc-header .fc-state-down span,
.fc-header .fc-state-active span {
background: #787878;
border-color: #777;
background: #888;
border-color: #808080 #808080 #909090; /* inner border */
}
/* down button state */
.fc-header .fc-state-down span {
background: #787878;
border-color: #777;
}
/* disabled button state */
.fc-header .fc-state-disabled,
.fc-header .fc-state-disabled a {
border-color: #ccc;
}
/* DISABLED button COLORS */
.fc-header .fc-state-disabled a {
color: #999;
}
.fc-header .fc-state-disabled,
.fc-header .fc-state-disabled a {
border-color: #ccc; /* outer border */
}
.fc-header .fc-state-disabled span {
border-color: #fff;
background: #F0F0F0;
border-color: #fff #fff #f0f0f0; /* inner border */
background: #f0f0f0;
}
@ -180,15 +196,15 @@ table.fc-header {
}
.fc-content .fc-state-highlight { /* today */
background: #FFFFCC;
background: #ffc;
}
.fc-content td.fc-not-today {
.fc-content .fc-not-today {
background: none;
}
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
background: #ADDBFF;
background: #9cf;
opacity: .2;
filter: alpha(opacity=20); /* for IE */
}
@ -204,40 +220,63 @@ table.fc-header {
------------------------------------------------------------------------*/
.fc-event,
.fc-event a,
.fc-agenda .fc-event-time {
.fc-event a {
color: #fff;
border-style: solid;
border-color: blue;
background-color: blue;
border-color: #36c; /* DEFAULT EVENT COLOR */
background-color: #36c; /* */
}
/* Use the 'className' CalEvent property and the following
* example CSS to change event color on a per-event basis:
*
* .my-event-class,
* .my-event-class a {
* border-color: red;
* background-color: red;
* }
*/
.fc-event a {
overflow: hidden;
font-size: 11px;
font-size: .85em;
text-decoration: none;
text-align: left;
cursor: pointer;
}
.fc-event-editable {
cursor: pointer;
}
.fc-event-time,
.fc-event-title {
padding: 0 1px;
}
.fc-event a { /* prep for rounded corners */
/* for fake rounded corners */
.fc-event a {
display: block;
position: relative;
width: 100%;
height: 100%;
}
/* right-to-left */
.fc-rtl .fc-event a {
text-align: right;
}
/* resizable */
.fc .ui-resizable-handle {
display: block;
position: absolute;
z-index: 99999;
border: 0 !important; /* important overrides pre jquery ui 1.7 styles */
background: url(data:image/gif;base64,AAAA) !important; /* hover fix for IE */
}
@ -254,6 +293,8 @@ table.fc-header {
border-width: 0;
}
/* for fake rounded corners */
.fc-content .fc-corner-left {
margin-left: 1px;
}
@ -279,22 +320,19 @@ table.fc-header {
}
.fc-event-hori .ui-resizable-e {
top: 0 !important;
right: -5px !important;
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
right: -3px !important;
width: 7px !important;
height: 100% !important;
border: 0 !important;
background: none !important;
cursor: e-resize;
}
.fc-event-hori .ui-resizable-w {
top: 0 !important;
left: -5px !important;
left: -3px !important;
width: 7px !important;
height: 100% !important;
border: 0 !important;
background: none !important;
cursor: w-resize;
}

View file

@ -1,3 +1,13 @@
/*
* FullCalendar Google Calendar Extension
*
* Copyright (c) 2009 Adam Shaw
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function($) {
$.fullCalendar.gcalFeed = function(feedUrl, options) {
@ -11,48 +21,40 @@
'start-min': $.fullCalendar.formatDate(start, 'u'),
'start-max': $.fullCalendar.formatDate(end, 'u'),
'singleevents': true,
'max-results': 1000
'max-results': 9999
},
function(data) {
var events = [];
if (data.feed.entry)
if (data.feed.entry) {
$.each(data.feed.entry, function(i, entry) {
var url;
$.each(entry['link'], function(j, link) {
if (link.type == 'text/html') {
url = link.href;
var startStr = entry['gd$when'][0]['startTime'],
start = $.fullCalendar.parseDate(startStr),
end = $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']),
allDay = startStr.indexOf('T') == -1,
classNames = [],
url;
$.each(entry.link, function() {
if (this.type == 'text/html') {
url = this.href;
}
});
var startStr = entry['gd$when'][0]['startTime'];
var start = $.fullCalendar.parseDate(startStr);
var end = $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']);
var allDay = startStr.indexOf('T') == -1;
var classNames = [];
if (allDay) {
end = new Date(end - 1); // make in inclusive
}else{
classNames.push('fc-event-nobg');
}
if (options.className) {
if (typeof options.className == 'string') {
classNames.push(options.className);
}else{
classNames = classNames.concat(options.className);
}
end = new Date(end - 1); // make inclusive
}
events.push({
id: entry['gCal$uid']['value'],
url: url,
title: entry['title']['$t'],
url: url,
start: $.fullCalendar.parseDate(entry['gd$when'][0]['startTime']),
end: end,
allDay: allDay,
location: entry['gd$where'][0]['valueString'],
description: entry['content']['$t'],
allDay: allDay,
className: classNames,
className: options.className,
editable: options.editable || false
});
});
}
callback(events);
});
}

View file

@ -1,4 +1,7 @@
/* Grid-based Views: month, basicWeek, basicDay
-----------------------------------------------------------------------------*/
setDefaults({
weekMode: 'fixed'
});
@ -17,8 +20,8 @@ views.month = function(element, options) {
strProp(options.titleFormat, 'month'),
options
);
addDays(this.visStart = cloneDate(start), -((start.getDay() - options.weekStart + 7) % 7));
addDays(this.visEnd = cloneDate(this.end), (7 - this.visEnd.getDay() + options.weekStart) % 7);
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);
@ -36,7 +39,7 @@ views.basicWeek = function(element, options) {
addDays(date, delta * 7);
}
this.title = formatDates(
this.start = this.visStart = addDays(cloneDate(date), -((date.getDay() - options.weekStart + 7) % 7)),
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),
strProp(options.titleFormat, 'week'),
options
@ -61,18 +64,16 @@ views.basicDay = function(element, options) {
}
// flags for [Opera] rendering bugs
// rendering bugs
var tdTopBug, trTopBug, tbodyTopBug, sniffBugs = true;
var tdHeightBug;
var sniffedEventLeftBug, eventLeftDiff=0;
var tdTopBug, trTopBug, tbodyTopBug,
tdHeightBug,
rtlLeftDiff;
function Grid(element, options, methods) {
var tm, weekStart,
var tm, firstDay,
rtl, dis, dit, // day index sign / translate
rowCnt, colCnt,
colWidth,
@ -85,10 +86,10 @@ function Grid(element, options, methods) {
renderEvents: renderEvents,
rerenderEvents: rerenderEvents,
updateSize: updateSize,
defaultEventEnd: function(event) {
defaultEventEnd: function(event) { // calculates an end if event doesnt have one, mostly for resizing
return cloneDate(event.start);
},
visEventEnd: function(event) {
visEventEnd: function(event) { // returns exclusive 'visible' end, for rendering
if (event.end) {
var end = cloneDate(event.end);
return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
@ -120,7 +121,7 @@ function Grid(element, options, methods) {
// update option-derived variables
tm = options.theme ? 'ui' : 'fc';
weekStart = options.weekStart;
firstDay = options.firstDay;
if (rtl = options.isRTL) {
dis = -1;
dit = colCnt - 1;
@ -138,7 +139,7 @@ function Grid(element, options, methods) {
s += "<th class='fc-" +
dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default' +
(i==dit ? ' fc-left' : '') +
(i==dit ? ' fc-leftmost' : '') +
"'>" + formatDate(d, colFormat, options) + "</th>";
addDays(d, 1);
}
@ -152,7 +153,7 @@ function Grid(element, options, methods) {
s += "<td class='fc-" +
dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default fc-day' + (i*colCnt+j) +
(j==dit ? ' fc-left' : '') +
(j==dit ? ' fc-leftmost' : '') +
(rowCnt>1 && d.getMonth() != month ? ' fc-other-month' : '') +
(+d == +today ?
' fc-today '+tm+'-state-highlight' :
@ -182,7 +183,7 @@ function Grid(element, options, methods) {
s += "<td class='fc-" +
dayIDs[d.getDay()] + ' ' + // needs to be first
tm + '-state-default fc-new fc-day' + (i*colCnt+j) +
(j==dit ? ' fc-left' : '') + "'>" +
(j==dit ? ' fc-leftmost' : '') + "'>" +
(showNumbers ? "<div class='fc-day-number'></div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div>" +
"</td>";
@ -218,7 +219,7 @@ function Grid(element, options, methods) {
addDays(d, 1);
});
if (rowCnt == 1) { // more likely changed (week or day view)
if (rowCnt == 1) { // more changes likely (week or day view)
// redo column header text and class
d = cloneDate(view.visStart);
@ -245,16 +246,25 @@ function Grid(element, options, methods) {
};
function dayClick() {
var date = addDays(
cloneDate(view.visStart),
parseInt(this.className.match(/fc\-day(\d+)/)[1])
);
view.trigger('dayClick', this, date);
}
function updateSize() {
var width = element.width();
var height = Math.round(width / options.aspectRatio);
var width = element.width(),
height = Math.round(width / options.aspectRatio),
leftTDs = tbody.find('tr td:first-child'),
tbodyHeight = height - thead.height(),
rowHeight1, rowHeight2;
setOuterWidth(
thead.find('th').slice(0, -1),
colWidth = Math.floor(width / colCnt)
);
var leftTDs = tbody.find('tr td:first-child');
var tbodyHeight = height - thead.height();
var rowHeight1, rowHeight2;
if (options.weekMode == 'variable') {
rowHeight1 = rowHeight2 = Math.floor(tbodyHeight / (rowCnt==1 ? 2 : 6));
}else{
@ -262,18 +272,19 @@ function Grid(element, options, methods) {
rowHeight2 = tbodyHeight - rowHeight1*(rowCnt-1);
}
if (sniffBugs) {
if (tdTopBug == undefined) {
// nasty bugs in opera 9.25
// position() returning relative to direct parent
var tr = tbody.find('tr:first');
var td = tr.find('td:first');
var trTop = tr.position().top;
var tdTop = td.position().top;
var tr = tbody.find('tr:first'),
td = tr.find('td:first'),
trTop = tr.position().top,
tdTop = td.position().top;
tdTopBug = tdTop < 0;
trTopBug = trTop != tdTop;
tbodyTopBug = tbody.position().top != trTop;
sniffBugs = false;
//
}
if (tdHeightBug == undefined) {
// bug in firefox where cell height includes padding
td.height(rowHeight1);
tdHeightBug = rowHeight1 != td.height();
}
@ -285,8 +296,6 @@ function Grid(element, options, methods) {
setOuterHeight(leftTDs.slice(0, -1), rowHeight1);
setOuterHeight(leftTDs.slice(-1), rowHeight2);
}
//alert(tbodyHeight + ' === ' + tbody.height());
}
@ -302,7 +311,6 @@ function Grid(element, options, methods) {
function rerenderEvents(skipCompile) {
//console.log('rerender events');
view.clearEvents();
if (skipCompile) {
renderSegs(cachedSegs);
@ -336,7 +344,7 @@ function Grid(element, options, methods) {
k, seg,
event,
eventClasses,
startE, endE,
startElm, endElm,
left1, left2,
eventElement, eventAnchor,
triggerRes;
@ -346,9 +354,15 @@ function Grid(element, options, methods) {
td = tr.find('td:first');
innerDiv = td.find('div.fc-day-content div').css('position', 'relative');
top = innerDiv.position().top;
if (tdTopBug) top -= td.position().top;
if (trTopBug) top += tr.position().top;
if (tbodyTopBug) top += tbody.position().top;
if (tdTopBug) {
top -= td.position().top;
}
if (trTopBug) {
top += tr.position().top;
}
if (tbodyTopBug) {
top += tbody.position().top;
}
weekHeight = 0;
for (j=0; j<levels.length; j++) {
segs = levels[j];
@ -361,15 +375,15 @@ function Grid(element, options, methods) {
eventClasses = eventClasses.split(' ');
}
eventClasses.push('fc-event', 'fc-event-hori');
startE = seg.isStart ?
tr.find('td:eq('+((seg.start.getDay()-weekStart+colCnt)%colCnt)+') div.fc-day-content div') :
startElm = seg.isStart ?
tr.find('td:eq('+((seg.start.getDay()-firstDay+colCnt)%colCnt)+') div.fc-day-content div') :
tbody;
endE = seg.isEnd ?
tr.find('td:eq('+((seg.end.getDay()-weekStart+colCnt-1)%colCnt)+') div.fc-day-content div') :
endElm = seg.isEnd ?
tr.find('td:eq('+((seg.end.getDay()-firstDay+colCnt-1)%colCnt)+') div.fc-day-content div') :
tbody;
if (rtl) {
left1 = endE.position().left;
left2 = startE.position().left + startE.width();
left1 = endElm.position().left;
left2 = startElm.position().left + startElm.width();
if (seg.isStart) {
eventClasses.push('fc-corner-right');
}
@ -377,8 +391,8 @@ function Grid(element, options, methods) {
eventClasses.push('fc-corner-left');
}
}else{
left1 = startE.position().left;
left2 = endE.position().left + endE.width();
left1 = startElm.position().left;
left2 = endElm.position().left + endElm.width();
if (seg.isStart) {
eventClasses.push('fc-corner-left');
}
@ -388,7 +402,7 @@ function Grid(element, options, methods) {
}
eventElement = $("<div class='" + eventClasses.join(' ') + "'/>")
.append(eventAnchor = $("<a/>")
.append(event.allDay ? null :
.append(event.allDay || !seg.isStart ? null :
$("<span class='fc-event-time'/>")
.html(formatDates(event.start, event.end, options.timeFormat, options)))
.append($("<span class='fc-event-title'/>")
@ -405,22 +419,20 @@ function Grid(element, options, methods) {
.css({
position: 'absolute',
top: top,
left: left1 + eventLeftDiff,
zIndex: 3
left: left1 + (rtlLeftDiff||0),
zIndex: 2
})
.appendTo(element);
setOuterWidth(eventElement, left2-left1, true);
if (!sniffedEventLeftBug) {
if (rtl) {
eventLeftDiff = left1 - eventElement.position().left;
if (eventLeftDiff) {
eventElement.css('left', left1 + eventLeftDiff);
if (rtl && rtlLeftDiff == undefined) {
// bug in IE6 where offsets are miscalculated with direction:rtl
rtlLeftDiff = left1 - eventElement.position().left;
if (rtlLeftDiff) {
eventElement.css('left', left1 + rtlLeftDiff);
}
}
sniffedEventLeftBug = true;
}
eventElementHandlers(event, eventElement);
if (event.editable || typeof event.editable == 'undefined' && options.editable) {
if (event.editable || event.editable == undefined && options.editable) {
draggableEvent(event, eventElement);
resizableEvent(event, eventElement);
}
@ -447,7 +459,7 @@ function Grid(element, options, methods) {
view.trigger('eventMouseover', this, event, ev);
},
function(ev) {
view.trigger('eventMouseover', this, event, ev);
view.trigger('eventMouseout', this, event, ev);
}
);
}
@ -462,8 +474,8 @@ function Grid(element, options, methods) {
if (!options.disableDragging && eventElement.draggable) {
var matrix;
eventElement.draggable({
zIndex: 4,
delay: 50,
zIndex: 3,
delay: 100,
opacity: options.dragOpacity,
revertDuration: options.dragRevertDuration,
start: function(ev, ui) {
@ -476,7 +488,7 @@ function Grid(element, options, methods) {
}
});
tbody.find('tr').each(function() {
matrix.row(this);
matrix.row(this, tbodyTopBug);
});
var tds = tbody.find('tr:first td');
if (rtl) {
@ -485,9 +497,9 @@ function Grid(element, options, methods) {
tds.each(function() {
matrix.col(this);
});
matrix.start();
view.hideEvents(event, eventElement);
view.trigger('eventDragStart', eventElement, event, ev, ui);
matrix.mouse(ev.pageX, ev.pageY);
},
drag: function(ev) {
matrix.mouse(ev.pageX, ev.pageY);
@ -501,7 +513,11 @@ function Grid(element, options, methods) {
}else{
var dayDelta = cell.rowDelta*7 + cell.colDelta*dis;
view.moveEvent(event, dayDelta);
view.trigger('eventDrop', this, event, dayDelta, 0, ev, ui);
view.trigger('eventDrop', this, event, dayDelta, 0, function() {
view.moveEvent(event, -dayDelta);
rerenderEvents();
}, ev, ui);
eventElement.find('a').removeAttr('href'); // prevents safari from visiting the link
rerenderEvents();
}
}
@ -522,36 +538,29 @@ function Grid(element, options, methods) {
grid: [colWidth, 0],
containment: element,
start: function(ev, ui) {
eventElement.css('z-index', 4);
eventElement.css('z-index', 3);
view.hideEvents(event, eventElement);
view.trigger('eventResizeStart', this, event, ev, ui);
},
stop: function(ev, ui) {
view.trigger('eventResizeStop', this, event, ev, ui);
var dayDelta = Math.round((Math.max(colWidth, ui.size.width) - ui.originalSize.width) / colWidth);
// ui.size.width wasn't working with grid correctly, use .width()
var dayDelta = Math.round((eventElement.width() - ui.originalSize.width) / colWidth);
if (dayDelta) {
view.resizeEvent(event, dayDelta);
view.trigger('eventResize', this, event, dayDelta, 0, ev, ui);
view.trigger('eventResize', this, event, dayDelta, 0, function() {
view.resizeEvent(event, -dayDelta);
rerenderEvents();
}, ev, ui);
rerenderEvents();
}else{
view.showEvents(event, eventElement);
}
eventElement.css('z-index', 3);
eventElement.css('z-index', 2);
}
});
}
}
//
function dayClick() {
var dayIndex = parseInt(this.className.match(/fc\-day(\d+)/)[1]);
var date = addDays(cloneDate(view.visStart), dayIndex);
view.trigger('dayClick', this, date);
}
};

View file

@ -17,6 +17,11 @@ var defaults = {
right: 'today prev,next'
},
// editing
//editable: false,
//disableDragging: false,
//disableResizing: false,
// event ajax
startParam: 'start',
endParam: 'end',
@ -35,16 +40,16 @@ var defaults = {
day: 'dddd M/d'
},
// regional
// locale
isRTL: false,
weekStart: 0,
firstDay: 0,
monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
buttonText: {
prev: '&#9668;',
next: '&#9658;',
prev: '&nbsp;&#9668;&nbsp;',
next: '&nbsp;&#9658;&nbsp;',
today: 'today',
month: 'month',
week: 'week',
@ -57,6 +62,7 @@ var defaults = {
prev: 'circle-triangle-w',
next: 'circle-triangle-e'
}
};
// right-to-left defaults
@ -67,8 +73,8 @@ var rtlDefaults = {
right: 'title'
},
buttonText: {
prev: '&#9658;',
next: '&#9668;'
prev: '&nbsp;&#9658;&nbsp;',
next: '&nbsp;&#9668;&nbsp;'
}
};
@ -86,12 +92,15 @@ $.fn.fullCalendar = function(options) {
// method calling
if (typeof options == 'string') {
var args = Array.prototype.slice.call(arguments, 1), res;
var args = Array.prototype.slice.call(arguments, 1),
res;
this.each(function() {
var r = $.data(this, 'fullCalendar')[options].apply(this, args);
if (typeof res == 'undefined') res = r;
if (res == undefined) {
res = r;
}
});
if (typeof res != 'undefined') {
if (res != undefined) {
return res;
}
return this;
@ -111,10 +120,10 @@ $.fn.fullCalendar = function(options) {
// initialize options
options = $.extend(true, {},
defaults,
(options.isRTL || typeof options.isRTL == 'undefined' && defaults.isRTL) ? rtlDefaults : {},
(options.isRTL || options.isRTL==undefined && defaults.isRTL) ? rtlDefaults : {},
options
);
var tm = options.theme ? 'ui' : 'fc';
var tm = options.theme ? 'ui' : 'fc'; // for making theme classes
this.each(function() {
@ -139,13 +148,13 @@ $.fn.fullCalendar = function(options) {
viewName, view, // the current view
prevView,
viewInstances = {};
if (options.year) {
if (options.year != undefined) {
date.setYear(options.year);
}
if (options.month) {
if (options.month != undefined) {
date.setMonth(options.month);
}
if (options.date) {
if (options.date != undefined) {
date.setDate(options.date);
}
@ -164,35 +173,40 @@ $.fn.fullCalendar = function(options) {
$("<div class='fc-view fc-view-" + v + "'/>").appendTo(content),
options);
}
if (prevView) {
prevView.element.hide();
if (prevView.eventsChanged) {
if (prevView && prevView.eventsChanged) {
// if previous view's events have been changed, mark future views' events as dirty
eventsDirtyExcept(prevView);
prevView.eventsChanged = false;
}
}
if (header) {
// update 'active' view button
header.find('div.fc-button-' + viewName).removeClass(tm + '-state-active');
header.find('div.fc-button-' + v).addClass(tm + '-state-active');
}
view.name = viewName = v;
render();
if (prevView) {
// hide the old element AFTER the new has been rendered, preserves scrollbars
prevView.element.hide();
}
}
}
function render(inc) {
if (inc || !view.date || +view.date != +date) {
ignoreResizes = true;
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);
callback(events); // no refetching
}
});
ignoreResizes = false;
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');
@ -202,15 +216,18 @@ $.fn.fullCalendar = function(options) {
}
}
else if (view.eventsDirty) {
// ensure events are rerendered if another view messed with them
view.rerenderEvents();
}
if (header) {
// update title text
header.find('h2.fc-header-title').html(view.title);
}
view.eventsDirty = false;
view.trigger('viewDisplay', _element);
}
// marks other views' events as dirty
function eventsDirtyExcept(exceptView) {
$.each(viewInstances, function() {
if (this != exceptView) {
@ -219,6 +236,7 @@ $.fn.fullCalendar = function(options) {
});
}
// called when any event objects have been added/removed/changed, rerenders
function eventsChanged() {
view.clearEvents();
view.renderEvents(events);
@ -253,20 +271,21 @@ $.fn.fullCalendar = function(options) {
// Fetch from a particular source. Append to the 'events' array
function fetchEventSource(src, callback) {
var prevDate = cloneDate(date),
var prevViewName = view.name,
prevDate = cloneDate(date),
reportEvents = function(a) {
if (+date == +prevDate) {
if (prevViewName == view.name && +prevDate == +date) { // protects from fast switching
for (var i=0; i<a.length; i++) {
normalizeEvent(a[i]);
a[i].source = src;
}
events = events.concat(a);
}
if (callback) {
callback(a);
}
}
},
reportPopEvents = function(a) {
reportEventsAndPop = function(a) {
reportEvents(a);
popLoading();
};
@ -276,11 +295,11 @@ $.fn.fullCalendar = function(options) {
params[options.endParam] = Math.round(eventEnd.getTime() / 1000);
params[options.cacheParam] = (new Date()).getTime();
pushLoading();
$.getJSON(src, params, reportPopEvents);
$.getJSON(src, params, reportEventsAndPop);
}
else if ($.isFunction(src)) {
pushLoading();
src(cloneDate(eventStart), cloneDate(eventEnd), reportPopEvents);
src(cloneDate(eventStart), cloneDate(eventEnd), reportEventsAndPop);
}
else {
reportEvents(src); // src is an array
@ -331,39 +350,41 @@ $.fn.fullCalendar = function(options) {
},
gotoDate: function(year, month, dateNum) {
if (typeof year != 'undefined') {
if (year != undefined) {
date.setYear(year);
}
if (typeof month != 'undefined') {
if (month != undefined) {
date.setMonth(month);
}
if (typeof dateNum != 'undefined') {
if (dateNum != undefined) {
date.setDate(dateNum);
}
render();
},
moveDate: function(years, months, days) {
if (typeof years != 'undefined') {
incrementDate: function(years, months, days) {
if (years != undefined) {
addYears(date, years);
}
if (typeof months != 'undefined') {
if (months != undefined) {
addMonths(date, months);
}
if (typeof days != 'undefined') {
if (days != undefined) {
addDays(date, days);
}
render();
},
//
// Event Rendering
// Event Manipulation
//
updateEvent: function(event) {
var startDelta = event.start - event._start,
endDelta = event.end ? (event.end - (event._end || view.defaultEventEnd(event))) : 0,
i, len = events.length, e;
updateEvent: function(event) { // update an existing event
var i, len = events.length, e,
startDelta = event.start - event._start,
endDelta = event.end ?
(event.end - (event._end || view.defaultEventEnd(event))) // event._end would be null if event.end
: 0; // was null and event was just resized
for (i=0; i<len; i++) {
e = events[i];
if (e._id == event._id && e != event) {
@ -379,6 +400,8 @@ $.fn.fullCalendar = function(options) {
}
e.title = event.title;
e.allDay = event.allDay;
e.className = event.className;
e.editable = event.editable;
normalizeEvent(e);
}
}
@ -386,7 +409,7 @@ $.fn.fullCalendar = function(options) {
eventsChanged();
},
renderEvent: function(event, stick) {
renderEvent: function(event, stick) { // render a new event
normalizeEvent(event);
if (!event.source) {
if (stick) {
@ -434,9 +457,7 @@ $.fn.fullCalendar = function(options) {
return e._id == filter;
});
}
else {
return events;
}
return events; // else, return all
},
rerenderEvents: function() {
@ -447,9 +468,9 @@ $.fn.fullCalendar = function(options) {
// Event Source
//
addEventSource: function(src) {
eventSources.push(src);
fetchEventSource(src, function() {
addEventSource: function(source) {
eventSources.push(source);
fetchEventSource(source, function() {
eventsChanged();
});
},
@ -490,19 +511,21 @@ $.fn.fullCalendar = function(options) {
}
function buildSection(buttonStr) {
if (buttonStr) {
var tr = $("<tr/>"),
prevTitle = false;
var tr = $("<tr/>");
$.each(buttonStr.split(' '), function(i) {
if (i > 0) {
tr.append("<td><span class='fc-header-space'/></td>");
}
var prevButton;
$.each(this.split(','), function(j) {
var buttonName = this,
buttonNameShort = this.replace(/^(basic|agenda)/, '').toLowerCase();
if (buttonName == 'title') {
tr.find('> :last div').addClass(tm + '-corner-right');
tr.append("<td><h2 class='fc-header-title'/></td>");
prevTitle = true;
if (prevButton) {
prevButton.addClass(tm + '-corner-right');
}
prevButton = null;
}else{
var buttonClick;
if (publicMethods[buttonNameShort]) {
@ -512,6 +535,9 @@ $.fn.fullCalendar = function(options) {
buttonClick = function() { switchView(buttonName) };
}
if (buttonClick) {
if (prevButton) {
prevButton.addClass(tm + '-no-right');
}
var button,
icon = options.theme ? options.buttonIcons[buttonNameShort] : null,
text = options.buttonText[buttonNameShort];
@ -549,17 +575,19 @@ $.fn.fullCalendar = function(options) {
switchView(buttonName);
});
}
if (j == 0 || prevTitle) {
button.addClass(tm + '-corner-left');
if (prevButton) {
prevButton.addClass(tm + '-no-right');
}else{
button.addClass(tm + '-no-left');
button.addClass(tm + '-corner-left');
}
prevTitle = false;
prevButton = button;
}
}
}
});
tr.find('> :last div').addClass(tm + '-corner-right');
if (prevButton) {
prevButton.addClass(tm + '-corner-right');
}
});
return $("<table/>").append(tr);
}
@ -571,11 +599,11 @@ $.fn.fullCalendar = function(options) {
-----------------------------------------------------------------------------*/
var elementWidth,
ignoreResizes = false,
ignoreWindowResizes = false,
resizeCnt = 0;
$(window).resize(function() {
if (!ignoreResizes) {
if (!ignoreWindowResizes) {
var rcnt = ++resizeCnt; // add a delay
setTimeout(function() {
if (rcnt == resizeCnt) {
@ -610,7 +638,7 @@ $.fn.fullCalendar = function(options) {
var fakeID = 0;
function normalizeEvent(event) {
event._id = event._id || (typeof event.id == 'undefined' ? '_fc' + fakeID++ : event.id + '');
event._id = event._id || (event.id == undefined ? '_fc' + fakeID++ : event.id + '');
if (event.date) {
if (!event.start) {
event.start = event.date;
@ -620,10 +648,10 @@ function normalizeEvent(event) {
event._start = cloneDate(event.start = parseDate(event.start));
event.end = parseDate(event.end);
if (event.end && event.end < event.start) {
event.end = cloneDate(event.start);
event.end = null;
}
event._end = event.end ? cloneDate(event.end) : null;
if (typeof event.allDay == 'undefined') {
if (event.allDay == undefined) {
event.allDay = true;
}
}

View file

@ -1 +1,2 @@
})(jQuery);

View file

@ -2,8 +2,9 @@
* FullCalendar
* http://arshaw.com/fullcalendar/
*
* use fullcalendar.css for basic styling
* requires jQuery UI core and draggables ONLY if you plan to do drag & drop
* Use fullcalendar.css for basic styling.
* For event drag & drop, required jQuery UI draggable.
* For event resizing, requires jQuery UI resizable.
*
* Copyright (c) 2009 Adam Shaw
* Dual licensed under the MIT and GPL licenses:
@ -15,3 +16,4 @@
*/
(function($) {

View file

@ -38,9 +38,8 @@ function clearTime(d) {
function cloneDate(d, dontKeepTime) {
if (dontKeepTime) {
return clearTime(new Date(+d));
}else{
return new Date(+d);
}
return new Date(+d);
}
@ -49,23 +48,24 @@ function cloneDate(d, dontKeepTime) {
-----------------------------------------------------------------------------*/
var parseDate = fc.parseDate = function(s) {
if (typeof s == 'object')
return s; // already a Date object
if (typeof s == 'undefined')
return null;
if (typeof s == 'number')
if (typeof s == 'object') { // already a Date object
return s;
}
if (typeof s == 'number') { // a UNIX timestamp
return new Date(s * 1000);
return parseISO8601(s, true) ||
Date.parse(s) ||
new Date(parseInt(s) * 1000);
}
if (typeof s == 'string') {
if (s.match(/^\d+$/)) { // a UNIX timestamp
return new Date(parseInt(s) * 1000);
}
return parseISO8601(s, true) || Date.parse(s) || null;
}
return null;
}
var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) {
// derived from http://delete.me.uk/2005/03/iso8601.html
var regexp = "([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 d = s.match(new RegExp(regexp));
var d = s.match(parseISO8601Regex);
if (!d) return null;
var offset = 0;
var date = new Date(d[1], 0, 1);
@ -85,6 +85,11 @@ var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) {
return new Date(Number(date) + (offset * 60 * 1000));
}
var parseISO8601Regex = new RegExp(
"([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})))?)?)?)?");
/* Date Formatting
@ -253,11 +258,9 @@ function HoverMatrix(changeCallback) {
origRow, origCol,
currRow, currCol;
// this.cell = null;
this.row = function(e) {
this.row = function(e, topBug) {
prevRowE = $(e);
tops.push(prevRowE.offset().top);
tops.push(prevRowE.offset().top + (topBug ? prevRowE.parent().position().top : 0));
};
this.col = function(e) {
@ -265,13 +268,12 @@ function HoverMatrix(changeCallback) {
lefts.push(prevColE.offset().left);
};
this.start = function() {
this.mouse = function(x, y) {
if (origRow == undefined) {
tops.push(tops[tops.length-1] + prevRowE.outerHeight());
lefts.push(lefts[lefts.length-1] + prevColE.outerWidth());
origRow = currRow = currCol = -1;
};
this.mouse = function(x, y) {
currRow = currCol = -1;
}
var r, c;
for (r=0; r<tops.length && y>=tops[r]; r++) ;
for (c=0; c<lefts.length && x>=lefts[c]; c++) ;
@ -283,7 +285,7 @@ function HoverMatrix(changeCallback) {
if (r == -1 || c == -1) {
this.cell = null;
}else{
if (origRow == -1) {
if (origRow == undefined) {
origRow = r;
origCol = c;
}
@ -310,7 +312,8 @@ function HoverMatrix(changeCallback) {
/* Misc Utils
-----------------------------------------------------------------------------*/
var dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
var undefined,
dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
function zeroPad(n) {
return (n < 10 ? '0' : '') + n;
@ -319,3 +322,4 @@ function zeroPad(n) {
function strProp(s, prop) {
return typeof s == 'string' ? s : s[prop];
}

View file

@ -1,19 +1,30 @@
/* Methods & Utilities for All Views
-----------------------------------------------------------------------------*/
var viewMethods = {
//
// Objects inheriting these methods must implement the following properties/methods:
// - title
// - start
// - end
// - visStart
// - visEnd
// - defaultEventEnd(event)
// - visEventEnd(event)
//
// - render
// - rerenderEvents
//
/*
* Objects inheriting these methods must implement the following properties/methods:
* - title
* - start
* - end
* - visStart
* - visEnd
* - defaultEventEnd(event)
* - visEventEnd(event)
* - render(events)
* - rerenderEvents()
*
*
* z-index reservations:
* 1. day-overlay
* 2. events
* 3. dragging/resizing events
*
*/
init: function(element, options) {
this.element = element;
@ -26,7 +37,7 @@ var viewMethods = {
// trigger event handlers, always append view as last arg
// triggers an event handler, always append view as last arg
trigger: function(name, thisObj) {
if (this.options[name]) {
@ -36,7 +47,7 @@ var viewMethods = {
//
// returns a Date object for an event's end
eventEnd: function(event) {
return event.end || this.defaultEventEnd(event);
@ -44,14 +55,13 @@ var viewMethods = {
// event/element creation reporting
// report when view receives new events
reportEvents: function(events) {
reportEvents: function(events) { // events are already normalized at this point
var i, len=events.length, event,
fakeID = 0,
eventsByID = this.eventsByID = {},
cachedEvents = this.cachedEvents = [];
for (i=0; i<len; i++) { // TODO: move _id creation to more global 'cleanEvents'
for (i=0; i<len; i++) {
event = events[i];
if (eventsByID[event._id]) {
eventsByID[event._id].push(event);
@ -62,6 +72,10 @@ var viewMethods = {
}
},
// report when view creates an element for an event
reportEventElement: function(event, element) {
this.eventElements.push(element);
var eventElementsByID = this.eventElementsByID;
@ -76,7 +90,7 @@ var viewMethods = {
// event element manipulation
clearEvents: function() { // just remove ELEMENTS
clearEvents: function() { // only remove ELEMENTS
$.each(this.eventElements, function() {
this.remove();
});
@ -89,12 +103,13 @@ var viewMethods = {
},
hideEvents: function(event, exceptElement) {
this._eee(event, exceptElement, 'hide'); // fadeOut
this._eee(event, exceptElement, 'hide');
},
_eee: function(event, exceptElement, funcName) { // event-element-each
var elements = this.eventElementsByID[event._id];
for (var i=0; i<elements.length; i++) {
var elements = this.eventElementsByID[event._id],
i, len = elements.length;
for (i=0; i<len; i++) {
if (elements[i] != exceptElement) {
elements[i][funcName]();
}
@ -105,41 +120,41 @@ var viewMethods = {
// event modification reporting
moveEvent: function(event, days, minutes) { // and actually DO the date change too
moveEvent: function(event, days, minutes) { // actually DO the date changes
minutes = minutes || 0;
var i, event2, events = this.eventsByID[event._id];
for (i=0; i<events.length; i++) {
event2 = events[i];
event2.allDay = event.allDay;
addMinutes(addDays(event2.start, days, true), minutes);
if (event.end) {
event2.end = addMinutes(addDays(this.eventEnd(event2), days, true), minutes);
}else{
event2.end = null;
var events = this.eventsByID[event._id],
i, len=events.length, e;
for (i=0; i<len; i++) {
e = events[i];
e.allDay = event.allDay;
addMinutes(addDays(e.start, days, true), minutes);
if (e.end) {
e.end = addMinutes(addDays(e.end, days, true), minutes);
}
normalizeEvent(event2);
normalizeEvent(e);
}
this.eventsChanged = true;
},
resizeEvent: function(event, days, minutes) { // and actually DO the date change too
resizeEvent: function(event, days, minutes) { // actually DO the date changes
minutes = minutes || 0;
var i, event2, events = this.eventsByID[event._id];
for (i=0; i<events.length; i++) {
event2 = events[i];
event2.end = addMinutes(addDays(this.eventEnd(event2), days, true), minutes);
normalizeEvent(event2);
var events = this.eventsByID[event._id],
i, len=events.length, e;
for (i=0; i<len; i++) {
e = events[i];
e.end = addMinutes(addDays(this.eventEnd(e), days, true), minutes);
normalizeEvent(e);
}
this.eventsChanged = true;
},
// semi-transparent overlay (for days while dragging)
// semi-transparent overlay (while dragging)
showOverlay: function(props) {
if (!this.dayOverlay) {
this.dayOverlay = $("<div class='fc-cell-overlay' style='position:absolute;display:none'/>")
this.dayOverlay = $("<div class='fc-cell-overlay' style='position:absolute;z-index:1;display:none'/>")
.appendTo(this.element);
}
var o = this.element.offset();
@ -217,7 +232,7 @@ function stackSegs(segs) {
collide = false;
if (levels[j]) {
for (k=0; k<levels[j].length; k++) {
if (seg.end > levels[j][k].start && seg.start < levels[j][k].end) {
if (segsCollide(levels[j][k], seg)) {
collide = true;
break;
}
@ -246,3 +261,4 @@ function segCmp(a, b) {
function segsCollide(seg1, seg2) {
return seg1.end > seg2.start && seg1.start < seg2.end;
}

View file

@ -76,7 +76,7 @@
</script>
</head>
<body style='font-size:12px'>
<body style='font-size:14px'>
<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
</body>
</html>

View file

@ -33,7 +33,7 @@
dragOpacity: .5,
dragRevertDuration: 100,
weekMode: 'liquid', //'variable'
//weekMode: 'liquid', //'variable'
/*
titleFormat: {

View file

@ -11,7 +11,7 @@
var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
var jsonFeed = "../examples/json_events.php";
var jsonFeed = "../examples/json-events.php";
var staticEvents = [
{

View file

@ -20,20 +20,20 @@
viewDisplay: function(view) {
console.log('viewDisplay');
console.log(view);
console.log(this);
//console.log(view);
//console.log(this);
},
//loading: // see sources.html
windowResize: function(view) {
console.log('windowResize - ' + view.title);
console.log(this);
//console.log(this);
},
dayClick: function(dayDate, view) {
console.log('dayClick - ' + dayDate + ' - ' + view.title);
console.log(this);
//console.log(this);
},
eventRender: function(event, element, view) {
@ -45,16 +45,16 @@
}
else if (event.id == 1) {
element.css('border-color', 'red');
console.log('renderEvent (' + event.title + ') - ' + view.title);
//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;
//console.log(jsEvent);
//console.log(view);
//console.log(this);
//return false;
},
/*
eventMouseover: function(event, jsEvent, view) {
@ -73,20 +73,23 @@
eventDragStart: function(event, jsEvent, ui, view) {
console.log('DRAG START ' + event.title);
console.log(this);
//console.log(this);
},
eventDragStop: function(event, jsEvent, ui, view) {
console.log('DRAG STOP ' + event.title);
console.log(this);
//console.log(this);
},
eventDrop: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
eventDrop: function(event, dayDelta, minuteDelta, revertFunc, 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);
/*setTimeout(function() {
revertFunc();
}, 2000);*/
//console.log(jsEvent);
//console.log(ui);
//console.log(view.title);
//console.log(this);
},
eventResizeStart: function(event, jsEvent, ui, view) {
@ -97,14 +100,17 @@
console.log('RESIZE STOP ' + event.title);
console.log(this);
},
eventResize: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
eventResize: function(event, dayDelta, minuteDelta, revertFunc, 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);
/*setTimeout(function() {
revertFunc();
}, 2000);*/
//console.log(jsEvent);
//console.log(ui);
//console.log(view.title);
//console.log(this);
},
events: [
@ -144,10 +150,10 @@
},
{
id: 4,
title: "Click for Facebook",
title: "Click for Google",
start: new Date(y, m, 27),
end: new Date(y, m, 28),
url: "http://facebook.com/"
url: "http://google.com/"
},
{
id: 5,