Compare commits

...

24 Commits

Author SHA1 Message Date
Adam Shaw e2f3c6e74a 1.2.3 2009-10-14 05:22:49 +00:00
Adam Shaw df4828e05d forgot to change version number 2009-09-21 09:53:03 +00:00
Adam Shaw 0a00aa0a3f gcal bug backported 2009-09-21 09:48:16 +00:00
Adam Shaw b1dfeee9e4 1.2 doc changes to legacy 2009-09-13 22:33:06 +00:00
Adam Shaw cfb6720bf7 Tagging version 1.2, to be maintained for patches/bugfixes, before moving on to 1.3 2009-07-19 02:04:35 +00:00
Adam Shaw 7d8fe1f347 forgot version string 2009-06-30 06:08:08 +00:00
Adam Shaw 2acacf8ac9 1.2.1 tested patches, modified docs 2009-06-30 06:03:15 +00:00
Adam Shaw 9a06943f52 un-unit-tested bugfixes for 1.2.1 2009-06-29 05:36:29 +00:00
Adam Shaw de10f54efb at version 1.2 2009-06-01 04:51:34 +00:00
Adam Shaw e56ffb3d99 add test suit. almost at 1.2 2009-05-31 20:56:02 +00:00
Adam Shaw 103b87ff2d 2009-05-31 05:02:41 +00:00
Adam Shaw 5c9ed310f0 2009-05-31 05:01:24 +00:00
Adam Shaw 69917fa336 2009-05-31 04:57:21 +00:00
Adam Shaw f3e8cc8d59 2009-05-31 04:49:51 +00:00
Adam Shaw e92525b9e4 2009-05-31 03:25:12 +00:00
Adam Shaw ff281feb33 almost at 1.2 2009-05-30 05:54:53 +00:00
Adam Shaw 05a4a07073 fixed weekStart bug 2009-05-25 17:26:13 +00:00
Adam Shaw d9fad7a2a7 crud for events 2009-05-18 05:36:12 +00:00
Adam Shaw f35d3648fc cssClass, beefed up events option 2009-05-17 17:41:48 +00:00
Adam Shaw 55b9ad3b70 last minute css changes (ie sucks) 2009-05-11 04:31:03 +00:00
Adam Shaw b0e089170d changed makefile, updated examples 2009-05-11 02:58:02 +00:00
Adam Shaw 26212ad377 ie6/opera9.25 bugfixes, added options, more 2009-05-10 19:48:37 +00:00
Adam Shaw aea9e567ea localization: start-of-week and right-to-left 2009-05-08 19:34:50 +00:00
Adam Shaw 7763b011f9 fixed IE JSON caching issue 2009-05-05 14:42:35 +00:00
30 changed files with 2816 additions and 1190 deletions

View File

