diff --git a/changelog.txt b/changelog.txt
index ff8d311..e0c766f 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -3,6 +3,9 @@ version 1.2
- cssClass attribute for CalEvents
- multiple event sources (using an array for the 'events' option)
- the 'events' option for fullCalendar() and gcalFullCalendar() is now optional
+ - bugs w/ month date formatting
+ - change behavior for parsing number strings (now as unix timestamp)
+ - allow multiple classes in cssClass
version 1.1 (5/10/09)
- Added the following options:
diff --git a/docs/conf.py b/docs/conf.py
index cf7a292..9658915 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -188,3 +188,6 @@ latex_documents = [
# If false, no module index is generated.
#latex_use_modindex = True
+
+highlight_language = 'javascript'
+
diff --git a/docs/index.txt b/docs/index.txt
index 8d7481e..8edf66b 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -1,31 +1,21 @@
-.. highlight:: javascript
+Main Usage
+==========
-Usage
-=====
+The following code initializes a FullCalendar within an element with ID 'calendar'::
-.. code-block:: javascript
-
- $('#myCalendar').fullCalendar({
- // initializes a calendar
- // see options, data provider, and triggered events below
- });
+ $('#calendar').fullCalendar({
- $('#myCalendar').fullCalendar('nextMonth'); // move ahead one month
+ // put your options here
- $('#myCalendar').fullCalendar('currentMonth'); // go to current month
+ })
- $('#myCalendar').fullCalendar('prevMonth'); // move back one month
- $('#myCalendar').fullCalendar('gotoMonth', year, month);
- // go to an arbitrary month. 'month' is zero-based
-
- $('#myCalender').fullCalendar('refresh');
- // re-fetch events for the current month
-
-Options
-=======
+.. _GeneralOptions:
+
+General Options
+===============
**year**, **month**: integers
The month that will be displayed when the calendar first loads.
@@ -35,18 +25,11 @@ Options
Determines if all events on the calendar can be dragged & dropped. If
``true``, requires `jQuery UI `_ core and draggables.
Can be overridden on a per-event basis with the ``draggable`` property of
- each :ref:`CalEvent ` object.
+ each :ref:`CalEvent `.
**fixedWeeks**: boolean, default:``true``
If ``true``, the calendar will always be 6 weeks tall. If ``false``, the
calendar's height will vary per month.
-
- **weekStart**: integer, default:``0``
- The day-of-week each week begins. 0 = Sunday (default),
- 1 = Monday (for UK users), 2 = Tuesday, etc.
-
- **rightToLeft**: boolean, default:``false``
- Displays the calendar right-to-left (for Arabic and Hebrew languages)
**abbrevDayHeadings**: boolean, default:``true``
Whether to display "Sun" versus "Sunday" for days of the week.
@@ -55,42 +38,28 @@ Options
Determines whether a title such as "January 2009" will be displayed at the
top of the calendar.
- **titleFormat**: string, default:``"Y F"``
- A string defining format of the title above the calendar. The default
- "Y F" creates strings such as "January 2009". Use the following
- codes in your format string (similar to the PHP's date function):
-
- * **F** - January through December
- * **m** - 01 through 12 (leading zeros)
- * **M** - Jan through Dec
- * **n** - 1 through 12
- * **Y** - Examples: 1999 or 2003
- * **y** - Examples: 99 or 03
+ **titleFormat**: string, default:``"F Y"``
+ A string defining the format of the title above the calendar. The default
+ "F Y" creates strings such as "January 2009". Consult the
+ :ref:`$.fullCalendar.formatDate ` documentation for a full
+ list of commands.
**buttons**: boolean/hash, default:``true``
Determines whether navigation buttons will be displayed at the top of the
- calendar. A hash with keys 'today', 'prev', and 'next' will determine if
- each individual button is displayed. Strings can be provided to change
- each button's text.
+ calendar. A hash such as ``{today:false, prev:true, next:true}`` can be
+ provided to display only certain buttons. A hash such as
+ ``{today:false, prev:"Last Month", next:"Next Month"}`` can be provided
+ to display only certain buttons AND change a button's text.
**showTime**: boolean/ ``"guess"``, default:``"guess"``
Determines if times will be displayed before each event's title.
``"guess"`` displays times only for events with non-zero start or end times.
**timeFormat**: string, default: ``"gx"``
- A string defining the format of dislayed of event times. The default "gx"
- creates a string such as "9a". Use the following codes in your format
- string (similar to PHP's date function):
-
- * **a** - am or pm
- * **A** - AM or PM
- * **x** - a or p
- * **X** - A or P
- * **g** - 1 through 12 (hour)
- * **G** - 0 through 23 (hour, military time)
- * **h** - 01 through 12 (hour, leading zeros)
- * **H** - 00 through 23 (hour, military time and leading zeros)
- * **i** - 00 to 59 (minute, leading zeros)
+ A string defining the format of dislayed event times. The default "gx"
+ creates a string such as "9a". Consult the
+ :ref:`$.fullCalendar.formatDate `
+ documentation for a full list of commands.
**eventDragOpacity**: float
The opacity of an event element while it is being dragged (0.0 - 1.0)
@@ -99,21 +68,91 @@ Options
Controls the duration (in milliseconds) of the animation of an event
snapping back into place.
-
-.. _EventDataProvider:
+
+
+.. _TriggeredActions:
-Event Data Provider
-===================
+Triggered Actions
+=================
+
+The following options are *functions* that get executed every time something
+special happens:
+
+ **monthDisplay**: function(year, month, monthTitle)
+ Triggered once when the calendar loads and every time the
+ calendar's month is changed. ``month`` is zero-based. ``monthTitle``
+ contains the new title of the month (ex: "January 2009")
+
+ **loading**: function(isLoading)
+ Triggered with a ``true`` argument when the calendar begins fetching
+ events via AJAX. Triggered with ``false`` when done.
+
+ **resize**: function()
+ Triggered after the calendar has recovered from a resize (due to the window
+ being resized).
+
+ ``this`` is set to the main element
+
+ **dayClick**: function(dayDate)
+ Triggered when the user clicks on a day. ``dayDate`` is a Date object with
+ it's time set to 00:00:00.
+
+ ``this`` is set to the TD element of the clicked day.
+
+ **eventRender**: function(calEvent, element)
+ Triggered before an element is rendered for the given :ref:`CalEvent `.
+ ``element`` is the jQuery element that will be used by default. You can modify
+ this element or return a brand new element that will be used instead.
+
+ This function is great for attaching other jQuery plugins to each event
+ element, such as a `qTip `_
+ tooltip effect.
+
+ **eventClick**, **eventMouseover**, **eventMouseout**: function(calEvent, jsEvent)
+ Triggered on click/mouseover/mouseout actions for an event.
+ ``calEvent`` holds that event's information (date, title, etc).
+ ``jsEvent`` holds the native javascript event (with information about click position, etc).
+
+ ``this`` is set to the event's element
+
+ For ``eventClick``, return ``false`` to prevent the browser from going to
+ the event's URL.
+
+ **eventDragStart**, **eventDragStop**: function(calEvent, jsEvent, ui)
+ Triggered before/after an event is dragged (but not necessarily moved to a new day).
+ ``calEvent`` holds that event's information (date, title, etc).
+ ``jsEvent`` holds the native javascript event (with information about click position, etc).
+ ``ui`` holds the jQuery UI object.
+
+ ``this`` is set to the event's element
+
+ **eventDrop**: function(calEvent, dayDelta, jsEvent, ui)
+ 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)
+ or backwards (a negative number).
+
+ ``dayDelta`` is elegant for dealing with multi-day and repeating events.
+ If updating a remote database, just add the ``dayDelta`` to the start
+ and end times of all events with the given ``calEvent.id``
+
+
+
+.. _EventSources:
+
+Event Feeds and Sources
+=======================
+
+The following options determine *how* events get on the calendar:
**events**: array/string/function
- An array of :ref:`CalEvent` can be used to hardcode events into the
+ An array of :ref:`CalEvents ` can be used to hardcode events into the
calendar.
Or, a URL can be provided. This URL should return JSON for an array of
- :ref:`CalEvent`. GET parameters, determined by the ``startParam`` and
- ``endParam`` options, will be inserted into the URL. These parameters
- indicate the UNIX timestamp of the start of the first visible day
- (inclusive) and the end of the last visible day (exclusive).
+ :ref:`CalEvents `. GET parameters, determined by the
+ ``startParam`` and ``endParam`` options, will be inserted into the URL.
+ These parameters indicate the UNIX timestamp of the start of the first
+ visible day (inclusive) and the end of the last visible day (exclusive).
Or, a function can be provided for custom fetching. The function is
queried every time event data is needed. The function is passed a ``start``
@@ -140,91 +179,48 @@ Event Data Provider
}
+ **eventSources**: array
+ Similar to the ``events`` options, except one may specify *multiple* sources.
+ For example, one may specify an array of JSON URL's, an array of custom
+ functions, an array of hardcoded event arrays, or any combination.
+
**startParam**: string, default:``"start"``
A GET parameter of this name will be inserted into the URL when fetching
- events from a JSON script (when ``event`` is a URL string). The value
- of this GET parameter will be a UNIX timestamp denoting the start of the
- first visible day (inclusive).
+ events from a JSON script. The value of this GET parameter will be a UNIX
+ timestamp denoting the start of the first visible day (inclusive).
**endParam**: string, default:``"end"``
A GET parameter of this name will be inserted into the URL when fetching
- events from a JSON script (when ``event`` is a URL string). The value
- of this GET parameter will be a UNIX timestamp denoting the end of the
- last visible day (exclusive).
+ events from a JSON script. The value of this GET parameter will be a UNIX
+ timestamp denoting the end of the last visible day (exclusive).
**cacheParam**: string, default:``"_"``
When using a JSON url, a parameter of this name will
automatically be inserted into the URL to prevent the browser from
caching the response. The value will be the current millisecond time.
-.. _TriggeredEvents:
-
-Triggered Events
-================
+The following methods can be called on a FullCalendar that has already
+been initialized:
- **monthDisplay**: function(year, month, monthTitle)
- Triggered once when the calendar loads and every time the
- calendar's month is changed. ``month`` is zero-based. ``monthTitle``
- contains the new title of the month (ex: "January 2009")
+ **.fullCalendar(** ``'addEventSource'``, **source)**
+ Adds an event source. ``source`` may be an array/string/function just as in
+ the ``events`` option. Events will be immediately fetched from this source
+ and placed on the calendar.
+
+ **.fullCalendar(** ``'removeEventSource'``, **source)**
+ Remove an event source. ``source`` must be the original array/string/function.
- **loading**: function(isLoading)
- Triggered with a ``true`` argument when the calendar begins fetching
- events via AJAX. Triggered with ``false`` when done.
-
- **resize**: function()
- Triggered after the calendar has recovered from a resize (due to the window
- pane being resized).
-
- ``this`` is set to the main element
-
- **dayClick**: function(dayDate)
- Triggered when the user clicks on a day. ``dayDate`` is a Date object with
- it's time set to 00:00:00.
-
- ``this`` is set to the TD element of the clicked day.
-
- **eventRender**: function(calEvent, element)
- Triggered before an element is rendered for the given ``calEvent``.
- ``element`` is the jQuery element that will be used by default. You can modify
- this element or return a brand new element that will be used instead.
-
- **eventClick**, **eventMouseover**, **eventMouseout**: function(calEvent, domEvent)
- Triggered on click/mouseover/mouseout actions for an event.
- ``calEvent`` holds that event's information (date, title, etc).
- ``domEvent`` holds the native DOM event (with information about click position, etc).
-
- ``this`` is set to the event's TABLE element
-
- For ``eventClick``, return ``false`` to prevent the browser from going to
- calEvent's URL.
-
- **eventDragStart**, **eventDragStop**: function(calEvent, domEvent, ui)
- Triggered before/after an event is dragged (but not necessarily moved to a new day).
- ``calEvent`` holds that event's information (date, title, etc).
- ``domEvent`` holds the native DOM event (with information about click position, etc).
- ``ui`` holds the jQuery UI object.
-
- ``this`` is set to the event's TABLE element
-
- **eventDrop**: function(calEvent, dayDelta, domEvent, ui)
- 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)
- or backwards (a negative number).
-
- ``dayDelta`` is elegant for dealing with multi-day and repeating events.
- If updating a remote database, just add the ``dayDelta`` to the start
- and end times of all events with the given ``calEvent.id``
-
-
-.. _CalEvent:
+
+
+.. _CalEvents:
CalEvent Objects
================
-A ``CalEvent`` is a data structure that frequents FullCalendar's API. It is
-used when a custom event-fetcher needs to report to the :ref:`EventDataProvider`.
-It is also used in various :ref:`TriggeredEvents`. Here are the properties of a
-``CalEvent``\:
+A CalEvent is a data structure that frequents FullCalendar's API. It is the
+standardized currency used in :ref:`EventSources`. It is also passed to various
+:ref:`Triggered Actions `. Here are the properties of a
+CalEvent:
**id**: integer/string,
Uniquely identifies the given event. Absolutely essential for multi-day
@@ -240,7 +236,7 @@ It is also used in various :ref:`TriggeredEvents`. Here are the properties of a
A javascript Date object indicating the date/time an event begins.
Events with ambiguous time-of-day should use 00:00:00.
- When reporting to the :ref:`EventDataProvider`, for convenience,
+ In an :ref:`Event Source `, for convenience,
one can also use a string in IETF format (ex: "Wed, 18 Oct 2009 13:00:00 EST"),
a string in ISO8601 format (ex: "2009-11-05T13:15:30Z") or an integer
UNIX timestamp.
@@ -249,9 +245,9 @@ It is also used in various :ref:`TriggeredEvents`. Here are the properties of a
A javascript Date object indicating the date/time an event ends
(exclusively). If an event has an ambiguous end time, ``end`` should be
set to midnight of the next day. This is implied if ``end`` is omitted.
- (For convenience with the :ref:`EventDataProvider`).
+ (For convenience with an :ref:`Event Source `).
- IETF and ISO8601 strings can be used for the :ref:`EventDataProvider`.
+ IETF and ISO8601 strings can be used with an :ref:`Event Source `.
**draggable**: boolean (optional)
Overrides the master ``draggable`` property for this single event.
@@ -259,20 +255,189 @@ It is also used in various :ref:`TriggeredEvents`. Here are the properties of a
**showTime**: boolean/ ``"guess"`` (optional)
Overrides the master ``showTime`` property for this single event.
-When giving events to the :ref:`EventDataProvider`, one can include other
-properties beyond the ones listed. This is useful if you want to earmark your
-events with additional data to be retrieved later during a
-:ref:`Triggered Event `.
+ **className**: string/array (optional)
+ A CSS class (or array of classes) that will be attached to this event's
+ element.
+
+ **source**: array/string/function (automatic)
+ A reference to the original array, JSON URL, or function the event
+ came from. Do not worry about populating this value, FullCalendar will
+ do this automatically.
+
+The following methods can be called on a FullCalendar that has already been
+initialized. These methods get/add/remove/update the event elements that
+currently reside on the calendar. Note that when you are using a JSON feed or custom
+event source, your event is never *permanently* deleted, because it may be
+refetched from the source at a later time. It is up to the developer to delete
+the event(s) from any database.
+ **.fullCalendar(** ``'addEvent'``, **calEvent)**
+ Add an event to the current month on-the-fly. ``calEvent`` is an object
+ containing at least an id, title, and start date.
+
+ **.fullCalendar(** ``'updateEvent'``, **calEvent)**
+ Report modifications to the given :ref:`CalEvent ` and redraw.
+ ``calEvent`` must be the *actual CalEvent object*, as retrieved from a
+ :ref:`Triggered Action ` or ``getEventsById`` (see below).
+ A set of repeating events will all be affected.
+
+ **.fullCalendar(** ``'removeEvent'``, **calEventOrId)**
+ Remove elements belonging to the given :ref:`CalEvent `. If the
+ event is repeating, all occurences of the event will be removed. The
+ second argument may be a CalEvent's ID, or the CalEvent object itself.
+
+ **.fullCalendar(** ``'getEventsById'`` , **eventId)**
+ Returns a list of :ref:`CalEvents ` with the given ID that are
+ currently being displayed.
+
+
+
+
+Navigation Methods
+==================
-Extras
+The following methods may be called on a FullCalendar that has already been
+initialized:
+
+ **.fullCalendar(** ``'prevMonth'`` **)**
+ Visits the previous month.
+
+ **.fullCalendar(** ``'nextMonth'`` **)**
+ Visits the next month.
+
+ **.fullCalendar(** ``'gotoMonth'``, **year, month)**
+ Visits an arbitrary month. ``month`` is zero-based (0 is January, 1 is
+ February, etc).
+
+ **.fullCalendar(** ``'today'`` **)**
+ Visits the current month.
+
+ **.fullCalendar(** ``'refresh'`` **)**
+ Refetch and redraw the events for the current month.
+
+
+
+Locale
======
-FullCalendar provides some extra date utilities\:
+Use the following options to change the calendar's locale:
+
+ **weekStart**: integer, default:``0``
+ The day-of-week each week begins. 0 = Sunday (default),
+ 1 = Monday (for UK users), 2 = Tuesday, etc.
+
+ **rightToLeft**: boolean, default:``false``
+ Displays the calendar right-to-left (for Arabic and Hebrew)
+
+The following *variables* may be reassigned or modified to globally change the
+text for months and days:
+
+ **$.fullCalendar.monthNames**
+ Default: ``['January', 'February', 'March', ...]``
+
+ **$.fullCalendar.monthAbbrevs**
+ Default: ``['Jan', 'Feb', 'Mar', ...]``
+
+ **$.fullCalendar.dayNames**
+ Default: ``['Sunday', 'Monday', 'Tuesday', ...]``
+
+ **$.fullCalendar.dayAbbrevs**
+ Default: ``['Sun', 'Mon', 'Tue', ...]``
+
+Notice these variables are attached to the main **$** jQuery object.
+
+The :ref:`GeneralOptions` ``titleFormat`` and ``timeFormat`` may also be of
+interest to those wanting to change locale.
+
+
- **$.parseISO8601(string, ignoreTimezone)**
- Parses an ISO8601 string and returns a ``Date`` object
+Date Parsing and Formatting
+===========================
+
+The following utilities are always available. These typically come in handy
+when creating a custom event source:
+
+.. _formatDate:
+
+ **$.fullCalendar.formatDate(date, format)**
+ Format a javascript Date object into a string. ``format`` may contain
+ one or more of the following commands (similar to PHP's date function):
+
+ * **F** - January through December
+ * **M** - Jan through Dec
+ * **n** - 1 through 12 (month)
+ * **m** - 01 through 12 (month, leading zeros)
+ * **Y** - Examples: 1999 or 2003
+ * **y** - Examples: 99 or 03
+ * **a** - am or pm
+ * **A** - AM or PM
+ * **x** - a or p
+ * **X** - A or P
+ * **g** - 1 through 12 (hour)
+ * **G** - 0 through 23 (hour, military time)
+ * **h** - 01 through 12 (hour, leading zeros)
+ * **H** - 00 through 23 (hour, military time and leading zeros)
+ * **i** - 00 to 59 (minute, leading zeros)
- **$.ISO8601String(date)**
- Takes a ``Date`` object and returns an ISO8601 string
+ **$.fullCalendar.parseDate(string)**
+ Parse a string and return a javascript Date object. The string may be
+ in ISO8601 format, IETF format, or a UNIX timestamp.
+
+ **$.fullCalendar.parseISO8601(string, ignoreTimezone)**
+ Parse an ISO8601 string into a javascript Date object.
+Notice these functions are attached to the main **$** jQuery object.
+
+
+
+Google Calendar
+===============
+
+To integrate with your Google Calendar, you must first **make your calendar public**:
+
+#. In the Google Calendar interface, locate the "My Calendar" box on the left.
+
+#. Click the arrow next to the calendar you need.
+
+#. A menu will appear. Click "Share this calendar."
+
+#. Check "Make this calendar public."
+
+#. Make sure "Share only my free/busy information" is *unchecked*.
+
+#. Click "Save."
+
+Then, you must obtain your calendar's **XML feed URL**.
+
+#. In the Google Calendar interface, locate the "My Calendar" box on the left
+
+#. Click the arrow next to the calendar you need.
+
+#. A menu will appear. Click "Calendar settings."
+
+#. In the "Calendar Address" section of the screen, click the XML badge.
+
+#. Your feed's URL will appear.
+
+The API for integrating a Google Calendar feed has changed since
+FullCalendar 1.1. The ``$.fullCalendar.gcalFeed`` function now produces
+an event source that can be passed to the ``events`` or ``eventSources``
+option::
+
+ $('#calendar').fullCalendar({
+
+ events: $.fullCalendar.gcalFeed(
+ "http://www.google.com/calendar/feeds/...", // feed URL
+ { className: 'gcal-events' } // optional options
+ )
+
+ });
+
+Here is a list of available options:
+
+* **className** - CSS class to attach to each event from this Google Calendar
+
+* **draggable** - whether to allow dragging (default: ``false``)
+
+See *gcal.html* in the *examples* directory for a complete example.
+
diff --git a/docs/templates/layout.html b/docs/templates/layout.html
index 3524703..30f5226 100644
--- a/docs/templates/layout.html
+++ b/docs/templates/layout.html
@@ -3,6 +3,13 @@
fullcalendar_nav() ?>
begin_content() ?>
+
+
Table of Contents
+{{ toc }}
+
+
+
+
{% block body %}{% endblock %}
end_content() ?>
diff --git a/examples/gcal.html b/examples/gcal.html
index 6760aaf..ca7b505 100644
--- a/examples/gcal.html
+++ b/examples/gcal.html
@@ -30,9 +30,12 @@
$(document).ready(function() {
- $('#calendar').gcalFullCalendar({
+ $('#calendar').fullCalendar({
// US Holidays
- events: 'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
+ events: $.fullCalendar.gcalFeed(
+ 'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
+ {draggable: false, className: 'mygcal'}
+ ),
eventClick: function(event) {
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
diff --git a/fullcalendar.js b/fullcalendar.js
index 36279ba..1411dad 100644
--- a/fullcalendar.js
+++ b/fullcalendar.js
@@ -17,19 +17,30 @@
(function($) {
$.fn.fullCalendar = function(options) {
+
+
+ //
+ // Calls methods of a pre-existing instance
+ //
if (typeof options == 'string') {
var args = Array.prototype.slice.call(arguments, 1);
- var ret; // ugly
+ var res;
this.each(function() {
var r = $.data(this, 'fullCalendar')[options].apply(this, args);
- if (typeof ret == 'undefined') ret = r;
+ if (typeof res == 'undefined') res = r;
});
- if (typeof ret == 'undefined')
- return this;
- return ret;
+ if (typeof res != 'undefined')
+ return res;
+ return this;
}
+
+
+ //
+ // Process options
+ //
+
options = options || {};
var r2l = options.rightToLeft;
@@ -48,77 +59,94 @@
var weekStart = (options.weekStart || 0) % 7;
var timeFormat = options.timeFormat || 'gx';
var titleFormat = options.titleFormat || (r2l ? 'Y F' : 'F Y');
+
+
+
+ //
+ // Rendering bug detection variables
+ //
+
var tdTopBug, trTopBug, tbodyTopBug, sniffBugs = true;
+
+
this.each(function() {
- var date = options.year ? new Date(options.year, options.month || 0, 1) : new Date();
- var start, end, today, numWeeks;
+
+ //
+ // Instance variables
+ //
+
+ var date = options.year ? // holds the year & month of current month
+ new Date(options.year, options.month || 0, 1) :
+ new Date();
+ var start, end; // first & last VISIBLE dates
+ var today;
+ var numWeeks;
var ignoreResizes = false;
+
var events = [];
+ var eventSources = options.eventSources || [];
+ if (options.events) eventSources.push(options.events);
- var eventSources;
- var eo = options.events;
- if (eo) {
- if (typeof eo == 'string' || $.isFunction(eo)) {
- eventSources = [eo];
- }else{
- var item = eo[0];
- if (item) {
- if (typeof item == 'string' || $.isFunction(item))
- eventSources = eo;
- else {
- eventSources = [eo];
- }
- }
- }
- }
- else eventSources = [];
+
+ //
+ // Month navigation functions
+ //
- function updateMonth() {
- clearEvents();
+ function refreshMonth() {
+ clearEventElements();
render();
}
- function today() {
- date = new Date();
- updateMonth();
- }
-
function prevMonth() {
addMonths(date, -1);
- updateMonth();
+ refreshMonth();
}
function nextMonth() {
addMonths(date, 1);
- updateMonth();
+ refreshMonth();
+ }
+
+ function gotoToday() {
+ date = new Date();
+ refreshMonth();
}
function gotoMonth(year, month) {
date = new Date(year, month, 1);
- updateMonth();
+ refreshMonth();
}
+
+
+ //
+ // Publicly accessible methods
+ //
+
$.data(this, 'fullCalendar', {
- today: today,
+ refresh: refreshMonth,
prevMonth: prevMonth,
nextMonth: nextMonth,
+ today: gotoToday,
gotoMonth: gotoMonth,
- refresh: updateMonth,
- // event crud
+ //
+ // Event CRUD
+ //
+
addEvent: function(event) {
events.push(normalizeEvent(event));
- clearEvents();
+ clearEventElements();
renderEvents();
},
-
+
updateEvent: function(event) {
- event.start = cleanDate(event.start);
- event.end = cleanDate(event.end);
+ event.start = $.fullCalendar.parseDate(event.start);
+ event.end = $.fullCalendar.parseDate(event.end);
var startDelta = event.start - event._start;
var msLength = event.end - event.start;
event._start = cloneDate(event.start);
@@ -126,8 +154,8 @@
var e = events[i];
if (e.id === event.id && e !== event) {
e.start = new Date(e.start.getTime() + startDelta);
- e.end = new Date(e.start.getTime() + msLength);
e._start = cloneDate(e.start);
+ e.end = new Date(e.start.getTime() + msLength);
for (var k in event) {
if (k && k != 'start' && k != 'end' && k.charAt(0) != '_') {
e[k] = event[k];
@@ -135,14 +163,16 @@
}
}
}
- clearEvents();
+ clearEventElements();
renderEvents();
},
-
+
removeEvent: function(eventId) {
if (typeof eventId == 'object') {
eventId = eventId.id;
}
+
+ // remove from the 'events' array
var newEvents = [];
for (var i=0; i").appendTo(this);
- if (bo) {
+ if (bo) { // "button options"
var buttons = $("").appendTo(header);
var prevButton, nextButton;
if (bo == true || bo.today != false) {
todayButton = $("")
- .click(today);
+ .click(gotoToday);
if (typeof bo.today == 'string') todayButton.val(bo.today);
buttons.append(todayButton);
}
@@ -237,14 +297,13 @@
monthElement = $("")
.appendTo($("").appendTo(this));
-
+ //
+ // Build the TABLE cells for the current month. (calls event fetch+render code)
+ //
-
-
-
- var thead, tbody, glass, monthTitle;
+ var thead, tbody, glass;
function render() {
@@ -253,7 +312,7 @@
clearTime(date);
var year = date.getFullYear();
var month = date.getMonth();
- monthTitle = formatTitle(date);
+ var monthTitle = $.fullCalendar.formatDate(date, titleFormat);
if (titleElement) titleElement.text(monthTitle);
clearTime(date);
@@ -276,9 +335,14 @@
todayButton.css('visibility', 'visible');
}
}
+
+ var dayNames = $.fullCalendar.dayNames;
+ var dayAbbrevs = $.fullCalendar.dayAbbrevs;
if (!tbody) {
+ // first time, build all cells from scratch
+
var table = $("
").appendTo(monthElement);
thead = "
";
@@ -313,6 +377,8 @@
}
tbody = $(tbody + "").appendTo(table);
+ // a protective coating over the TABLE
+ // intercepts mouse clicks and prevents text-selection
glass = $("")
.appendTo(monthElement)
.click(function(ev, ui) {
@@ -324,9 +390,12 @@
});
}else{
+
+ // NOT first time, reuse as many cells as possible
var diff = numWeeks - tbody.find('tr').length;
if (diff < 0) {
+ // remove extra rows
tbody.find('tr:gt(' + (numWeeks-1) + ')').remove();
}
else if (diff > 0) {
@@ -347,6 +416,7 @@
if (trs) tbody.append(trs);
}
+ // re-label and re-class existing cells
var d = cloneDate(start);
tbody.find('tr').each(function() {
for (var i=0; i<7; i++) {
@@ -368,9 +438,11 @@
}
- resizeTable();
+ setCellSizes();
if (sniffBugs) {
+ // nasty bugs in opera 9.25
+ // position() returning relative to direct parent
var tr = tbody.find('tr');
var td = tr.find('td');
var trTop = tr.position().top;
@@ -381,37 +453,7 @@
sniffBugs = false;
}
-
- events = [];
- var completed = eventSources.length;
- var reportEvents = function(a) {
- for (var i=0; i")
+ var cl = event.className;
+ if (typeof cl == 'string') {
+ cl = ' ' + cl;
+ }
+ else if (typeof cl == 'object') {
+ cl = ' ' + cl.join(' ');
+ }
+ var element = $("
")
.append("
" +
(roundW ? "
" : '') +
"
" +
@@ -549,7 +628,6 @@
"
" +
(roundE ? "
" : '') + "
");
buildEventText(event, element.find('td.c'));
- if (event.cssClass) element.addClass(event.cssClass);
if (options.eventRender) {
var res = options.eventRender(event, element);
if (typeof res != 'undefined') {
@@ -576,9 +654,33 @@
innerDiv.height(height);
}
}
+
+
+ //
+ // create the text-contents of an event segment
+ //
+
+ function buildEventText(event, element) {
+ $("")
+ .text(event.title)
+ .appendTo(element);
+ var st = typeof event.showTime == 'undefined' ? showTime : event.showTime;
+ if (st != false) {
+ if (st == true || st == 'guess' &&
+ (event.start.getHours() || event.start.getMinutes() ||
+ event.end.getHours() || event.end.getMinutes())) {
+ var timeStr = $.fullCalendar.formatDate(event.start, timeFormat);
+ var timeElement = $("");
+ if (r2l) element.append(timeElement.text(' ' + timeStr));
+ else element.prepend(timeElement.text(timeStr + ' '));
+ }
+ }
+ }
-
+ //
+ // Attach event handlers to an event segment
+ //
function initEventElement(event, element) {
element.click(function(ev) {
@@ -607,10 +709,35 @@
}
eventElements.push([event, element]);
}
+
+
+ //
+ // Remove all event segments from DOM
+ //
+
+ function clearEventElements() {
+ for (var i=0; i")
- .text(event.title)
- .appendTo(element);
- var st = typeof event.showTime == 'undefined' ? showTime : event.showTime;
- if (st != false) {
- var h = event.start.getHours();
- var m = event.start.getMinutes();
- if (st == true || st == 'guess' && (h || m || event.end.getHours() || event.end.getMinutes())) {
- var s = '';
- for (var i=0; i");
- if (r2l) element.append(timeElement.text(' ' + s));
- else element.prepend(timeElement.text(s + ' '));
}
+ };
+ if (options.loading) {
+ options.loading(true);
+ }
+ for (var i=0; i