A jQuery plugin that sets a div to allow recording an event to an iCalendar implementation, as well as various utility functions for events. If you find this plugin useful please vote for it on the jQuery site.
The current version is 1.1.0 and is available under the GPL and MIT licences. For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.
The iCalendar specification (RFC 2445) defines a standard for 'interoperable calendaring and scheduling services for the Internet'.
The iCalendar functionality can easily be added to a division
with appropriate default settings - although you do need to specify some
of the details about the event itself. The resulting links allow the user
to post details about an event to any number of iCalendar sites.
You can also remove the iCalendar widget if it is no longer required.
Two types of iCalendar sites exist - external and local. External ones exist on the Web and are invoked via a URL. Local ones reside on your desktop and are transferred via the clipboard (default) or via a textfield or a downloadable event file.
iCalendar with everyone:
Join us for an Australia Day lunch on your local beach
from 11:30 to 12:30 on January 26, 2008.
AustDayLunch = {start: new Date(2008, 1-1, 26, 11, 30, 00),
end: new Date(2008, 1-1, 26, 12, 45, 00),
title: 'Australia Day lunch',
description: 'A traditional barbeque for our big day',
location: 'On your local beach'};
$('#defaultICal').icalendar(AustDayLunch);
$('#removeICal').toggle(function() {
$(this).text('Re-attach');
$('#defaultICal').icalendar('destroy');
},
function() {
$(this).text('Remove');
$('#defaultICal').icalendar(AustDayLunch);
}
);
You can override the defaults globally as shown below:
$.icalendar.setDefaults({tipPrefix: 'Save to '});
Processed fields are marked with a class of hasICalendar
and are not re-processed if targetted a second time.
Control the appearance of the widget.
A select few:
$('#selectICal').icalendar(
$.extend({sites: ['google', 'outlook']}, AustDayLunch));
Use a compact format:
$('#compactICal').icalendar($.extend({compact: true}, AustDayLunch));
Popup on demand:
$('#popupICal').icalendar($.extend({popup: true}, AustDayLunch));
Change on the fly:
$('#changeICal').icalendar(
$.extend({sites: ['yahoo', 'icalendar']}, AustDayLunch));
$('#changeButton').toggle(function() {
$('#changeICal').icalendar('change', {sites: ['google', 'outlook']});
},
function() {
$('#changeICal').icalendar('change', {sites: ['yahoo', 'icalendar']});
});
For sites that are not external, such as iCalendar and Outlook, the iCalendar event is used locally. By default, the event definition is copied into the clipboard so that the user can paste it elsewhere. The copy is perfomed via a Flash download to make it common across the browsers. Confirmation is required by the user prior to the copy since they may not realise that the clipboard will be used and may want to retain content already stored there.
Copy to clipboard:
$('#clipboardICal').icalendar($.extend(
{sites: ['icalendar']}, AustDayLunch));
If you set copyFlash to '' you can disable the clipboard copy.
In this case the user sees the event details in a popup dialog box.
Disable clipboard:
$('#noClipboardICal').icalendar($.extend(
{sites: ['outlook'], copyFlash: ''}, AustDayLunch));
Alternatively, you can specify a field that is to receive the iCalendar definition, instead of using the clipboard.
Copy to field:
$('#fieldICal').icalendar($.extend(
{sites: ['icalendar'], echoField: '#fieldOut'}, AustDayLunch));
Or provide a downloadable file by specifying an echo Web site that correctly identifies the file type (MIME type 'text/calendar', file extension '.ics').
Downloadable file:
$('#downloadableICal').icalendar($.extend({sites: ['outlook'],
echoUrl: 'http://keith-wood.name/iCalEcho.php'}, AustDayLunch));
The following PHP page echoes an iCalendar for you as an attachment with the correct type.
<?php
/*
* Echo an iCalendar for jquery.icalendar.js
*
* Written by Keith Wood (kbwood{at}iinet.com.au) July 2008
*/
ini_set("display_errors", 1);
error_reporting(E_ALL & ~E_NOTICE);
$content = $_GET["content"];
header("Content-length: ".strlen($content));
header("Content-type: text/calendar");
header("Content-disposition: attachment; filename=event.ics");
echo $_GET["content"];
?>
An event may recur a number of times over various periods, specified as either a set of date/times or a recurrence rule.
Use the recurrence setting to implement this in the plugin.
Look for the RDATE or RRULE entry in the
event definition below.
Recurrences:
$('#recurICal').icalendar($.extend(
{sites: ['icalendar'], echoField: '#recurOut'}, AustDayLunch));
var recurrences = [{dates: [new Date(2008, 2-1, 16), new Date(2008, 3-1, 6)]},
{times: [new Date(2008, 2-1, 16, 10, 0, 0),
new Date(2008, 3-1, 6, 12, 30, 0)]},
{periods: [[new Date(2008, 2-1, 16, 10, 0, 0),
new Date(2008, 2-1, 16, 11, 0, 0)],
[new Date(2008, 3-1, 6, 12, 30, 0), 'PT30M']]},
{freq: 'weekly'},
{freq: 'daily', interval: 2},
{freq: 'weekly', by: {type: 'day', values: ['TU', 'TH']}},
{freq: 'monthly', until: new Date(2008, 12-1, 31)},
{freq: 'monthly', count: 4},
{freq: 'monthly', by: {type: 'monthday', values: [6, 26]}}];
$('#recurrence').change(function() {
$('#recurICal').icalendar('change',
{recurrence: recurrences[$(this).val()]});
$('#recurICal a').click();
});
You can add new sites to the list as shown below.
Note: this example is not a real iCalendar site.
The parameters are the id, display name, icon URL or index, and site URL.
A special site URL of 'echo' indicates that the iCalendar definition should be
used locally. Otherwise, within the site URL use:
Add your own:
$.icalendar.addSite('another', 'Another Cal', 'img/calendar-green.gif',
'http://www.anothercal.com/add?title={t}&desc={d}' +
'&start={s}&end={e}&loc={l}');
$('#addICal').icalendar($.extend(
{sites: ['google', 'another'], compact: true}, AustDayLunch));
$('#add2ICal').icalendar($.extend(
{sites: ['google', 'another']}, AustDayLunch));
The following list shows the current sites with their IDs:
var html = '';
$.each($.icalendar.getSites(), function(id, site) {
if (id != 'another') {
html += '<li>' + id + ' - ' + site.display + '</li>';
}
});
$('#siteList').html(html);
You can format the links with a bit of CSS. The structure of the links is shown below,
where the outermost div is the container you specify in your page:
<div id="defaultICal" class="hasICalendar">
<ul class="icalendar_list">
<li><a href="Submission URL"><img src="icon.png"/> Display Name</a></li>
:
</ul>
</div>
If the list is in the compact format then the ul also has
the icalendar_compact class assigned to it and
omits the text description of the sites.
Discrete styling: Save to my calendar
$('#discreteICal').icalendar($.extend({compact: true}, AustDayLunch));
#discreteICal ul { float: left; margin-left: 10px;
background-color: transparent; border: none; }
#discreteICal li { margin: 0px 5px; }
Alternate styling:
$('#styleICal').icalendar(AustDayLunch);
#styleICal ul { float: left; border: 1px solid #247;
background: #81c7fb url(img/bookmark-bg.jpg) center; }
#styleICal li { width: auto; margin: 2px; padding: 0px 5px;
border: none; background: transparent; }
#styleICal a { color: #fff; font-weight: bold; }
Or with curvy corners:
$('#curvyCorners').corner();
$('#cornersICal').icalendar($.extend({compact: true}, AustDayLunch));
#curvyCorners { float: left; width: 84px; border: 1px solid #aaa;
background-color: #eee; padding: 2px; }
#cornersICal ul { border: none; }
This plugin provides a function for parsing the contents of an iCalendar definition.
The result is a JavaScript object that you can easily navigate for further processing,
e.g. ical.vevent.description.
Further iCalendar examples are available in the
specification.
CLASS becomes class_._value field holding the original value.Date objects where possible and are annotated
with a _type field to indicate their timezone:
UTC, float (none specified), or a name.start and end values.Parse source:
Parsed model:
$('#parseButton').click(function() {
var ical = $.icalendar.parse($('#parseInput').val());
$('#parseOutput').val($.toJSON(ical, true));
});
iCalendar allows for the definition of
durations,
for events and alarms amongst others.
They are defined as a number of weeks (PnnW),
or a number of days/hours/minutes/seconds (PnnDTnnHnnMnnS).
A duration may be prefixed by a negative sign (-) if it extends into the past.
This plugin provides two functions for dealing with these durations.
The first function calculates the duration between two date/times and returns the value formatted for use within an iCalendar.
Calculate duration: to
$('#calcDuration').click(function() {
var start = getDateTime('#date1', '#time1');
var end = getDateTime('#date2', '#time2');
$('#durationOut').val($.icalendar.calculateDuration(start, end));
});
The second function adds a duration to a start date/time to determine the end.
Add duration: plus
$('#addDuration').click(function() {
var start = getDateTime('#date3', '#time3');
var duration = $('#durationIn').val();
try {
$('#ending').val($.icalendar.addDuration(start, duration));
}
catch (e) {
alert(e);
}
});
This tab highlights examples of this plugin in use "in the wild".
None as yet.
To add another example, please contact me (kbwood{at}iinet.com.au) and provide the plugin name, the URL of your site, its title, and a short description of its purpose and where/how the plugin is used.
A full list of all possible settings is shown below. Note that not all would apply in all cases. For more detail see the documentation reference page.
$(selector).icalendar({
sites: [], // List of site IDs to use, empty for all
icons: 'icalendar.png', // Horizontal amalgamation of all site icons
iconSize: 16, // The size of the individual icons
target: '_blank', // The name of the target window for the iCalendar links
compact: false, // True if a compact presentation should be used, false for full
popup: false, // True to have it popup on demand, false to show always
popupText: 'Send to my calendar...', // Text for the popup trigger
tipPrefix: '', // Additional text to show in the tool tip for each icon
echoUrl: '', // The URL to echo back iCalendar content, or blank for clipboard
echoField: '', // The ID of a field to copy the iCalendar definition into,
// or blank for clipboard
start: null, // The start date/time of the event
end: null, // The end date/time of the event
title: '', // The title of the event
summary: '', // The summary of the event
description: '', // The description of the event
location: '', // The location of the event
url: '', // A URL with more information about the event
contact: '', // An e-mail address for further contact about the event
recurrence: null, // Details about a recurring event, an object with attributes:
// dates (Date or Date[]) or times (Date or Date[]) or
// periods (Date[2] or Date[][2] or [][Date, string]) or
// freq (string - secondly, minutely, hourly, daily, weekly, monthly, yearly),
// interval (number), until (Date), count (number), weekStart (number),
// by (object[] - type (string - second, minute, day, monthday, yearday,
// weekno, month, setpos), values (number or number[] or string or string[]))
// Confirmation message for clipboard copy
copyConfirm: 'The event will be copied to your clipboard. Continue?',
// Success message during clipboard copy
copySucceeded: 'The event has been copied to your clipboard',
// Failure message during clipboard copy
copyFailed: 'Failed to copy the event to the clipboard\n',
copyFlash: 'clipboard.swf', // The URL for the Flash clipboard copy module
// Clipboard not supported message
copyUnavailable: 'The clipboard is unavailable, please copy the event details from below:\n'
});
$.icalendar.setDefaults({...}); // Change global defaults
$.icalendar.addSite(id, display, icon, url, override); // Add a new iCalendar site
$.icalendar.getSites(); // Get the list of known iCalendar sites
$(selector).icalendar('change', settings); // Change settings for iCalendar instances
$(selector).icalendar('destroy'); // Remove iCalendar functionality
$.icalendar.formatDate(date); // Convert a date to the iCalendar format
$.icalendar.formatDateTime(dateTime, local); // Convert a date/time to the iCalendar format
$.icalendar.calculateDuration(start, end); // Get the duration between two date/times
$.icalendar.addDuration(start, duration); // Add a duration to a date/time
$.icalendar.parse(content, options); // Convert iCalendar text into a JavaScript object model
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script><style type="text/css">@import "jquery.icalendar.css";</style>
<script type="text/javascript" src="jquery.icalendar.js"></script>
Alternately, you can use the packed version
jquery.icalendar.pack.js (10.9K vs 29.6K), or the minified version
jquery.icalendar.min.js (12.3K, 4.8K when zipped).divs or spans.
$(selector).icalendar({start: ...});For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.
None as yet.
Contact Keith Wood at kbwood{at}iinet.com.au with comments or suggestions.
| Version | Date | Changes |
|---|---|---|
| 1.1.0 | 16 Jan 2010 |
|
| 1.0.0 | 25 Oct 2008 |
|