@ -1,26 +1,38 @@
FILES =\
*.js\
*.css\
fullcalendar\
jquery\
examples
examples\
changelog.txt
VER = `cat version.txt`
DATE = `svn info . | grep Date: | sed 's/.*: //g'`
REV = `svn info . | grep Rev: | sed 's/.*: //g'`
VER = `cat version.txt`
VVER = `cat ../version.txt`
DATE = `svn info | grep Date: | sed 's/.*: //g'`
REV = `svn info | grep Rev: | sed 's/.*: //g'`
min:
@java -jar build/yuicompressor-2.4.2.jar -o build/fullcalendar.min.js fullcalendar/fullcalendar.js
zip:
@mkdir -p fullcalendar
@cp -rt fullcalendar ${FILES}
@rm -rf `find fullcalendar -type d -name .svn`
@sed -i "s/FullCalendar/& v${VER}/" fullcalendar/fullcalendar.js
@sed -i "s/Date:/& ${DATE}/" fullcalendar/fullcalendar.js
@sed -i "s/Revision:/& ${REV}/" fullcalendar/fullcalendar.js
@mkdir -p build/fullcalendar-${VER}
@cp -rt build/fullcalendar-${VER} ${FILES}
@if [ -e build/fullcalendar.min.js ];\
then cp build/fullcalendar.min.js build/fullcalendar-${VER}/fullcalendar;\
else echo "\n!!! WARNING: fullcalendar.js not yet minified.\n";\
fi
@rm -rf `find build/fullcalendar-* -type d -name .svn`
@for f in build/fullcalendar-${VER}/fullcalendar/*.js; do\
sed -i "s/* FullCalendar/& v${VER}/" $$f;\
sed -i "s/* Date:/& ${DATE}/" $$f;\
sed -i "s/* Revision:/& ${REV}/" $$f;\
done
@cd build; zip -r fullcalendar-${VVER}.zip fullcalendar-${VVER}
@mkdir -p dist
@zip -r dist/fullcalendar-${VER}.zip fullcalendar
@rm -rf fullcalendar
@mv build/fullcalendar-${VER}.zip dist
@rm -rf build/fullcalendar-${VER}
@rm -f build/fullcalendar.min.js
clean:
@rm -rf dist/*
@rm -rf build/fullcalendar-*
@rm -f build/*.js

Binary file not shown.

64
changelog.txt Normal file
View File

@ -0,0 +1,64 @@
version 1.2.3 (10/13/09)
- fixed <button> postback bug when calendar is within a <form>
version 1.2.2 (9/21/09)
- backport of gcal max-results bug
version 1.2.1 (6/29/09)
- bugfixes
- allows and corrects invalid end dates for events
- doesn't throw an error in IE while rendering when display:none
- fixed 'loading' callback when used w/ multiple addEventSource calls
- gcal className can now be an array
version 1.2 (5/31/09)
- expanded API
- 'className' CalEvent attribute
- 'source' CalEvent attribute
- dynamically get/add/remove/update events of current month
- locale improvements: change month/day name text
- better date formatting ($.fullCalendar.formatDate)
- multiple 'event sources' allowed
- dynamically add/remove event sources
- options for prevYear and nextYear buttons
- docs have been reworked (include addition of Google Calendar docs)
- changed behavior of parseDate for number strings
(now interpets as unix timestamp, not MS times)
- bugfixes
- rightToLeft month start bug
- off-by-one errors with month formatting commands
- events from previous months sticking when clicking prev/next quickly
- Google Calendar API changed to work w/ multiple event sources
- can also provide 'className' and 'draggable' options
- date utilties moved from $ to $.fullCalendar
- more documentation in source code
- minified version of fullcalendar.js
- test suit (available from svn)
- top buttons now use <button> w/ an inner <span> for better css cusomization
- thus CSS has changed. IF UPGRADING FROM PREVIOUS VERSIONS,
UPGRADE YOUR FULLCALENDAR.CSS FILE!!!
version 1.1 (5/10/09)
- Added the following options:
- weekStart
- rightToLeft
- titleFormat
- timeFormat
- cacheParam
- resize
- Fixed rendering bugs
- Opera 9.25 (events placement & window resizing)
- IE6 (window resizing)
- Optimized window resizing for ALL browsers
- Events on same day now sorted by start time (but first by timespan)
- Correct z-index when dragging
- Dragging contained in overflow DIV for IE6
- Modified fullcalendar.css
- for right-to-left support
- for variable start-of-week
- for IE6 resizing bug
- for THEAD and TBODY (in 1.0, just used TBODY, restructured in 1.1)
- IF UPGRADING FROM FULLCALENDAR 1.0, YOU MUST UPGRADE FULLCALENDAR.CSS
!!!!!!!!!!!

View File

@ -35,7 +35,7 @@ html:
arshaw:
mkdir -p build/html build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
cp -r build/html/* /var/www/arshaw/pages/fullcalendar/docs/
cp -r build/html/* /var/www/arshaw/pages/fullcalendar/docs12/
@echo
@echo "Build finished. The HTML pages are in build/html."

View File

@ -188,3 +188,6 @@ latex_documents = [
# If false, no module index is generated.
#latex_use_modindex = True
highlight_language = 'javascript'

View File

@ -1,31 +1,21 @@
.. highlight:: javascript
Main Usage
==========
Usage
=====
The following code initializes a FullCalendar within an element of 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,7 +25,7 @@ Options
Determines if all events on the calendar can be dragged & dropped. If
``true``, requires `jQuery UI <http://jqueryui.com/>`_ core and draggables.
Can be overridden on a per-event basis with the ``draggable`` property of
each :ref:`CalEvent <CalEvent>` object.
each :ref:`CalEvent <CalEvents>`.
**fixedWeeks**: boolean, default:``true``
If ``true``, the calendar will always be 6 weeks tall. If ``false``, the
@ -47,17 +37,43 @@ Options
**title**: boolean, default:``true``
Determines whether a title such as "January 2009" will be displayed at the
top of the calendar.
**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 <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.
``true`` will display a previous-month, next-month, and "today" button.
The "today" button will only be visible for months other than the current.
``false`` will display absolutely no buttons.
An object hash can be provided to display only *certain* buttons. The hash
can have the following properties::
{
today: bool/string,
prevYear: bool/string,
prevMonth: bool/string,
nextMonth: bool/string,
nextYear: bool/string
}
A value of ``false`` will not display the button. A value of ``true`` will
display the button with some default text. A *string* value will display
the button *and* customize its text.
**showTime**: boolean/ ``"guess"``, default:``"guess"``
Determines if times such as "8a" or "1p" will be displayed before each
event's title. ``"guess"`` displays times only for events with non-zero
start or end times.
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 event times. The default "gx"
creates a string such as "9a". Consult the
:ref:`$.fullCalendar.formatDate <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)
@ -66,21 +82,92 @@ 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 <CalEvents>`.
``element`` is the jQuery element that will be used by default. You may modify
this element or return a brand new element that will be used instead.
Returning ``false`` will prevent the event from being rendered at all.
This function is great for attaching other jQuery plugins to each event
element, such as a `qTip <http://craigsworks.com/projects/qtip/docs/>`_
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 <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 <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``
@ -107,81 +194,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).
.. _TriggeredEvents:
**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.
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.
**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 <TriggeredActions>`. Here are the properties of a
CalEvent:
**id**: integer/string,
Uniquely identifies the given event. Absolutely essential for multi-day
@ -197,18 +251,21 @@ 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 <EventSources>`, 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.
**end**: date (optional)
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`).
A javascript Date object indicating the date/time an event ends. This is
an **exclusive** value!!! **Example:** if an event spans two whole days,
``end`` must be the time 00:00:00 of the *third* day.
IETF and ISO8601 strings can be used for the :ref:`EventDataProvider`.
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 an :ref:`Event Source <EventSources>`).
IETF and ISO8601 strings can be used with an :ref:`Event Source <EventSources>`.
**draggable**: boolean (optional)
Overrides the master ``draggable`` property for this single event.
@ -216,20 +273,195 @@ 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 <TriggeredEvents>`.
**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/update/remove events on the current month.
For JSON and custom event sources, changes are never *permanent* because they
may be overwritten by a refetch. The developer is responsible for updating
any remote databases.
**.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 <CalEvents>` and redraw.
``calEvent`` must be the *actual CalEvent object*, as retrieved from a
:ref:`Triggered Action <TriggeredActions>` or ``getEventsById`` (see below).
A set of repeating events will all be affected.
**.fullCalendar(** ``'removeEvent'``, **calEventOrId)**
Remove elements belonging to the given :ref:`CalEvent <CalEvents>`. 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 <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(** ``'prevYear'`` **)**
Moves one year back.
**.fullCalendar(** ``'nextYear'`` **)**
Moves one year ahead.
**.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):
* **Y** - Examples: 1999 or 2003
* **y** - Examples: 99 or 03
* **F** - January through December
* **M** - Jan through Dec
* **n** - 1 through 12 (month)
* **m** - 01 through 12 (month, leading zeros)
* **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)
* **c** - 2009-06-07T05:28:21Z (ISO8601)
**$.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.

View File

@ -1,8 +1,16 @@
<? fullcalendar_docs_head() ?>
<? fullcalendar_title() ?>
<? fullcalendar_nav() ?>
<? fullcalendar_docs_nav() ?>
<? begin_content() ?>
<div id='toc'>
<h1>Table of Contents</h1>
{{ toc }}
</div>
<div class='clear'></div>
{% block body %}{% endblock %}
<? end_content() ?>
<? fullcalendar_side() ?>

View File

@ -4,7 +4,7 @@
<style type='text/css'>
body {
margin-top: 50px;
margin-top: 40px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
@ -16,11 +16,11 @@
}
</style>
<link rel='stylesheet' type='text/css' href='../fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
@ -35,7 +35,7 @@
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
start: new Date(y, m, 6, 14, 0),
end: new Date(y, m, 11)
},
{
@ -56,7 +56,7 @@
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
start: new Date(y, m, 27, 16),
end: new Date(y, m, 29),
url: "http://facebook.com/"
}

View File

@ -4,7 +4,7 @@
<style type='text/css'>
body {
margin-top: 50px;
margin-top: 40px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
@ -22,17 +22,20 @@
}
</style>
<link rel='stylesheet' type='text/css' href='../fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../fullcalendar.js'></script>
<script type='text/javascript' src='../gcal.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='../fullcalendar/gcal.js'></script>
<script type='text/javascript'>
$(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;

View File

@ -4,7 +4,7 @@
<style type='text/css'>
body {
margin-top: 50px;
margin-top: 40px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
@ -22,11 +22,11 @@
}
</style>
<link rel='stylesheet' type='text/css' href='../fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript'>
$(document).ready(function() {

View File

@ -1,728 +0,0 @@
/*
* 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
*
* 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
*
* Date:
* Revision:
*/
(function($) {
$.fn.fullCalendar = function(options) {
if (typeof options == 'string') {
var args = Array.prototype.slice.call(arguments, 1);
this.each(function() {
$.data(this, 'fullCalendar')[options].apply(this, args);
});
return this;
}
options = options || {};
var showTime = typeof options.showTime == 'undefined' ? 'guess' : options.showTime;
var bo = options.buttons;
this.each(function() {
var date = options.year ? new Date(options.year, options.month || 0, 1) : new Date();
var start, end, today, numWeeks;
var events = typeof options.events != 'string' && !$.isFunction(options.events) ?
cleanEvents(options.events) : null;
var ignoreResizes = false;
function updateMonth() {
clearEvents();
render();
}
function today() {
date = new Date();
updateMonth();
}
function prevMonth() {
addMonths(date, -1);
updateMonth();
}
function nextMonth() {
addMonths(date, 1);
updateMonth();
}
function gotoMonth(year, month) {
date = new Date(year, month, 1);
updateMonth();
}
$.data(this, 'fullCalendar', {
today: today,
prevMonth: prevMonth,
nextMonth: nextMonth,
gotoMonth: gotoMonth,
refresh: updateMonth
});
var titleElement, todayButton, monthElement;
var header = $("<div class='full-calendar-header'/>").appendTo(this);
if (bo != false) {
var buttons = $("<div class='full-calendar-buttons'/>").appendTo(header);
todayButton =
$("<input type='button' class='full-calendar-today' value='today'/>")
.click(today);
var prevButton =
$("<input type='button' class='full-calendar-prev' value='&lt;'/>")
.click(prevMonth);
var nextButton =
$("<input type='button' class='full-calendar-next' value='&gt;'/>")
.click(nextMonth);
if (typeof bo == 'object') {
if (bo.today != false) {
if (typeof bo.today == 'string') todayButton.val(bo.today);
buttons.append(todayButton);
}
if (bo.prev != false) {
if (typeof bo.prev == 'string') prevButton.val(bo.prev);
buttons.append(prevButton);
}
if (bo.next != false) {
if (typeof bo.next == 'string') nextButton.val(bo.next);
buttons.append(nextButton);
}
}else{
buttons
.append(todayButton)
.append(prevButton)
.append(nextButton);
}
}
if (options.title !== false)
titleElement = $("<h2 class='full-calendar-title'/>").appendTo(header);
monthElement = $("<div class='full-calendar-month' style='position:relative'/>").appendTo(this);
var tbody, glass, monthTitle;
function render() {
ignoreResizes = true;
date.setDate(1);
clearTime(date);
var year = date.getFullYear();
var month = date.getMonth();
monthTitle = monthNames[month] + ' ' + year;
if (titleElement) titleElement.text(monthTitle);
clearTime(date);
start = cloneDate(date);
addDays(start, -start.getDay());
end = cloneDate(date);
addMonths(end, 1);
addDays(end, (7 - end.getDay()) % 7);
numWeeks = Math.round((end.getTime() - start.getTime()) / 604800000);
if (options.fixedWeeks != false) {
addDays(end, (6 - numWeeks) * 7);
numWeeks = 6;
}
today = clearTime(new Date());
if (todayButton) {
if (today.getFullYear() == year && today.getMonth() == month) {
todayButton.css('visibility', 'hidden');
}else{
todayButton.css('visibility', 'visible');
}
}
if (!tbody) {
tbody = "<tbody><tr class='day-headings'>";
for (var i=0; i<7; i++) {
tbody +=
"<th class='day-heading " + dayAbbrevs[i].toLowerCase() + "'>" +
(options.abbrevDayHeadings!=false ? dayAbbrevs[i] : dayNames[i]) +
"</th>";
}
var d = cloneDate(start);
for (var i=0; i<numWeeks; i++) {
tbody += "<tr class='week"+(i+1)+"'>";
for (var j=0; j<7; j++) {
tbody +=
"<td class='day " + dayAbbrevs[j].toLowerCase() +
(d.getMonth() == month ? '' : ' other-month') +
(d.getTime() == today.getTime() ? ' today' : '') +
"'><div class='day-number'>" + d.getDate() + "</div>" +
"<div class='day-content'><div/></div></td>";
addDays(d, 1);
}
tbody += "</tr>";
}
tbody += "</tr></tbody>";
tbody = $(tbody)
.appendTo($("<table style='width:100%'/>")
.appendTo(monthElement));
glass = $("<div style='position:absolute;top:0;left:0;z-index:1;width:100%' />")
.appendTo(monthElement)
.click(function(ev, ui) {
if (options.dayClick) {
buildDayGrid();
var td = dayTD(ev.pageX, ev.pageY);
if (td) return options.dayClick.call(td, dayDate(td));
}
});
}else{
var diff = numWeeks - (tbody.find('tr').length - 1);
if (diff < 0) {
tbody.find('tr:gt(' + numWeeks + ')').remove();
}
else if (diff > 0) {
var trs = "";
for (var i=0; i<diff; i++) {
trs += "<tr class='week"+(numWeeks+i)+"'>";
for (var j=0; j<7; j++) {
trs +=
"<td class='day " + dayAbbrevs[j].toLowerCase() + "'>" +
"<div class='day-number'></div>" +
"<div class='day-content'><div/></div>" +
"</td>";
}
trs += "</tr>";
}
if (trs) tbody.append(trs);
}
var d = cloneDate(start);
tbody.find('td').each(function() {
if (d.getMonth() == month) {
$(this).removeClass('other-month');
}else{
$(this).addClass('other-month');
}
if (d.getTime() == today.getTime()) {
$(this).addClass('today');
}else{
$(this).removeClass('today');
}
$(this.childNodes[0]).text(d.getDate());
addDays(d, 1);
});
}
resizeTable();
if (typeof options.events == 'string') {
if (options.loading) options.loading(true);
var jsonOptions = {};
jsonOptions[options.startParam || 'start'] = Math.round(start.getTime() / 1000);
jsonOptions[options.endParam || 'end'] = Math.round(end.getTime() / 1000);
$.getJSON(options.events, jsonOptions, function(data) {
events = cleanEvents(data);
renderEvents(events);
if (options.loading) options.loading(false);
});
}
else if ($.isFunction(options.events)) {
if (options.loading) options.loading(true);
options.events(start, end,
function(data) {
events = cleanEvents(data);
renderEvents(events);
if (options.loading) options.loading(false);
});
}
else if (events) renderEvents(events);
ignoreResizes = false;
if (options.monthDisplay)
options.monthDisplay(date.getFullYear(), date.getMonth(), monthTitle);
}
var eventMatrix = [];
function renderEvents() {
eventMatrix = [];
var i = 0;
var ws = cloneDate(start);
var we = addDays(cloneDate(ws), 7);
while (ws.getTime() < end.getTime()) {
var segs = [];
$.each(events, function(j, event) {
if (event.end.getTime() > ws.getTime() && event.start.getTime() < we.getTime()) {
var ss, se, isStart, isEnd;
if (event.start.getTime() < ws.getTime()) {
ss = cloneDate(ws);
isStart = false;
}else{
ss = cloneDate(event.start);
isStart = true;
}
if (event.end.getTime() > we.getTime()) {
se = cloneDate(we);
isEnd = false;
}else{
se = cloneDate(event.end);
isEnd = true;
}
ss = clearTime(ss);
se = clearTime((se.getHours()==0 && se.getMinutes()==0) ? se : addDays(se, 1));
segs.push({
event: event, start: ss, end: se,
isStart: isStart, isEnd: isEnd, msLength: se - ss
});
}
});
segs.sort(function(a, b) { return b.msLength - a.msLength; });
var levels = [];
$.each(segs, function(j, seg) {
var l = 0; // level index
while (true) {
var collide = false;
if (levels[l]) {
for (var k=0; k<levels[l].length; k++) {
if (seg.end.getTime() > levels[l][k].start.getTime() &&
seg.start.getTime() < levels[l][k].end.getTime()) {
collide = true;
break;
}
}
}
if (collide) {
l++;
continue;
}else{
break;
}
}
if (levels[l]) levels[l].push(seg);
else levels[l] = [seg];
});
eventMatrix[i] = levels;
addDays(ws, 7);
addDays(we, 7);
i++;
}
_renderEvents();
}
var eventElements = []; // [[event, element], ...]
function _renderEvents() {
for (var i=0; i<eventMatrix.length; i++) {
var levels = eventMatrix[i];
var tr = tbody.find('tr:eq('+(i+1)+')');
var innerDiv = tr.find('td:first div.day-content div');
var top = innerDiv.position().top;
var height = 0;
for (var j=0; j<levels.length; j++) {
var segs = levels[j];
var maxh = 0;
for (var k=0; k<segs.length; k++) {
var seg = segs[k];
var event = seg.event;
var left1 = seg.isStart ?
tr.find('td:eq('+seg.start.getDay()+') div.day-content div').position().left :
tbody.position().left;
var left2 = seg.isEnd ?
tr.find('td:eq('+((seg.end.getDay()+6)%7)+') div.day-content div') :
tbody;
left2 = left2.position().left + left2.width();
var element = $("<table class='event' />")
.append("<tr>" +
(seg.isStart ? "<td class='nw'/>" : '') +
"<td class='n'/>" +
(seg.isEnd ? "<td class='ne'/>" : '') + "</tr>")
.append("<tr>" +
(seg.isStart ? "<td class='w'/>" : '') +
"<td class='c'/>" +
(seg.isEnd ? "<td class='e'/>" : '') + "</tr>")
.append("<tr>" +
(seg.isStart ? "<td class='sw'/>" : '') +
"<td class='s'/>" +
(seg.isEnd ? "<td class='se'/>" : '') + "</tr>");
buildEventText(element.find('td.c'), event,
typeof event.showTime == 'undefined' ? showTime : event.showTime);
if (options.eventRender) {
var res = options.eventRender(event, element);
if (typeof res != 'undefined') {
if (res === false) continue;
if (res !== true) element = $(res);
}
}
element
.css({
position: 'absolute',
top: top,
left: left1,
width: left2 - left1,
'z-index': 3
})
.appendTo(monthElement);
initEventElement(event, element);
var h = element.outerHeight({margin:true});
if (h > maxh) maxh = h;
}
height += maxh;
top += maxh;
}
innerDiv.height(height);
}
}
function initEventElement(event, element) {
element.click(function(ev) {
if (!element.hasClass('ui-draggable-dragging')) {
if (options.eventClick) {
var res = options.eventClick.call(this, event, ev);
if (res === false) return false;
}
if (event.url) window.location.href = event.url;
}
});
if (options.eventMouseover)
element.mouseover(function(ev) {
options.eventMouseover.call(this, event, ev);
});
if (options.eventMouseout)
element.mouseout(function(ev) {
options.eventMouseout.call(this, event, ev);
});
if (typeof event.draggable != 'undefined') {
if (event.draggable)
draggableEvent(event, element);
}
else if (options.draggable) {
draggableEvent(event, element);
}
eventElements.push([event, element]);
}
var dragStartTD, dragTD;
var dayOverlay;
function draggableEvent(event, element) {
element.draggable({
zIndex: 3,
delay: 50,
opacity: options.eventDragOpacity,
revertDuration: options.eventRevertDuration,
start: function(ev, ui) {
// hide other elements with same event
for (var i=0; i<eventElements.length; i++) {
var x = eventElements[i];
var xevent = x[0];
if (x[1].get(0) != this && (xevent == event ||
typeof xevent.id != 'undefined' && xevent.id == event.id))
x[1].hide();
}
if (!dayOverlay)
dayOverlay =
$("<div class='over-day' style='position:absolute;z-index:2' />")
.appendTo(monthElement);
buildDayGrid();
dragTD = dragStartTD = null;
eventDrag(this, ev, ui);
if (options.eventDragStart)
options.eventDragStart.call(this, event, ev, ui);
},
drag: function(ev, ui) {
eventDrag(this, ev, ui);
},
stop: function(ev, ui) {
if (!dragTD || dragTD == dragStartTD) {
// show all events
for (var i=0; i<eventElements.length; i++)
eventElements[i][1].show();
}else{
var delta = dayDelta(dragStartTD, dragTD);
for (var i=0; i<events.length; i++) {
if (event == events[i] || typeof event.id != 'undefined' && event.id == events[i].id) {
addDays(events[i].start, delta, true);
addDays(events[i].end, delta, true);
}
}
if (options.eventDrop)
options.eventDrop.call(this, event, delta, ev, ui);
clearEvents();
renderEvents();
}
dayOverlay.hide();
if (options.eventDragStop)
options.eventDragStop.call(this, event, ev, ui);
}
});
}
function eventDrag(node, ev, ui) {
var oldTD = dragTD;
dragTD = dayTD(ev.pageX, ev.pageY);
if (!dragStartTD) dragStartTD = dragTD;
if (dragTD != oldTD) {
if (dragTD) {
$(node).draggable('option', 'revert', dragTD==dragStartTD);
dayOverlay.css({
top: currTDY,
left: currTDX,
width: currTDW,
height: currTDH,
display: 'block'
});
}else{
$(node).draggable('option', 'revert', true);
dayOverlay.hide();
}
}
}
var dayX, dayY, dayX0, dayY0;
var currTD, currR, currC;
var currTDX, currTDY, currTDW, currTDH;
function buildDayGrid() {
var tr, td, o=monthElement.offset();
dayX0 = o.left;
dayY0 = o.top;
dayY = [];
tbody.find('tr:gt(0)').each(function() {
tr = $(this);
dayY.push(tr.position().top);
});
dayY.push(dayY[dayY.length-1] + tr.height());
dayX = [];
tr.find('td').each(function() {
td = $(this);
dayX.push(td.position().left);
});
dayX.push(dayX[dayX.length-1] + td.width());
currTD = null;
}
function dayTD(x, y) {
var r=-1, c=-1;
var rmax=dayY.length-1, cmax=dayX.length-1;
while (r < rmax && y > dayY0 + dayY[r+1]) r++;
while (c < cmax && x > dayX0 + dayX[c+1]) c++;
if (r < 0 || r >= rmax || c < 0 || c >= cmax)
return currTD = null;
else if (!currTD || r != currR || c != currC) {
currR = r;
currC = c;
currTD = tbody.find('tr:eq('+(r+1)+') td:eq('+c+')').get(0);
currTDX = dayX[c];
currTDY = dayY[r];
currTDW = dayX[c+1] - currTDX;
currTDH = dayY[r+1] - currTDY;
return currTD;
}
return currTD;
}
function dayDate(node) {
var i, tds = tbody.get(0).getElementsByTagName('td');
for (i=0; i<tds.length; i++) {
if (tds[i] == node) break;
}
var d = cloneDate(start);
return addDays(d, i);
}
function dayDelta(node1, node2) {
var i1, i2, tds = tbody.get(0).getElementsByTagName('td');
for (var i=0; i<tds.length; i++) {
if (tds[i] == node1) i1 = i;
if (tds[i] == node2) i2 = i;
}
return i2 - i1;
}
function resizeTable() {
var cellw = Math.floor(tbody.width() / 7);
var cellh = Math.round(cellw * .85);
tbody.find('th:lt(6)').width(cellw);
tbody.find('td').height(cellh);
glass.height(monthElement.height());
}
function clearEvents() {
for (var i=0; i<eventElements.length; i++)
eventElements[i][1].remove();
eventElements = [];
}
$(window).resize(function() {
if (!ignoreResizes) {
clearEvents();
resizeTable();
_renderEvents();
}
});
render();
});
return this;
};
// event utils
function buildEventText(element, event, showTime) {
if (showTime != false) {
var h = event.start.getHours();
var m = event.start.getMinutes();
if (showTime == true || showTime == 'guess' &&
(h || m || event.end.getHours() || event.end.getMinutes())) {
element.append($("<span class='event-time' />")
.text((h%12 || 12) + (h<12 ? 'a' : 'p') + ' '));
}
}
element.append($("<span class='event-title' />")
.text(event.title));
}
function cleanEvents(events) {
$.each(events, function(i, event) {
if (event.date) event.start = event.date;
event.start = cleanDate(event.start);
event.end = cleanDate(event.end);
if (!event.end) event.end = addDays(cloneDate(event.start), 1);
});
return events;
}
// date utils
var monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var dayNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var dayAbbrevs = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
function addMonths(d, n, keepTime) {
d.setMonth(d.getMonth() + n);
if (keepTime) return d;
return clearTime(d);
}
function addDays(d, n, keepTime) {
d.setDate(d.getDate() + n);
if (keepTime) return d;
return clearTime(d);
}
function clearTime(d) {
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);
return d;
}
function cloneDate(d) {
return new Date(+d);
}
function cleanDate(d) {
if (typeof d == 'string')
return $.parseISO8601(d, true) || Date.parse(d) || new Date(parseInt(d));
if (typeof d == 'number')
return new Date(d * 1000);
return d;
}
$.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));
if (!d) return null;
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); }
if (d[5]) { date.setDate(d[5]); }
if (d[7]) { date.setHours(d[7]); }
if (d[8]) { date.setMinutes(d[8]); }
if (d[10]) { date.setSeconds(d[10]); }
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
if (!ignoreTimezone) {
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
}
return new Date(Number(date) + (offset * 60 * 1000));
};
$.ISO8601String = function(date) {
// derived from http://delete.me.uk/2005/03/iso8601.html
var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }
return date.getUTCFullYear() +
"-" + zeropad(date.getUTCMonth() + 1) +
"-" + zeropad(date.getUTCDate()) +
"T" + zeropad(date.getUTCHours()) +
":" + zeropad(date.getUTCMinutes()) +
":" + zeropad(date.getUTCSeconds()) +
"Z";
};
})(jQuery);

View File

@ -1,36 +1,45 @@
/* top area w/ month title and buttons */
.full-calendar-header {
.full-calendar-title {
text-align: left;
}
.full-calendar-buttons {
float: right;
margin: 0 0 1em;
}
.full-calendar-buttons input {
.full-calendar-buttons button {
vertical-align: middle;
font-size: 1.0em;
margin: 0 0 0 5px;
font-size: 1em;
}
.full-calendar-prev,
.full-calendar-next {
width: 40px;
margin-left: 5px;
.full-calendar-buttons button span {
padding: 0 10px;
}
/* To always display the "today" button:
*
* .full-calendar-buttons button.today {
* visibility: visible !important;
* }
*/
/* table & borders */
/* table layout & outer border */
.full-calendar-month-wrap {
clear: both;
border: 1px solid #ccc; /* outer border color & style */
}
.full-calendar-month {
clear: both;
overflow: hidden; /*
^ prevents draggable events from leaving.
reason for our long-winded border css.
borders now look consistent across doctypes. */
border: 1px solid #ccc; /* border color & style */
width: 100%;
overflow: hidden;
}
.full-calendar-month table {
@ -38,35 +47,37 @@
border-spacing: 0;
}
.full-calendar-month th.day-heading,
/* cell styling */
.full-calendar-month th,
.full-calendar-month td.day {
padding: 0;
vertical-align: top;
border-style: solid; /* border style */
border-color: #ccc; /* border color */
border-style: solid; /* inner border style */
border-color: #ccc; /* inner border color */
border-width: 1px 0 0 1px;
}
.full-calendar-month tr.day-headings th {
.full-calendar-month th {
border-top: 0;
text-align: center;
}
.full-calendar-month th.sun,
.full-calendar-month td.sun {
.full-calendar-month th.first,
.full-calendar-month td.first {
border-left: 0;
}
/* day styling */
.full-calendar-month td.today {
background: #FFFFCC;
}
.full-calendar-month .day-number {
text-align: right;
padding-right: 2px;
padding: 0 2px;
}
.full-calendar-month .other-month .day-number {
@ -77,10 +88,14 @@
padding: 2px 2px 0; /* distance between events and day edges */
}
.full-calendar-month td.day {
/* FullCalendar automatically chooses a height, but this can be overridden: */
/* height: 100px !important; */
}
/* FullCalendar automatically chooses a cell's height,
* but this can be overridden:
*
* .full-calendar-month td.day {
* height: 100px !important;
* }
*/
@ -123,6 +138,15 @@
font-weight: bold;
}
/* To change the color of events on a per-class basis (such as with the
* "className" attribute of a CalEvent), do something like this:
*
* .full-calendar-month .myclass td {
* background: green;
* }
*/
/* the rectangle that covers a day when dragging an event */
@ -130,6 +154,31 @@
.full-calendar-month .over-day {
background: #ADDBFF;
opacity: .2;
filter: alpha(opacity=20);
filter: alpha(opacity=20); /* for IE */
}
/* right-to-left support */
.r2l .full-calendar-title {
text-align: right;
}
.r2l .full-calendar-buttons {
float: left;
}
.r2l .full-calendar-buttons button {
margin: 0 5px 0 0;
}
.r2l .full-calendar-month .day-number {
text-align: left;
}
.r2l .full-calendar-month .event {
text-align: right;
}

1259
fullcalendar/fullcalendar.js Normal file

File diff suppressed because it is too large Load Diff

71
fullcalendar/gcal.js Normal file
View File

@ -0,0 +1,71 @@
/*!
* FullCalendar Google Calendar Extension
*
* Visit http://arshaw.com/fullcalendar/docs/#google-calendar
* for docs and examples.
*
* 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
*
* Date:
* Revision:
*/
(function($) {
$.fullCalendar.gcalFeed = function(feedUrl, options) {
feedUrl = feedUrl.replace(/\/basic$/, '/full');
options = options || {};
var draggable = options.draggable || false;
return function(start, end, callback) {
$.getJSON(feedUrl + "?alt=json-in-script&callback=?",
{
'start-min': $.fullCalendar.formatDate(start, 'c'),
'start-max': $.fullCalendar.formatDate(end, 'c'),
'singleevents': true,
'max-results': 9999
},
function(data) {
var events = [];
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 showTime = entry['gd$when'][0]['startTime'].indexOf('T') != -1;
var classNames = [];
if (showTime) {
classNames.push('nobg');
}
if (options.className) {
if (typeof options.className == 'string') {
classNames.push(options.className);
}else{
classNames = classNames.concat(options.className);
}
}
events.push({
id: entry['gCal$uid']['value'],
url: url,
title: entry['title']['$t'],
start: $.fullCalendar.parseDate(entry['gd$when'][0]['startTime']),
end: $.fullCalendar.parseDate(entry['gd$when'][0]['endTime']),
location: entry['gd$where'][0]['valueString'],
description: entry['content']['$t'],
showTime: showTime,
className: classNames,
draggable: draggable
});
});
callback(events);
});
}
}
})(jQuery);

76
gcal.js
View File

@ -1,76 +0,0 @@
/*
* gcalFullCalendar extension for fullCalendar
* http://arshaw.com/fullcalendar/
*
* Same usage/options as fullCalendar.
* However, enter your Google Calendar's public feed URL in the 'events' option.
* Here is how to find it in the Google Calendar interface:
*
* -> click the arrow next to your calendar's name
* -> click "Share this calendar"
* -> check "Make this calendar public" and then Save
* -> click the arrow again, then click "Calendar settings"
* -> in the "Calendar Address" section, click the XML rectangle
* -> the URL is displayed
*
* 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($) {
$.fn.gcalFullCalendar = function(options) {
var feedURL;
if (options && typeof options.events == 'string') {
feedURL = options.events;
}
else return this;
feedURL = feedURL.replace(/\/basic$/, '/full');
$.extend(options, {
events: function(start, end, callback) {
$.getJSON(feedURL + "?alt=json-in-script&callback=?",
{
'start-min': $.ISO8601String(start),
'start-max': $.ISO8601String(end),
'singleevents': true
},
function(data) {
var events = [];
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;
});
events.push({
id: entry['gCal$uid']['value'],
url: url,
title: entry['title']['$t'],
start: $.parseISO8601(entry['gd$when'][0]['startTime'], true),
end: $.parseISO8601(entry['gd$when'][0]['endTime'], true),
location: entry['gd$where'][0]['valueString'],
description: entry['content']['$t'],
allDay: entry['gd$when'][0]['startTime'].indexOf('T') == -1,
draggable: false
});
});
callback(events);
});
},
eventRender: function(event, element) {
if (!event.allDay) element.addClass('nobg');
}
});
return this.fullCalendar(options);
};
})(jQuery);

View File

@ -1,73 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type='text/css'>
body {
margin-top: 50px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#calendar {
width: 900px;
margin: 0 auto;
}
</style>
<link rel='stylesheet' type='text/css' href='../../fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../../fullcalendar.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$('#calendar').fullCalendar({
draggable: true,
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6),
end: new Date(y, m, 11)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0)
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27),
end: new Date(y, m, 29),
url: "http://facebook.com/"
}
]
});
});
</script>
</head>
<body>
<div id='calendar'></div>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type='text/css'>
body {
margin-top: 50px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#loading {
position: absolute;
top: 5px;
right: 5px;
}
#calendar {
width: 900px;
margin: 0 auto;
}
</style>
<link rel='stylesheet' type='text/css' href='../../fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../../fullcalendar.js'></script>
<script type='text/javascript' src='../../gcal.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').gcalFullCalendar({
// US Holidays
events: 'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
eventClick: function(event) {
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
},
loading: function(bool) {
if (bool) $('#loading').show();
else $('#loading').hide();
}
});
});
</script>
</head>
<body>
<div id='loading' style='display:none'>loading...</div>
<div id='calendar'></div>
</body>
</html>

View File

@ -1,56 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type='text/css'>
body {
margin-top: 50px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#loading {
position: absolute;
top: 5px;
right: 5px;
}
#calendar {
width: 900px;
margin: 0 auto;
}
</style>
<link rel='stylesheet' type='text/css' href='../../fullcalendar.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../../fullcalendar.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').fullCalendar({
draggable: true,
events: "json_events.php",
eventDrop: function(event, delta) {
alert(event.title + ' was moved ' + delta + ' days\n' +
'(should probably update your database)');
},
loading: function(bool) {
if (bool) $('#loading').show();
else $('#loading').hide();
}
});
});
</script>
</head>
<body>
<div id='loading' style='display:none'>loading...</div>
<div id='calendar'></div>
<p>json_events.php needs to be running in the same directory.</p>
</body>
</html>

View File

@ -1,25 +0,0 @@
<?php
$year = date('Y');
$month = date('m');
echo json_encode(array(
array(
'id' => 1,
'title' => "Event1",
'start' => "$year-$month-10",
'url' => "http://yahoo.com/"
),
array(
'id' => 2,
'title' => "Event2",
'start' => "$year-$month-20",
'end' => "$year-$month-22",
'url' => "http://yahoo.com/"
)
));
?>

134
test/actions.html Normal file
View File

@ -0,0 +1,134 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$('#calendar').fullCalendar({
monthDisplay: function(year, month, monthTitle) {
$.jGrowl("<b>monthDisplay</b><br />" +
year + "-" + month + "<br />" +
monthTitle);
},
loading: function(bool) {
$.jGrowl("<b>loading</b>: " + bool);
},
resize: function() {
$.jGrowl("<b>resize</b>");
},
dayClick: function(date) {
$.jGrowl("<b>dayClick</b><br />" +
date + "<br />" +
this.nodeName);
},
eventRender: function(event, element) {
if (event.id == 3) {
//return false;
return $("<div style='background:red' />").text(event.title);
}
},
eventClick: function(event, ev) {
$.jGrowl("<b>eventClick</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
//return false;
},
/*eventMouseover: function(event, ev) {
$.jGrowl("<b>eventMouseover</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
},
eventMouseout: function(event, ev) {
$.jGrowl("<b>eventMouseout</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
this.nodeName);
},*/
eventDragStart: function(event, ev, ui) {
$.jGrowl("<b>eventDragStart</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
eventDragStop: function(event, ev, ui) {
$.jGrowl("<b>eventDragStop</b><br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
eventDrop: function(event, delta, ev, ui) {
$.jGrowl("<b>eventDrop</b><br />" +
delta + "<br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
},
draggable: true,
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6, 14, 0),
end: new Date(y, m, 11)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0)
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27, 16),
end: new Date(y, m, 29),
url: "http://facebook.com/"
}
]
});
});
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div id='calendar' style='width:75%'></div>
</body>
</html>

119
test/jgrowl/jgrowl.css Executable file
View File

@ -0,0 +1,119 @@
div.jGrowl {
padding: 10px;
z-index: 9999;
}
/** Special IE6 Style Positioning **/
div.ie6 {
position: absolute;
}
div.ie6.top-right {
right: auto;
bottom: auto;
left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
}
div.ie6.top-left {
left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
}
div.ie6.bottom-right {
left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
}
div.ie6.bottom-left {
left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
}
div.ie6.center {
left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
width: 100%;
}
/** Normal Style Positions **/
body > div.jGrowl {
position: fixed;
}
body > div.jGrowl.top-left {
left: 0px;
top: 0px;
}
body > div.jGrowl.top-right {
right: 0px;
top: 0px;
}
body > div.jGrowl.bottom-left {
left: 0px;
bottom: 0px;
}
body > div.jGrowl.bottom-right {
right: 0px;
bottom: 0px;
}
body > div.jGrowl.center {
top: 0px;
width: 50%;
left: 25%;
}
/** Cross Browser Styling **/
div.center div.jGrowl-notification, div.center div.jGrowl-closer {
margin-left: auto;
margin-right: auto;
}
div.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer {
background-color: #000;
color: #fff;
opacity: .85;
filter: alpha(opacity = 85);
zoom: 1;
width: 235px;
padding: 10px;
margin-top: 5px;
margin-bottom: 5px;
font-family: Tahoma, Arial, Helvetica, sans-serif;
font-size: 12px;
text-align: left;
display: none;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
div.jGrowl div.jGrowl-notification {
min-height: 40px;
}
div.jGrowl div.jGrowl-notification div.header {
font-weight: bold;
font-size: 10px;
}
div.jGrowl div.jGrowl-notification div.close {
float: right;
font-weight: bold;
font-size: 12px;
cursor: pointer;
}
div.jGrowl div.jGrowl-closer {
height: 15px;
padding-top: 4px;
padding-bottom: 4px;
cursor: pointer;
font-size: 11px;
font-weight: bold;
text-align: center;
}

241
test/jgrowl/jgrowl.js Executable file
View File

@ -0,0 +1,241 @@
/**
* jGrowl 1.2.0
*
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Written by Stan Lemon <stanlemon@mac.com>
* Last updated: 2009.05.11
*
* jGrowl is a jQuery plugin implementing unobtrusive userland notifications. These
* notifications function similarly to the Growl Framework available for
* Mac OS X (http://growl.info).
*
* To Do:
* - Move library settings to containers and allow them to be changed per container
*
* Changes in 1.2.0
* - Added message pooling to limit the number of messages appearing at a given time.
* - Closing a notification is now bound to the notification object and triggered by the close button.
*
* Changes in 1.1.2
* - Added iPhone styled example
* - Fixed possible IE7 bug when determining if the ie6 class shoudl be applied.
* - Added template for the close button, so that it's content could be customized.
*
* Changes in 1.1.1
* - Fixed CSS styling bug for ie6 caused by a mispelling
* - Changes height restriction on default notifications to min-height
* - Added skinned examples using a variety of images
* - Added the ability to customize the content of the [close all] box
* - Added jTweet, an example of using jGrowl + Twitter
*
* Changes in 1.1.0
* - Multiple container and instances.
* - Standard $.jGrowl() now wraps $.fn.jGrowl() by first establishing a generic jGrowl container.
* - Instance methods of a jGrowl container can be called by $.fn.jGrowl(methodName)
* - Added glue preferenced, which allows notifications to be inserted before or after nodes in the container
* - Added new log callback which is called before anything is done for the notification
* - Corner's attribute are now applied on an individual notification basis.
*
* Changes in 1.0.4
* - Various CSS fixes so that jGrowl renders correctly in IE6.
*
* Changes in 1.0.3
* - Fixed bug with options persisting across notifications
* - Fixed theme application bug
* - Simplified some selectors and manipulations.
* - Added beforeOpen and beforeClose callbacks
* - Reorganized some lines of code to be more readable
* - Removed unnecessary this.defaults context
* - If corners plugin is present, it's now customizable.
* - Customizable open animation.
* - Customizable close animation.
* - Customizable animation easing.
* - Added customizable positioning (top-left, top-right, bottom-left, bottom-right, center)
*
* Changes in 1.0.2
* - All CSS styling is now external.
* - Added a theme parameter which specifies a secondary class for styling, such
* that notifications can be customized in appearance on a per message basis.
* - Notification life span is now customizable on a per message basis.
* - Added the ability to disable the global closer, enabled by default.
* - Added callbacks for when a notification is opened or closed.
* - Added callback for the global closer.
* - Customizable animation speed.
* - jGrowl now set itself up and tears itself down.
*
* Changes in 1.0.1:
* - Removed dependency on metadata plugin in favor of .data()
* - Namespaced all events
*/
(function($) {
/** jGrowl Wrapper - Establish a base jGrowl Container for compatibility with older releases. **/
$.jGrowl = function( m , o ) {
// To maintain compatibility with older version that only supported one instance we'll create the base container.
if ( $('#jGrowl').size() == 0 ) $('<div id="jGrowl"></div>').addClass($.jGrowl.defaults.position).appendTo('body');
// Create a notification on the container.
$('#jGrowl').jGrowl(m,o);
};
/** Raise jGrowl Notification on a jGrowl Container **/
$.fn.jGrowl = function( m , o ) {
if ( $.isFunction(this.each) ) {
var args = arguments;
return this.each(function() {
var self = this;
/** Create a jGrowl Instance on the Container if it does not exist **/
if ( $(this).data('jGrowl.instance') == undefined ) {
$(this).data('jGrowl.instance', new $.fn.jGrowl());
$(this).data('jGrowl.instance').startup( this );
}
/** Optionally call jGrowl instance methods, or just raise a normal notification **/
if ( $.isFunction($(this).data('jGrowl.instance')[m]) ) {
$(this).data('jGrowl.instance')[m].apply( $(this).data('jGrowl.instance') , $.makeArray(args).slice(1) );
} else {
$(this).data('jGrowl.instance').create( m , o );
}
});
};
};
$.extend( $.fn.jGrowl.prototype , {
/** Default JGrowl Settings **/
defaults: {
pool: 0,
header: '',
group: '',
sticky: false,
position: 'top-right', // Is this still needed?
glue: 'after',
theme: 'default',
corners: '10px',
check: 250,
life: 3000,
speed: 'normal',
easing: 'swing',
closer: true,
closeTemplate: '&times;',
closerTemplate: '<div>[ close all ]</div>',
log: function(e,m,o) {},
beforeOpen: function(e,m,o) {},
open: function(e,m,o) {},
beforeClose: function(e,m,o) {},
close: function(e,m,o) {},
animateOpen: {
opacity: 'show'
},
animateClose: {
opacity: 'hide'
}
},
notifications: [],
/** jGrowl Container Node **/
element: null,
/** Interval Function **/
interval: null,
/** Create a Notification **/
create: function( message , o ) {
var o = $.extend({}, this.defaults, o);
this.notifications[ this.notifications.length ] = { message: message , options: o };
o.log.apply( this.element , [this.element,message,o] );
},
render: function( notification ) {
var self = this;
var message = notification.message;
var o = notification.options;
var notification = $('<div class="jGrowl-notification' + ((o.group != undefined && o.group != '') ? ' ' + o.group : '') + '"><div class="close">' + o.closeTemplate + '</div><div class="header">' + o.header + '</div><div class="message">' + message + '</div></div>')
.data("jGrowl", o).addClass(o.theme).children('div.close').bind("click.jGrowl", function() {
$(this).parent().trigger('jGrowl.close');
}).parent();
( o.glue == 'after' ) ? $('div.jGrowl-notification:last', this.element).after(notification) : $('div.jGrowl-notification:first', this.element).before(notification);
/** Notification Actions **/
$(notification).bind("mouseover.jGrowl", function() {
$(this).data("jGrowl").pause = true;
}).bind("mouseout.jGrowl", function() {
$(this).data("jGrowl").pause = false;
}).bind('jGrowl.beforeOpen', function() {
o.beforeOpen.apply( self.element , [self.element,message,o] );
}).bind('jGrowl.open', function() {
o.open.apply( self.element , [self.element,message,o] );
}).bind('jGrowl.beforeClose', function() {
o.beforeClose.apply( self.element , [self.element,message,o] );
}).bind('jGrowl.close', function() {
$(this).trigger('jGrowl.beforeClose').animate(o.animateClose, o.speed, o.easing, function() {
$(this).remove();
o.close.apply( self.element , [self.element,message,o] );
});
}).trigger('jGrowl.beforeOpen').animate(o.animateOpen, o.speed, o.easing, function() {
$(this).data("jGrowl").created = new Date();
}).trigger('jGrowl.open');
/** Optional Corners Plugin **/
if ( $.fn.corner != undefined ) $(notification).corner( o.corners );
/** Add a Global Closer if more than one notification exists **/
if ( $('div.jGrowl-notification:parent', this.element).size() > 1 && $('div.jGrowl-closer', this.element).size() == 0 && this.defaults.closer != false ) {
$(this.defaults.closerTemplate).addClass('jGrowl-closer').addClass(this.defaults.theme).appendTo(this.element).animate(this.defaults.animateOpen, this.defaults.speed, this.defaults.easing).bind("click.jGrowl", function() {
$(this).siblings().children('div.close').trigger("click.jGrowl");
if ( $.isFunction( self.defaults.closer ) ) self.defaults.closer.apply( $(this).parent()[0] , [$(this).parent()[0]] );
});
};
},
/** Update the jGrowl Container, removing old jGrowl notifications **/
update: function() {
$(this.element).find('div.jGrowl-notification:parent').each( function() {
if ( $(this).data("jGrowl") != undefined && $(this).data("jGrowl").created != undefined && ($(this).data("jGrowl").created.getTime() + $(this).data("jGrowl").life) < (new Date()).getTime() && $(this).data("jGrowl").sticky != true &&
($(this).data("jGrowl").pause == undefined || $(this).data("jGrowl").pause != true) ) {
$(this).trigger('jGrowl.close');
}
});
if ( this.notifications.length > 0 && (this.defaults.pool == 0 || $(this.element).find('div.jGrowl-notification:parent').size() < this.defaults.pool) ) {
this.render( this.notifications.shift() );
}
if ( $(this.element).find('div.jGrowl-notification:parent').size() < 2 ) {
$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose, this.defaults.speed, this.defaults.easing, function() {
$(this).remove();
});
};
},
/** Setup the jGrowl Notification Container **/
startup: function(e) {
this.element = $(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');
this.interval = setInterval( function() {
jQuery(e).data('jGrowl.instance').update();
}, this.defaults.check);
if ($.browser.msie && parseInt($.browser.version) < 7 && !window["XMLHttpRequest"]) $(this.element).addClass('ie6');
},
/** Shutdown jGrowl, removing it and clearing the interval **/
shutdown: function() {
$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();
clearInterval( this.interval );
}
});
/** Reference the Defaults Object for compatibility with older versions of jGrowl **/
$.jGrowl.defaults = $.fn.jGrowl.prototype.defaults;
})(jQuery);

89
test/locale.html Normal file
View File

@ -0,0 +1,89 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$.fullCalendar.monthNames = ["januari", "februari", "maart", "april", "mei", "juni","juli", "augustus", "september", "oktober", "november", "december"];
$.fullCalendar.monthAbbrevs = ["jan", "feb", "maa", "apr", "mei", "jun", "jul", "aug","sep", "okt", "nov", "dec"];
$.fullCalendar.dayNames = ['zondag', 'maandag', 'dinsdag', 'woensdag','donderdag', 'vrijdag', 'zaterdag'];
$.fullCalendar.dayAbbrevs = ["zo", "ma", "di", "wo", "do", "vr", "za", "zo"];
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
$('#calendar').fullCalendar({
abbrevDayHeadings: false,
weekStart: 1,
//rightToLeft: true,
events: [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6, 14, 0),
end: new Date(y, m, 11)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 2)
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 9)
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0)
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27, 16),
end: new Date(y, m, 29),
url: "http://facebook.com/"
}
],
draggable: true,
dayClick: function(date) {
$(this).css('background', 'lightblue');
$.jGrowl("<b>dayClick</b><br />" +
date + "<br />" +
this.nodeName);
},
eventDrop: function(event, delta, ev, ui) {
$.jGrowl("<b>eventDrop</b><br />" +
delta + "<br />" +
event.title + "<br />" +
ev.pageX + "," + ev.pageY + "<br />" +
ui);
}
});
});
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div id='calendar' style='width:75%'></div>
</body>
</html>

110
test/methods.html Normal file
View File

@ -0,0 +1,110 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<style type='text/css'>
.newclass { color: red }
</style>
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').fullCalendar({
title: false,
buttons: false,
monthDisplay: function(year, month, title) {
$('h3').text(title);
},
draggable: true
});
});
function addTestEvents() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth()+1;
if (m<10) m = '0' + m;
$('#calendar').fullCalendar('addEvent', {
id: 99,
title: 'Some event',
start: y+'-'+m+'-02'
});
$('#calendar').fullCalendar('addEvent', {
id: 99,
title: 'Some event',
start: y+'-'+m+'-09'
});
$('#calendar').fullCalendar('addEvent', {
id: 5,
title: 'Birthday',
start: y+'-'+m+'-20'
});
}
function updateTestEvents() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth()+1;
if (m<10) m = '0' + m;
var reps = $('#calendar').fullCalendar('getEventsById', 99);
var e = reps[1];
e.title = "Better Title!";
e.start = y+'-'+m+'-11';
e.end = y+'-'+m+'-13';
e.className = 'newclass';
e.draggable = false;
e.showTime = true;
$('#calendar').fullCalendar('updateEvent', e);
}
function removeTestEvents(therepeating) {
if (therepeating) {
$('#calendar').fullCalendar('removeEvent', 99);
}else{
$('#calendar').fullCalendar('removeEvent', 5);
}
}
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div style='float:right'>
<input type='button' value='add test events' onclick='addTestEvents()' /><br />
<input type='button' value='update test events' onclick='updateTestEvents()' /><br />
<input type='button' value='delete repeating events' onclick='removeTestEvents(true)' /><br />
<input type='button' value='delete single event' onclick='removeTestEvents(false)' /><br />
</div>
<h3></h3>
<p>
<a href='#' onclick="$('#calendar').fullCalendar('today')">today</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('prevMonth')">prev</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('nextMonth')">next</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('prevYear')">prevyear</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('nextYear')">nextyear</a> &nbsp;
<a href='#' onclick="$('#calendar').fullCalendar('gotoMonth', 1986, 5)">June 1986</a>
</p>
<div id='calendar' style='width:75%'></div>
</body>
</html>

99
test/options.html Normal file
View File

@ -0,0 +1,99 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<style type='text/css'>
.full-calendar-month .rep td { background: green }
.full-calendar-month .cool td { color: yellow }
.full-calendar-month .long td { background: red }
</style>
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').fullCalendar({
year: 2009,
month: 3,
draggable: true,
fixedWeeks: true,
abbrevDayHeadings: false,
//title: false,
titleFormat: 'm/Y', //'n/Y', //'M y',
//buttons: false,
//buttons: { today:false },
//buttons: { today:false, prevMonth:"prev", nextMonth:"next" },
//buttons: { today:true, prevMonth:false, nextMonth:"next" },
//buttons: { prevYear:true, nextYear:true },
//buttons: { today:true, prevYear:"py", prevMonth:true, nextMonth:true, nextYear:"ny" },
showTime: true,
timeFormat: 'ha', //'H:i', //'GA', //'gX',
eventDragOpacity: .5,
eventRevertDuration: 2000,
// test for CalEvent.source
eventDrop: function(event) {
$.jGrowl(event.source);
},
events: [
{
id: 1,
title: "Long Event",
start: new Date(2009, 3, 6, 14, 0),
end: new Date(2009, 3, 11),
showTime: false, // showTime
className: 'long',
draggable: false // draggable
},
{
id: 2,
title: "Repeating Event",
start: new Date(2009, 3, 2),
className: 'rep cool'
},
{
id: 2,
title: "Repeating Event",
start: new Date(2009, 3, 9),
className: ['rep', 'cool']
},
{
id: 3,
title: "Meeting",
date: new Date(2009, 3, 20, 9, 30) // date alias
},
{
id: 4,
title: "Click for Facebook",
start: new Date(2009, 3, 27, 16),
end: new Date(2009, 3, 29),
url: "http://facebook.com/"
}
]
});
});
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div id='calendar' style='width:75%'></div>
</body>
</html>

145
test/sources.html Normal file
View File

@ -0,0 +1,145 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<link rel='stylesheet' type='text/css' href='../fullcalendar/fullcalendar.css' />
<link rel='stylesheet' type='text/css' href='jgrowl/jgrowl.css' />
<style type='text/css'>
.full-calendar-month .static td {
background: blue;
color: yellow;
}
.full-calendar-month .gcal td {
background: lightgreen;
}
</style>
<!--
<script type='text/javascript' src='legacy_jquery/jquery.js'></script>
<script type='text/javascript' src='legacy_jquery/ui.core.js'></script>
<script type='text/javascript' src='legacy_jquery/ui.draggable.js'></script>
-->
<script type='text/javascript' src='../jquery/jquery.js'></script>
<script type='text/javascript' src='../jquery/ui.core.js'></script>
<script type='text/javascript' src='../jquery/ui.draggable.js'></script>
<script type='text/javascript' src='../fullcalendar/fullcalendar.js'></script>
<!--<script type='text/javascript' src='../build/fullcalendar.min.js'></script>-->
<script type='text/javascript' src='../fullcalendar/gcal.js'></script>
<script type='text/javascript' src='jgrowl/jgrowl.js'></script>
<script type='text/javascript'>
$(document).ready(function() {
var d = new Date();
var y = d.getFullYear();
var m = d.getMonth();
var gcalSource = $.fullCalendar.gcalFeed(
'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
{draggable: true, className: 'gcal'}
);
var staticSource = [
{
id: 1,
title: "Long Event",
start: new Date(y, m, 6, 14, 0),
end: new Date(y, m, 11),
className: 'static'
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 2),
className: 'static'
},
{
id: 2,
title: "Repeating Event",
start: new Date(y, m, 9),
className: 'static'
},
{
id: 3,
title: "Meeting",
start: new Date(y, m, 20, 9, 0),
className: 'static'
},
{
id: 4,
title: "Click for Facebook",
start: new Date(y, m, 27, 16),
end: new Date(y, m, 29),
url: "http://facebook.com/",
className: 'static'
}
];
var jsonSource = "../examples/json_events.php";
$('#calendar').fullCalendar({
draggable: true,
eventSources: [staticSource, gcalSource],
loading: function(bool) {
if (bool) {
$('#loading').css('visibility', 'visible');
}else{
$('#loading').css('visibility', 'hidden');
}
}
});
window.addStaticSource = function() {
$('#calendar').fullCalendar('addEventSource', staticSource);
};
window.addJsonSource = function() {
$('#calendar').fullCalendar('addEventSource', jsonSource);
};
window.addGcalSource = function() {
$('#calendar').fullCalendar('addEventSource', gcalSource);
};
window.removeStaticSource = function() {
$('#calendar').fullCalendar('removeEventSource', staticSource);
};
window.removeJsonSource = function() {
$('#calendar').fullCalendar('removeEventSource', jsonSource);
};
window.removeGcalSource = function() {
$('#calendar').fullCalendar('removeEventSource', gcalSource);
};
});
</script>
</head>
<body style='font-size:14px;font-family:Arial'>
<div style='float:right'>
<input type='button' value='add static event source' onclick='addStaticSource()' /><br />
<input type='button' value='* add json event source' onclick='addJsonSource()' /><br />
<input type='button' value='add gcal event source' onclick='addGcalSource()' /><br />
<br />
<input type='button' value='remove static event source' onclick='removeStaticSource()' /><br />
<input type='button' value='remove json event source' onclick='removeJsonSource()' /><br />
<input type='button' value='remove gcal event source' onclick='removeGcalSource()' /><br />
<br />
<input type='button' value='refresh' onclick="$('#calendar').fullCalendar('refresh')" />
</div>
<div style='visibility:hidden' id='loading'>loading...</div>
<div id='calendar' style='float:left;width:75%'></div>
</body>
</html>

View File

@ -1 +1 @@
1.0
1.2.3