├── _config.yml ├── examples ├── events_static.js ├── london-2012-ics.html ├── events_random.js ├── year.html ├── resource.html ├── month.html ├── day.html └── week.html ├── LICENSE.txt ├── df-calendar.jquery.json ├── docs ├── changelog.html └── index.html ├── README.markdown ├── jquery.calendar.min.css ├── jquery.calendar.css └── jquery.calendar.min.js /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-tactile -------------------------------------------------------------------------------- /examples/events_static.js: -------------------------------------------------------------------------------- 1 | /** Make sure there are always a few this week **/ 2 | var events_static = [ 3 | { 4 | uid : 1, 5 | begins : $.cal.date().addDays(2).format('Y-m-d')+' 10:10:00', 6 | ends : $.cal.date().addDays(2).format('Y-m-d')+' 12:00:00', 7 | title : 'Done', 8 | color : '#dddddd' 9 | }, 10 | { 11 | uid : 2, 12 | begins : $.cal.date().addDays(2).format('Y-m-d')+' 12:15:00', 13 | ends : $.cal.date().addDays(2).format('Y-m-d')+' 13:45:00', 14 | notes : 'Keepin\' it real…\n\nMan.' 15 | }, 16 | { 17 | uid : 3, 18 | begins : $.cal.date().addDays(3).format('Y-m-d')+' 14:15:00', 19 | ends : $.cal.date().addDays(3).format('Y-m-d')+' 16:30:00', 20 | notes : 'An event…' 21 | }, 22 | { 23 | uid : 4, 24 | begins : $.cal.date().addDays(4).format('Y-m-d')+' 11:30:00', 25 | ends : $.cal.date().addDays(4).format('Y-m-d')+' 12:30:00', 26 | color : '#990066', 27 | notes : 'The big game' 28 | }, 29 | { 30 | uid : 5, 31 | begins : $.cal.date().addDays(4).format('Y-m-d')+' 12:30:00', 32 | ends : $.cal.date().addDays(4).format('Y-m-d')+' 12:45:00', 33 | notes : 'Good-O' 34 | } 35 | ]; 36 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Custom D, https://www.customd.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /df-calendar.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "df-calendar", 3 | "version" : "1.1.1", 4 | "title" : "jQuery Calendar", 5 | "author" : { 6 | "name" : "Team DF", 7 | "email" : "plugins@teamdf.com", 8 | "url" : "http://teamdf.com/" 9 | }, 10 | "maintainers" : [ 11 | { 12 | "name" : "Sam Sehnert", 13 | "email" : "sam@teamdf.com" 14 | } 15 | ], 16 | "description" : "This plugin allows developers to implement an extremely flexible calendar interface, with very little effort. The calendar plugin can render a Day, Week, Month and Resource calendar view. The plugin also provides an interface for manipulating and formatting dates and times.", 17 | "keywords" : [ 18 | "calendar", 19 | "date", 20 | "time", 21 | "format", 22 | "events", 23 | "tasks", 24 | "drag-n-drop", 25 | "widget", 26 | "icalendar", 27 | "ics", 28 | "inline" 29 | ], 30 | "homepage" : "https://github.com/teamdf/jquery-calendar/", 31 | "docs" : "http://opensource.teamdf.com/calendar/docs/", 32 | "demo" : "http://opensource.teamdf.com/calendar/examples/week.html", 33 | "files" : ["jquery.calendar.js","jquery.calendar.min.js","jquery.calendar.css","jquery.calendar.min.css"], 34 | "dependencies" : { 35 | "jquery" : ">1.7.0" 36 | }, 37 | "licenses" : [ 38 | { 39 | "type": "MIT", 40 | "url": "http://opensource.teamdf.com/license/" 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /docs/changelog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Changelog 5 | 6 | 7 | 8 | 9 | 10 |

Calendar

11 | Sam Sehnert 12 | 1.1.0 13 | 14 |
15 |
Version 1.1.1
16 |
Improved repetition parsing from ICS data.
17 |
Improved month calendar rendering.
18 | 19 |
Version 1.1.0
20 |
Implemented repetitions.
21 | 22 |
Version 1.0.3
23 |
Added ability to specify time range in event header.
24 | 25 |
Version 1.0.2
26 |
Published jQuery Plugin Version.
27 | 28 |
Version 1.0.1
29 |
Began implementation of month calendar (unfinished).
30 |
Added basic event displacement for overlapping events.
31 |
Added .ics parser.
32 | 33 |
Version 1.0.0
34 |
Implemented date object extender.
35 |
Implemented color generator.
36 |
Implemented calendar drawing engine.
37 |
Implemented basic remove and select interactions.
38 |
Implemented basic drag and drop resizing and moving of events.
39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/london-2012-ics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - iCalendar Feed 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 47 | 48 | 62 | 63 | 64 | 65 | 66 |
67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /examples/events_random.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generate a random set of events. 3 | * 4 | * @param int min : The minimum number of random events to return. 5 | * @param int max : The maximum number of random events to return. 6 | * 7 | * @return array : An array of randomly generated event objects for 8 | * : use in the calendar. 9 | */ 10 | function randomEvents( min, max, uidsuffix, daysbefore, daysafter ) 11 | { 12 | if( !min ) min = 50; 13 | if( !max ) max = 800; 14 | if( !daysbefore ) daysbefore = -21; 15 | if( !daysafter ) daysafter = 21; 16 | if( !uidsuffix ) uidsuffix = ''; 17 | 18 | var mins = ['00','15','30','45']; 19 | var durations = [15,15,15,15,30,30,30,30,30,45,45,45,45,45,60,60,60,60,60,60,90,120,165,210,245,300,600]; 20 | var colors = [ null, null, null, null, null, null, null, null, null, null, '#dddddd', '#7E0000', '#00630F', '#00630F' ]; 21 | var notes = [ 22 | 'Meeting', 23 | 'Lunch', 24 | 'Client', 25 | 'Dentist Appointment', 26 | 'Haircut', 27 | 'Dinner', 28 | 'Meeting with Boss', 29 | 'Flight', 30 | 'The big game', 31 | 'Eye exam', 32 | 'Doctor Appointment', 33 | 'Take the car in for a service', 34 | 'Walk the dog', 35 | 'The cake is a lie', 36 | 'Party' 37 | ]; 38 | var events = [], dayadd, hour, begins; 39 | 40 | for( var e=0; e to. 65 | */ 66 | function randomBetween( from, to ) 67 | { 68 | return Math.floor(Math.random()*(to-from+1)+from); 69 | } 70 | 71 | /** 72 | * Random array item function. Used in randomEvents() 73 | * 74 | * @param array arr : returns a random array element in a numerically keyed array. 75 | * 76 | * @return string : array item. 77 | */ 78 | function randomFrom(arr) 79 | { 80 | return arr[randomBetween(0,arr.length-1)]; 81 | } -------------------------------------------------------------------------------- /examples/year.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Month Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 79 | 80 | 94 | 95 | 96 | 97 | 98 |
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | jQuery Calendar Plugin 2 | ====================== 3 | ### By Sam Sehnert, [Custom D](https://www.customd.com/) 2017 4 | 5 | This is a [jQuery](http://jquery.com/) plugin which allows developers to implement an 6 | extremely flexible calendar interface with minimal up front development. The calendar 7 | plugin can render a Day, Week, Month and Resource calendar view. 8 | 9 | Demos 10 | ----- 11 | 12 | The Demos for this plugin live under the examples/ directory. Open them directly in your web browser, or view the following online example: 13 | 14 | - [Day Calendar](https://customd.github.io/jquery-calendar/examples/day.html) 15 | - [Week Calendar](https://customd.github.io/jquery-calendar/examples/week.html) 16 | - [Month Calendar](https://customd.github.io/jquery-calendar/examples/month.html) 17 | - ['Resource' Calendar](https://customd.github.io/jquery-calendar/examples/resource.html) 18 | - [London 2012 Olympics iCalendar Feed](https://customd.github.io/jquery-calendar/examples/london-2012-ics.html) 19 | 20 | Documentation 21 | ------------- 22 | ### Basic calendar instance 23 | 24 | The calendar method can be used to create a calendar widget which will allow users to graphically see and optionally edit events. The calendar leaves data implementation up to the developer. Developers can feed event data to the calendar using a standard object notation. 25 | 26 | $('#myCalendar').cal(); 27 | 28 | The target element must be a relative or absolute positioned block level element of your choice (a ```
``` would be a typical choice). 29 | 30 | You simply specify a relative or absolutely positioned parent element, and the plugin will 31 | generate the required HTML within that element. 32 | 33 |
34 | 35 | ### Extended Date/Time powers 36 | 37 | The calendar plugin includes its own date and time formatting methods (using [PHP style masking](http://php.net/manual/en/function.date.php)). 38 | 39 | $.cal.format( new Date(), 'Y-m-d H:i:s' ); 40 | 41 | You can also perform complicated date/time arithmetic using the built in date object extender (see the [full plugin documentation](https://customd.github.io/jquery-calendar/docs) for more details). 42 | 43 | var myDate = $.cal.date( '2012-01-01 08:00:00' ); 44 | myDate.addHours(1.5).format('D, jS F Y, G:i a'); 45 | 46 | // Returns 'Sun, 1st January 2012, 9:30 am' 47 | 48 | ### Full plugin documentation 49 | 50 | The Documentation for this plugin lives under the docs/ directory. Open it directly 51 | in your web browser, or see the [online documentation](https://customd.github.io/jquery-calendar/docs). 52 | 53 | License 54 | ------- 55 | 56 | Copyright 2017, [Custom D](https://www.customd.com), 57 | Released under the [MIT license](LICENSE.t)xt. 58 | -------------------------------------------------------------------------------- /examples/resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 97 | 98 | 112 | 113 | 114 | 115 | 116 |
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /examples/month.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Month Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 100 | 101 | 192 | 193 | 194 | 195 | 196 |
197 |
    198 |
  1. 199 |
  2. 200 |
  3. 201 |
  4. 202 |
203 |

204 | 209 |
210 |
211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /examples/day.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Day Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 130 | 131 | 229 | 230 | 231 | 232 | 233 |
234 |
    235 |
  1. 236 |
  2. 237 |
  3. 238 |
  4. 239 |
240 |

241 | 246 |
247 |
248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /jquery.calendar.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery calendar 1.0.2 (c) github.com/teamdf/jquery-calendar | opensource.teamdf.com/license */ 2 | .ui-cal{overflow:hidden}.ui-cal-week .ui-cal-wrapper{position:absolute;top:22px; left:61px;bottom:0px; right:0px;background-color:#fdfdfd;overflow:scroll}.ui-cal-week .ui-cal-timeline{position:absolute;top:21px;bottom:0px;left:0px;width:60px;background-color:#D1DAE8;border-right:1px solid #b3b3b3;overflow:hidden;z-index:3}.ui-cal-week .ui-cal-timeline .ui-cal-label-time{padding-right:7px;padding-bottom:1px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ie-box-sizing:border-box}.ui-cal-week .ui-cal-timeline .ui-cal-label-time p{position:relative;top:-6px;margin:0px;padding:0px;color:#333;text-align:right;text-shadow:rgba(255,255,255,0.5) 0px 1px 0px}.ui-cal-week .ui-cal-timeline .ui-cal-label-time p span{color:#727272;font-size:.95em}.ui-cal-resources .ui-cal-wrapper,.ui-cal-resources .ui-cal-timeline{top:44px}.ui-cal-week .ui-cal-dateline,.ui-cal .ui-cal-resourceline{position:absolute;left:60px; right:0px;height:21px;color:#333;cursor:pointer;border-style:solid;border-width:0;border-bottom-width:1px;border-left-width:1px;overflow:hidden;z-index:5}.ui-cal-week .ui-cal-dateline{top:0px;background:#cacaca repeat-x 0% 0%;border-color:#b3b3b3}.ui-cal-week .ui-cal-resourceline{top:22px;background:#ebebeb repeat-x 0% 0%;border-color:#D1D3D8}.ui-cal .ui-cal-label-date,.ui-cal .ui-cal-label-resource{position:absolute;margin:0px;padding:0px;height:100%;cursor:default;font-size:1em;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ie-box-sizing:border-box}.ui-cal-week .ui-cal-label-date,.ui-cal-week .ui-cal-label-resource{margin-left:-1px}.ui-cal .ui-cal-label-date p,.ui-cal .ui-cal-label-resource p{position:absolute;top:1em;width:100%;margin:-0.5em 0 0 0;padding:0;font-size:1em;text-align:center;text-shadow:rgba(255,255,255,0.5) 0px 1px 0px;white-space:pre-wrap;cursor:pointer;overflow:hidden;text-overflow:ellipsis}.ui-cal .ui-cal-label-date .delimiter{position:absolute;height:8px;bottom:0px;width:100%;border-right:1px solid #b3b3b3}.ui-cal .ui-cal-label-resource .delimiter{position:absolute;width:100%;height:100%;border-right:1px solid #D1D3D8}.ui-cal-week .ui-cal-dateline-fill{position:absolute;top:0px; left:0px;width:100%;height:21px;color:#333;cursor:pointer;background:#cacaca repeat-x 0% 0%;border-bottom:1px solid #b3b3b3;z-index:4}.ui-cal-week .ui-cal-resourceline-fill{position:absolute;top:22px; left:0px;width:100%;height:21px;color:#333;cursor:pointer;background:#ebebeb repeat-x 0% 0%;border-bottom:1px solid #D1D3D8;z-index:4}.ui-cal .ui-cal-date{position:absolute;top:0px;border-right:1px solid #E5E5E2;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ie-box-sizing:border-box}.ui-cal .ui-cal-date.ui-cal-today{background-color:#F2F6FB}.ui-cal .ui-cal-resource{border-right:1px dotted #E5E5E2}.ui-cal-week .ui-cal-time{border-top:1px solid #ececec;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ie-box-sizing:border-box}.ui-cal-week .ui-cal-time[past="00"]{border-top:1px solid #D1D3D8}.ui-cal .ui-cal-event,.ui-cal-month .ui-cal-event.selected{position:absolute;font-size:1em;background:transparent repeat-x 0 -3px;cursor:pointer;-webkit-transition:-webkit-box-shadow 0.2s ease-in-out;-moz-transition:-moz-box-shadow 0.2s ease-in-out;transition:box-shadow 0.2s ease-in-out}.ui-cal-week .ui-cal-event.begin{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px}.ui-cal-week .ui-cal-event.end,.ui-cal .ui-cal-event.end .details{-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:5px}.ui-cal-month .ui-cal-event.begin{-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:5px;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px}.ui-cal-month .ui-cal-event.end{-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px}.ui-cal .ui-cal-event.selected{background-color:#46f;z-index:2;-webkit-box-shadow:1px 0px 30px rgba( 80,80,80,0.5 ); -moz-box-shadow:1px 0px 30px rgba( 80,80,80,0.5 ); box-shadow:1px 0px 30px rgba( 80,80,80,0.5 ); cursor:pointer}.ui-cal-month .ui-cal-event{-webkit-transition:-webkit-box-shadow 0s linear;-moz-transition:-moz-box-shadow 0s linear;transition:box-shadow 0s linear}.ui-cal .ui-cal-event .details{position:absolute;left:2px; right:2px;top:0px; bottom:0px;margin:0px; padding:3px;width:expression(this.parentNode.offsetWidth-4+'px'); height:expression(this.parentNode.offsetHeight-16+'px'); cursor:pointer;overflow:hidden;white-space:pre-wrap; word-wrap:break-word; color:#fff;font-size:1.1em;font-family:sans-serif;text-overflow:ellipsis;border:0}.ui-cal .ui-cal-event.begin .details{top:1.45em}.ui-cal .ui-cal-event.end .details{bottom:2px}.ui-cal-week .ui-cal-event .resize-top{position:absolute;top:-4px; height:9px;left:0px; width:100%;margin:0;padding:0;cursor:row-resize;z-index:1}.ui-cal-week .ui-cal-event .resize-bottom{position:absolute;bottom:-4px; height:9px;left:0px; width:100%;cursor:row-resize;margin:0;padding:0;z-index:1}.ui-cal .ui-cal-event span.button-remove{position:absolute;top:3px; right:3px;width:10px;height:10px;background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAYAAABmBXS+AAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvElEQVQYGU2QLQvCUBiF793CitH/IGhRMK34V0wu+Iu0idUoCAaLzWAYjAVtwyIDh01Qr8+Zd7ADz85533v2wYxBzrkIZnCEq3fNkc5VCGEBjb5NwJcQqpT45QPPfb7gpc+JSqkfNngMa5jACqRUpXcd/5e5/4Rpa/cKWFY6QBnoNT28gDNIlUrbOhpzx0dwghg0Szu9rg9F6/HteGMY1FXCEPbwAUl+gLEKlhBYa/VvOsy6qwsl5OyfOv8B52rwq5FQN5gAAAAASUVORK5CYII=) no-repeat 50% 50%;cursor:pointer;opacity:0.6;-webkit-transition:opacity 0.3s linear}.ui-cal .ui-cal-event span.button-remove:hover,.ui-cal .ui-cal-event.selected span.button-remove{opacity:1}.ui-cal .ui-cal-event p.title{font-weight:bold;font-size:1em;line-height:1.6em;margin:0px;margin-left:3px;margin-right:13px;padding:0px;overflow:hidden;white-space:pre;cursor:pointer;text-overflow:ellipsis}.ui-cal .ui-cal-event textarea.details{color:#222;-webkit-resize:none;resize:none;outline:none;overflow-y:auto}.ui-cal-month .ui-cal-wrapper{position:absolute;top:22px; left:0px;bottom:0px; right:0px;background-color:#fdfdfd;overflow:none}.ui-cal-month .ui-cal-dateline{position:absolute;left:0px; right:0px;top:0px;height:21px;color:#333;cursor:pointer;background:#cacaca repeat-x 0% 0%;border-bottom:1px solid #b3b3b3;overflow:hidden;z-index:4}.ui-cal-month .ui-cal-date{border-right:1px solid #E5E5E2;border-bottom:1px solid #E5E5E2}.ui-cal-month .ui-cal-date p{margin:0;padding:5px;color:#777}.ui-cal-month .ui-cal-date.non-month p{color:#ccc}.ui-cal-month .ui-cal-label-date .delimiter{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ie-box-sizing:border-box}.ui-cal .ui-cal-dateline,.ui-cal .ui-cal-dateline-fill,.ui-cal .ui-cal-event,.ui-cal .ui-cal-event.selected{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADlJREFUeNp0y6sNACAAxNALBs0ArM9QbMEnJKiD4jEvNZXtEiRVEBg2LJgwoEN7pbtlSBBBX44AAwARiCdWebcYiAAAAABJRU5ErkJggg==)}.ui-cal-week .ui-cal-resourceline,.ui-cal-week .ui-cal-resourceline-fill{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAJElEQVQIHWNgYGBQZAISf0DEXzgLwQWL/WUGyjKBCEYQQRoAACCgByRDdQsFAAAAAElFTkSuQmCC)} -------------------------------------------------------------------------------- /examples/week.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 171 | 172 | 173 | 174 | 175 |
176 |
    177 |
  1. 178 |
  2. 179 |
  3. 180 |
  4. 181 |
182 |

183 | 188 |
189 |
190 | 191 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /jquery.calendar.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery calendar plug-in 1.0.2 3 | * Copyright 2012, Digital Fusion 4 | * Licensed under the MIT license. 5 | * http://teamdf.com/jquery-plugins/license/ 6 | * 7 | * @docs http://teamdf.com/jquery-plugins/calendar/ 8 | * @author Sam Sehnert 9 | */ 10 | 11 | .ui-cal{ 12 | overflow: hidden; 13 | } 14 | 15 | .ui-cal-week .ui-cal-wrapper{ 16 | /* Styles for element that holds the days and appointments */ 17 | position: absolute; 18 | top: 22px; left: 61px; 19 | bottom: 0px; right: 0px; 20 | background-color: #fdfdfd; 21 | overflow: scroll; 22 | } 23 | 24 | .ui-cal-week .ui-cal-timeline { 25 | /* Style for left bar - contains hour labels, and scroll tools down bottom */ 26 | position: absolute; 27 | top: 21px; 28 | bottom: 0px; 29 | left: 0px; 30 | width: 60px; 31 | background-color: #D1DAE8; 32 | border-right: 1px solid #b3b3b3; 33 | overflow: hidden; 34 | z-index: 3; 35 | } 36 | 37 | .ui-cal-week .ui-cal-timeline .ui-cal-label-time{ 38 | /* hour labels for positioning. holds label text */ 39 | padding-right: 7px; 40 | padding-bottom: 1px; 41 | box-sizing: border-box; 42 | -moz-box-sizing: border-box; 43 | -webkit-box-sizing: border-box; 44 | -ie-box-sizing: border-box; 45 | } 46 | 47 | .ui-cal-week .ui-cal-timeline .ui-cal-label-time p{ 48 | /* hour label text */ 49 | position: relative; 50 | top: -6px; 51 | margin: 0px; 52 | padding: 0px; 53 | color: #333; 54 | text-align: right; 55 | text-shadow: rgba(255, 255, 255, 0.5) 0px 1px 0px; 56 | } 57 | 58 | .ui-cal-week .ui-cal-timeline .ui-cal-label-time p span{ 59 | /* hour label text for emphasis 60 | usually for AM - PM text */ 61 | color: #727272; 62 | font-size: .95em; 63 | } 64 | 65 | .ui-cal-resources .ui-cal-wrapper, 66 | .ui-cal-resources .ui-cal-timeline{ 67 | top: 44px; 68 | } 69 | 70 | .ui-cal-week .ui-cal-dateline, 71 | .ui-cal .ui-cal-resourceline{ 72 | position: absolute; 73 | left: 60px; right: 0px; 74 | height: 21px; 75 | color: #333; 76 | cursor: pointer; 77 | border-style: solid; 78 | border-width: 0; 79 | border-bottom-width: 1px; 80 | border-left-width: 1px; 81 | overflow: hidden; 82 | z-index: 5; 83 | } 84 | 85 | .ui-cal-week .ui-cal-dateline{ 86 | top: 0px; 87 | background: #cacaca repeat-x 0% 0%; 88 | border-color: #b3b3b3; 89 | } 90 | 91 | .ui-cal-week .ui-cal-resourceline{ 92 | top: 22px; 93 | background: #ebebeb repeat-x 0% 0%; 94 | border-color: #D1D3D8; 95 | } 96 | 97 | .ui-cal .ui-cal-label-date, 98 | .ui-cal .ui-cal-label-resource { 99 | /* holds date labels inside dateline div */ 100 | position: absolute; 101 | margin: 0px; 102 | padding: 0px; 103 | height: 100%; 104 | cursor: default; 105 | font-size: 1em; 106 | box-sizing: border-box; 107 | -moz-box-sizing: border-box; 108 | -webkit-box-sizing: border-box; 109 | -ie-box-sizing: border-box; 110 | } 111 | 112 | .ui-cal-week .ui-cal-label-date, 113 | .ui-cal-week .ui-cal-label-resource{ 114 | margin-left: -1px; 115 | } 116 | 117 | .ui-cal .ui-cal-label-date p, 118 | .ui-cal .ui-cal-label-resource p{ 119 | /* date text label inside the time cell */ 120 | position: absolute; 121 | top: 1em; 122 | width: 100%; 123 | margin: -0.5em 0 0 0; 124 | padding: 0; 125 | font-size: 1em; 126 | text-align: center; 127 | text-shadow: rgba(255, 255, 255, 0.5) 0px 1px 0px; 128 | white-space: pre-wrap; 129 | cursor: pointer; 130 | overflow: hidden; 131 | text-overflow: ellipsis; 132 | } 133 | 134 | .ui-cal .ui-cal-label-date .delimiter{ 135 | /* Displays a small white line to separate 136 | dateline dates. */ 137 | position: absolute; 138 | height: 8px; 139 | bottom: 0px; 140 | width: 100%; 141 | border-right: 1px solid #b3b3b3; 142 | } 143 | 144 | .ui-cal .ui-cal-label-resource .delimiter{ 145 | /* Displays a small line to separate resourceline resources */ 146 | position: absolute; 147 | width: 100%; 148 | height: 100%; 149 | border-right: 1px solid #D1D3D8; 150 | } 151 | 152 | .ui-cal-week .ui-cal-dateline-fill{ 153 | position: absolute; 154 | top: 0px; left: 0px; 155 | width: 100%; 156 | height: 21px; 157 | color: #333; 158 | cursor: pointer; 159 | background: #cacaca repeat-x 0% 0%; 160 | border-bottom: 1px solid #b3b3b3; 161 | z-index: 4; 162 | } 163 | 164 | .ui-cal-week .ui-cal-resourceline-fill{ 165 | position: absolute; 166 | top: 22px; left: 0px; 167 | width: 100%; 168 | height: 21px; 169 | color: #333; 170 | cursor: pointer; 171 | background: #ebebeb repeat-x 0% 0%; 172 | border-bottom: 1px solid #D1D3D8; 173 | z-index: 4; 174 | } 175 | 176 | .ui-cal .ui-cal-date{ 177 | /* style for day block - inside viewer, and contains time blocks */ 178 | position: absolute; 179 | top: 0px; 180 | border-right: 1px solid #E5E5E2; 181 | box-sizing: border-box; 182 | -moz-box-sizing: border-box; 183 | -webkit-box-sizing: border-box; 184 | -ie-box-sizing: border-box; 185 | } 186 | 187 | .ui-cal .ui-cal-date.ui-cal-today{ 188 | background-color: #F2F6FB; 189 | } 190 | 191 | .ui-cal .ui-cal-resource{ 192 | border-right: 1px dotted #E5E5E2; 193 | } 194 | 195 | .ui-cal-week .ui-cal-time{ 196 | /* base style for time blocks */ 197 | border-top: 1px solid #ececec; 198 | box-sizing: border-box; 199 | -moz-box-sizing: border-box; 200 | -webkit-box-sizing: border-box; 201 | -ie-box-sizing: border-box; 202 | } 203 | 204 | .ui-cal-week .ui-cal-time[past="00"]{ 205 | border-top: 1px solid #D1D3D8; 206 | } 207 | 208 | .ui-cal .ui-cal-event, .ui-cal-month .ui-cal-event.selected{ 209 | position: absolute; 210 | font-size: 1em; 211 | background: transparent repeat-x 0 -3px; 212 | cursor: pointer; 213 | -webkit-transition: -webkit-box-shadow 0.2s ease-in-out; 214 | -moz-transition: -moz-box-shadow 0.2s ease-in-out; 215 | transition: box-shadow 0.2s ease-in-out; 216 | } 217 | 218 | .ui-cal-week .ui-cal-event.begin{ 219 | -webkit-border-top-right-radius: 6px; 220 | -moz-border-radius-topright: 6px; 221 | border-top-right-radius: 6px; 222 | -webkit-border-top-left-radius: 6px; 223 | -moz-border-radius-topleft: 6px; 224 | border-top-left-radius: 6px; 225 | } 226 | 227 | .ui-cal-week .ui-cal-event.end, 228 | .ui-cal .ui-cal-event.end .details{ 229 | -webkit-border-bottom-right-radius: 6px; 230 | -moz-border-radius-bottomright: 6px; 231 | border-bottom-right-radius: 6px; 232 | -webkit-border-bottom-left-radius: 6px; 233 | -moz-border-radius-bottomleft: 6px; 234 | border-bottom-left-radius: 5px; 235 | } 236 | 237 | .ui-cal-month .ui-cal-event.begin{ 238 | -webkit-border-bottom-left-radius: 6px; 239 | -moz-border-radius-bottomleft: 6px; 240 | border-bottom-left-radius: 5px; 241 | -webkit-border-top-left-radius: 6px; 242 | -moz-border-radius-topleft: 6px; 243 | border-top-left-radius: 6px; 244 | } 245 | 246 | .ui-cal-month .ui-cal-event.end{ 247 | -webkit-border-bottom-right-radius: 6px; 248 | -moz-border-radius-bottomright: 6px; 249 | border-bottom-right-radius: 6px; 250 | -webkit-border-top-right-radius: 6px; 251 | -moz-border-radius-topright: 6px; 252 | border-top-right-radius: 6px; 253 | } 254 | 255 | .ui-cal .ui-cal-event.selected{ 256 | /* style for selected appointments */ 257 | background-color: #46f; 258 | z-index: 2; 259 | -webkit-box-shadow: 1px 0px 30px rgba( 80, 80, 80, 0.5 ); /* CSS3 */ 260 | -moz-box-shadow: 1px 0px 30px rgba( 80, 80, 80, 0.5 ); /* CSS3 */ 261 | box-shadow: 1px 0px 30px rgba( 80, 80, 80, 0.5 ); /* CSS3 */ 262 | cursor: pointer; 263 | } 264 | 265 | .ui-cal-month .ui-cal-event{ 266 | -webkit-transition: -webkit-box-shadow 0s linear; 267 | -moz-transition: -moz-box-shadow 0s linear; 268 | transition: box-shadow 0s linear; 269 | } 270 | 271 | .ui-cal .ui-cal-event .details{ 272 | /* Style for appointment details section */ 273 | position: absolute; 274 | left: 2px; right: 2px; 275 | top: 0px; bottom: 0px; 276 | margin: 0px; padding: 3px; 277 | width:expression(this.parentNode.offsetWidth-4+'px'); /* For IEs broken absolute positioning. */ 278 | height: expression(this.parentNode.offsetHeight-16+'px'); /* For IEs broken absolute positioning. */ 279 | cursor: pointer; 280 | overflow: hidden; 281 | white-space: pre-wrap; /* css-3 */ 282 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 283 | color: #fff; 284 | font-size: 1.1em; 285 | font-family: sans-serif; 286 | text-overflow: ellipsis; 287 | border: 0; 288 | } 289 | 290 | .ui-cal .ui-cal-event.begin .details{ 291 | top: 1.45em; 292 | } 293 | 294 | .ui-cal .ui-cal-event.end .details{ 295 | bottom: 2px; 296 | } 297 | 298 | .ui-cal-week .ui-cal-event .resize-top{ 299 | /* Style for appointments resize bar 300 | (hidden, only for cursor and drag handler )*/ 301 | position: absolute; 302 | top: -4px; height: 9px; 303 | left: 0px; width: 100%; 304 | margin: 0; 305 | padding: 0; 306 | cursor: row-resize; 307 | z-index: 1; 308 | } 309 | 310 | .ui-cal-week .ui-cal-event .resize-bottom{ 311 | /* Style for appointments resize bar 312 | (hidden, only for cursor and drag handler )*/ 313 | position: absolute; 314 | bottom: -4px; height: 9px; 315 | left: 0px; width: 100%; 316 | cursor: row-resize; 317 | margin: 0; 318 | padding: 0; 319 | z-index: 1; 320 | } 321 | 322 | .ui-cal .ui-cal-event span.button-remove{ 323 | position: absolute; 324 | top: 3px; right: 3px; 325 | width: 10px; 326 | height: 10px; 327 | background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAYAAABmBXS+AAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvElEQVQYGU2QLQvCUBiF793CitH/IGhRMK34V0wu+Iu0idUoCAaLzWAYjAVtwyIDh01Qr8+Zd7ADz85533v2wYxBzrkIZnCEq3fNkc5VCGEBjb5NwJcQqpT45QPPfb7gpc+JSqkfNngMa5jACqRUpXcd/5e5/4Rpa/cKWFY6QBnoNT28gDNIlUrbOhpzx0dwghg0Szu9rg9F6/HteGMY1FXCEPbwAUl+gLEKlhBYa/VvOsy6qwsl5OyfOv8B52rwq5FQN5gAAAAASUVORK5CYII=) no-repeat 50% 50%; 328 | cursor: pointer; 329 | opacity: 0.6; 330 | -webkit-transition: opacity 0.3s linear; 331 | } 332 | 333 | .ui-cal .ui-cal-event span.button-remove:hover, 334 | .ui-cal .ui-cal-event.selected span.button-remove{ 335 | opacity: 1; 336 | } 337 | 338 | .ui-cal .ui-cal-event p.title{ 339 | /* style for time display in appointments */ 340 | font-weight: bold; 341 | font-size: 1em; 342 | line-height: 1.6em; 343 | margin: 0px; 344 | margin-left: 3px; 345 | margin-right: 13px; 346 | padding: 0px; 347 | overflow: hidden; 348 | white-space: pre; 349 | cursor: pointer; 350 | text-overflow: ellipsis; 351 | } 352 | 353 | .ui-cal .ui-cal-event textarea.details{ 354 | /* Style for textarea which allows user to edit 355 | the description for an appointment */ 356 | color: #222; 357 | -webkit-resize: none; 358 | resize: none; 359 | outline: none; 360 | overflow-y: auto; 361 | } 362 | 363 | 364 | 365 | .ui-cal-month .ui-cal-wrapper{ 366 | /* Styles for element that holds the days and appointments */ 367 | position: absolute; 368 | top: 22px; left: 0px; 369 | bottom: 0px; right: 0px; 370 | background-color: #fdfdfd; 371 | overflow: none; 372 | } 373 | 374 | .ui-cal-month .ui-cal-dateline{ 375 | position: absolute; 376 | left: 0px; right: 0px; 377 | top: 0px; 378 | height: 21px; 379 | color: #333; 380 | cursor: pointer; 381 | background: #cacaca repeat-x 0% 0%; 382 | border-bottom: 1px solid #b3b3b3; 383 | overflow: hidden; 384 | z-index: 4; 385 | } 386 | 387 | .ui-cal-month .ui-cal-date{ 388 | /* style for day block - inside viewer, and contains time blocks */ 389 | border-right: 1px solid #E5E5E2; 390 | border-bottom: 1px solid #E5E5E2; 391 | } 392 | 393 | .ui-cal-month .ui-cal-date p { 394 | margin: 0; 395 | padding: 5px; 396 | color: #777; 397 | } 398 | 399 | .ui-cal-month .ui-cal-date.non-month p { 400 | color: #ccc; 401 | } 402 | 403 | .ui-cal-month .ui-cal-label-date .delimiter{ 404 | box-sizing: border-box; 405 | -moz-box-sizing: border-box; 406 | -webkit-box-sizing: border-box; 407 | -ie-box-sizing: border-box; 408 | } 409 | 410 | .ui-cal .ui-cal-dateline, 411 | .ui-cal .ui-cal-dateline-fill, 412 | .ui-cal .ui-cal-event, 413 | .ui-cal .ui-cal-event.selected{ 414 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADlJREFUeNp0y6sNACAAxNALBs0ArM9QbMEnJKiD4jEvNZXtEiRVEBg2LJgwoEN7pbtlSBBBX44AAwARiCdWebcYiAAAAABJRU5ErkJggg==); 415 | } 416 | .ui-cal-week .ui-cal-resourceline, 417 | .ui-cal-week .ui-cal-resourceline-fill{ 418 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAUCAYAAABMDlehAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAJElEQVQIHWNgYGBQZAISf0DEXzgLwQWL/WUGyjKBCEYQQRoAACCgByRDdQsFAAAAAElFTkSuQmCC); 419 | } 420 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Calendar - Documentation 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 46 | 47 | 80 | 81 | 82 | 83 | 84 |

Calendar

85 | Sam Sehnert, Digital Fusion. 86 | 1.1.1 (changelog) 87 | © Digital Fusion 2012, MIT 88 | 89 |

This is a jQuery plugin which allows developers to implement an extremely flexible calendar interface with minimal up front development.

90 | 91 |

Contents

92 | 100 | 101 |

Getting Started

102 | 103 |

The calendar method can be used to create a calendar widget which will allow users to graphically see and optionally edit events. The calendar leaves data implementation up to the developer. Developers can feed event data to the calendar using a standard object notation.

104 | $(function(){ 105 | $('#myCalendar').cal(); 106 | } 107 |

The target element must be a relative or absolute positioned block level element of your choice.

108 | 109 |

You simply specify a relative or absolutely positioned parent element (a <div /> would be a typical choice), and the plugin will generate the required HTML within that element.

110 |

The HTML structure that the plugin generates is relatively complicated, and can vary depending on the setup options you've chosen, but a typical configuration will result in the following basic HTML:

111 | <div class="ui-cal ui-cal-container"> 112 | <div class="ui-cal-timeline"><!-- Contains time labels (vertical) --></div> 113 | <div class="ui-cal-dateline"><!-- Contains date labels (horizontal) --></div> 114 | <div class="ui-cal-dateline-fill" /> 115 | <div class="ui-cal-wrapper"><!-- Contains 'increment' grid blocks --></div> 116 | </div> 117 | 118 |

You can also use methods implemeneted by this plugin for formatting dates and times using the built in format method.

119 | $(function(){ 120 | $.cal.format( new Date(), 'Y-m-d H:i:s' ); // OR 121 | $.cal.date().format( 'Y-m-d H:i:s' ); // Outputs '1986-04-21 08:00:00' if the current time was 8am on the 21st April 1986. 122 | } 123 | 124 |

Demo

125 | 126 |

Basic Calendar Setup

127 |

This is the minimum config you'll need to generate a useful, read only calendar (in fact, you can omit the startdate and daystodisplay, but in most cases you'll want control over which dates are being displayed. In this example, we're using a static array of event objects to populate the calendar with events.

128 | 129 |
130 | 156 |
157 |
158 | 159 |

JavaScript

160 | $(function(){ 161 | $('div.calendar').cal({ 162 | 163 | startdate : '2011-08-01', 164 | daystodisplay : 5, 165 | 166 | events : [ 167 | { 168 | uid : 1, 169 | begins : '2011-08-04 10:00:00', 170 | ends : '2011-08-04 11:30:00', 171 | notes : 'Testing...', 172 | color : 'purple' 173 | }, 174 | { 175 | uid : 2, 176 | begins : '2011-08-03 11:00:00', 177 | ends : '2011-08-03 13:45:00', 178 | title : 'Test' 179 | } 180 | ] 181 | }); 182 | }); 183 |

HTML

184 | <div class="calendar"></div> 185 | 186 |

Multiple Calendar Setup

187 |

This syntax allows you to display events from multiple sources in the same calendar layout. This is especially useful when combining events from shared ics feeds, and your own sources.

188 | 189 |

JavaScript

190 | $(function(){ 191 | $('div.calendar').cal({ 192 | 193 | startdate : '2011-08-01', 194 | daystodisplay : 5, 195 | 196 | calendars : [ 197 | 198 | // Calendar source 1 199 | [ 200 | { 201 | uid : '1@cal1', 202 | begins : '2011-08-04 08:00:00', 203 | ends : '2011-08-04 09:30:00', 204 | notes : 'Calendar 1...', 205 | color : 'purple' 206 | } 207 | ], 208 | 209 | // Calendar source 2 210 | [ 211 | { 212 | uid : '1@cal1', 213 | begins : '2011-08-04 10:00:00', 214 | ends : '2011-08-04 11:30:00', 215 | notes : 'Calendar 2...', 216 | color : 'green' 217 | } 218 | ] 219 | ] 220 | }); 221 | }); 222 | 223 |

More Demos

224 | 231 | 232 |

Configuration Properties

233 |
234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 |
PropertyDefaultDescription
startdate*current date*The first date to display on the calendar, defined as either ISO8601 (e.g., '2011-08-01' for first of August 2011) or as a JavaScript date object.
daystodisplay7The number of days in total to display on the calendar.
defaultcolor'#255BA1'The default color to use for an event, where no other color is given in the event object.
maskeventlabel'g:i A'The date mask used to format the start time shown on an event element. When a title is specified on an event object, it is displayed instead of the formatted time.
maskeventlabeldelimiter''A string to be used as a delimiter between 'maskeventlabel' and 'maskeventlabelend'. Usually a dash padded with spaces.
maskeventlabelend''The date mask used to format the end time shown on an event element. When a title is specified on an event object, it is displayed instead of the formatted time.
maskmonthlabel'l'The date mask used to format the week labels shown on the month calendar.
maskdatelabel'D, jS'The date mask used to format the date labels shown at the top of the calendar.
masktimelabel
{
249 |     '00'    : 'g:i <\\sp\\a\\n>A<\/\\sp\\a\\n>',
250 |     'noon'  : '\\N\\O\\O\\N'
251 | }
An object containing the date masks used to format the time labels shown at the left of the calendar. The property names specify where the label is to be used, for example, '00' refers to all labels that fall on the hour, '30' refers to all labels that fall on the half hour.
daytimestart'00:00:00'Defines the time that the calendar starts drawing the day. E.g., A setting of '08:00:00' would cause the calendar to draw all hours starting from 8 am through to the daytimeend.
daytimeend'24:00:00'Defines the time that the calendar finishes drawing the day. E.g., A setting of '18:00:00' would cause the calendar to draw all hours starting from daytimestart through to 6 pm.
minwidth120The minimum width in pixels of the each day column.
minheight*calculated*The minimum height in pixels of each grid row. The default is calculated so that 1 pixel represents 1 minute (i.e., an hour will be 60 pixels).
gridincrement'15 mins'Defined the spacing of the grid lines. E.g., A setting of '30 mins' would create a grid line for every 30 minute increment.
allowmovefalseWhen set to true, allows the user to drag an event to a new location on the screen. Most useful with the 'eventmove' event.
allowresizefalseWhen set to true, allows the user to drag handles located at the top and bottom of an event to resize. Most useful with the 'eventresize' event.
allowselectfalseWhen set to true, allows the user to select an event by single clicking. Most useful with the 'eventselect' event.
allowremovefalseWhen set to true, displays a (x) icon in the top right of an event, which removes the event when clicked. Most useful with the 'eventremove' event.
265 |
266 | 267 |

Configuration

268 |

Config data can be passed when you first initialise the object, as shown in the demo above. Additionally, you can use the 'option' method to apply or modify config properties.

269 | 270 |

Date Masks

271 |

Use the php date characters to create your date mask. Be aware when writing your date mask, that any masked characters will need to be double backslashed in the JavaScript source, as demonstrated below. Non masked characters don't need to be escaped.

272 | 273 |
274 | 282 |

283 |
284 | $(function(){ 285 | setInterval(function(){ 286 | var time = $.cal.date().format( 'Y-m-d<b\\r />g\\h i\\m s\\s a' ); 287 | $('p.output').html( time ); 288 | }, 1000 ); 289 | }); 290 |

Most, but not all of the mask characters implemented in PHP are avaialable due to technical limitations with JavaScript dates. When using an incompatible mask character, an error will be printed in the console log.

291 | 292 |

The masktimelabel property

293 |

The masktimelabel object is available as a flexible way of formatting the time labeles that appear to the left of the calendar. The property names specify where the label is to be used, for example, '00' refers to all labels that fall on the hour, '30' refers to all labels that fall on the half hour, and in a special case, 'noon' refers to 12:00 PM specifically.

294 | 295 |
296 | 321 |
322 |
323 |
324 |
325 | // Left calendar 326 | $('#div.calendar1').cal({ 327 | masktimelabel : { 328 | '00' : 'g:i a' 329 | } 330 | }); 331 | 332 | // Center calendar 333 | $('#div.calendar2').cal({ 334 | masktimelabel : { 335 | '00' : 'g:i a', 336 | '30' : '<\\sp\\a\\n>30<\/\\sp\\a\\n>' 337 | } 338 | }); 339 | 340 | // Right calendar 341 | $('#div.calendar3').cal({ 342 | masktimelabel : { 343 | '00' : 'g:i <\\sp\\a\\n>A<\/\\sp\\a\\n>', 344 | '15' : '<\\sp\\a\\n>15<\/\\sp\\a\\n>', 345 | '30' : '<\\sp\\a\\n>g:30<\/\\sp\\a\\n>', 346 | '45' : '<\\sp\\a\\n>15<\/\\sp\\a\\n>', 347 | 'noon' : '\\N\\O\\O\\N' 348 | } 349 | }); 350 |

The <span /> tags wrap text that we want to show in the lighter grey; this style is defined in jquery.calendar.css.

351 | 352 |

The gridincrement setting

353 |

The gridincrement setting allows you to specify where the grid lines appear on the calendar.

354 | 355 |
356 | 367 |
368 |
369 |
370 | 371 | // Left calendar 372 | $('#demo4 div.calendar1').cal({ 373 | gridincrement : '30 mins' 374 | }); 375 | 376 | // Right calendar 377 | $('#demo4 div.calendar2').cal({ 378 | gridincrement : '1 hour' 379 | }); 380 | 381 | 382 |

Events

383 |
384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 |
EventParametersDetails
eventmoveString, Object, CollectionCalled when the user finishes a drag operation.
Recieves the events UID as passed in the original event object, the data object which represents the appointment, and a jQuery collection containing the event element.
eventresizeString, Object, CollectionCalled when the user finishes a resize operation.
Recieves the events UID as passed in the original event object, the data object which represents the appointment, and a jQuery collection containing the event element.
eventselectString, Object, CollectionCalled when the user clicks on an event.
Recieves the events UID as passed in the original event object, the data object which represents the appointment, and a jQuery collection containing the event element.
Return false from the callback function to prevent selection.
eventremoveString, Object, CollectionCalled when the user clicks on an events remove button.
Recieves the events UID as passed in the original event object, the data object which represents the appointment, and a jQuery collection containing the event element.
Return false from the callback function to prevent removal.
eventeditnotesString, Object, CollectionCalled when the user edits the notes of an event using the inline editing feature.
Recieves the events UID as passed in the original event object, the data object which represents the appointment, and a jQuery collection containing the event element.
396 |
397 | 398 |

Event: eventselect

399 |

In this example, we show how the eventselet event can be used to display details about the selected appointment. We also see how we can prevent selection by returning false in the hanlder function.

400 |
401 | 424 |
425 |

Click an event to select.

426 |
427 |
428 | $('div.calendar').cal({ 429 | events : demoevents, 430 | allowselect : true, 431 | eventselect : function( uid, $event ){ 432 | if( uid == 1 ){ 433 | 434 | alert('Sorry, this event cannot be selected.'); 435 | return false; 436 | 437 | } else { 438 | $('p.output').text( 'You selected event #'+uid ); 439 | $('table').html( 440 | '<tr><td>Begins</td><td>'+$event.data('cal').begins.format('g:i a')+'</td></tr>'+ 441 | '<tr><td>>Ends</td><td>'+$event.data('cal').ends.format('g:i a')+'</td></tr>' 442 | ); 443 | } 444 | } 445 | }); 446 | 447 |

Event: eventremove

448 |

In this example, we show how the eventremove event can be used to perform an action (such as sending of an AJAX request to update the database) when the user clicks the delete button. It also demonstrates that we can prevent the deletion by returning false in the handler function.

449 |
450 | 468 |
469 |

470 |
471 | $('div.calendar').cal({ 472 | events : demoevents, 473 | allowremove : true, 474 | eventremove : function( uid ){ 475 | if( uid == 1 ){ 476 | 477 | alert('Sorry, this event cannot be removed.'); 478 | return false; 479 | 480 | } else { 481 | $('p.output').text( 'You removed event #'+uid ); 482 | } 483 | } 484 | }); 485 | 486 | 487 |

Methods

488 |
489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 |
MethodReturnsDescription
.cal( 'option', [ Object ] )
.cal( 'option', [ String, String ] )
jQuery
String
Takes a config object, or config string/value and applies the configuration option to the calendar.
.cal( 'version' )StringReturns the version number of the currently installed calendar plugin.
.cal( 'destroy' )jQueryRemoves the calendar from the targeted element, and returns the element to its pre-initialisation state.
$.cal.date( [ Date ] )DateTakes a date object, and returns an extended date object. See the associated documentation for more details on the date methods.
$.cal.format( [ Date ] )StringTakes a date object, and returns a formatted string, according to the passed mask.
$.cal.incrementsIn( String, String )NumberTakes two strings representing a portion of time, (E.g., '15 mins' or '2 hours' ), and returns the number of times the second increment fits inside the first.
For example, $.cal.incrementsIn('1 hour','15 mins') returns 4.
502 |
503 | 504 |

Compatibility

505 |

This plugin has been tested, and verified working in the following browsers with JavaScript enabled.

506 |

That doesn't mean it doesn't work in other browsers, it just means we haven't tested it yet!

507 |
    508 |
  • Safari 5.1+
  • 509 |
510 | 511 | jQuery Browser Compatibility 512 | 513 | 514 | 515 | -------------------------------------------------------------------------------- /jquery.calendar.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery calendar 1.1.1 (c) github.com/teamdf/jquery-calendar | opensource.teamdf.com/license */ 2 | (function(e){"use strict";var t="cal";var n="1.1.1";var r="month";var s="week";var o={startdate:null,daystodisplay:null,startweek:null,startmonth:null,startyear:null,monthstodisplay:null,defaultcolor:"#255BA1",invalidcolor:"#888888",maskmonthlabel:"l",maskeventlabel:"g:i A",maskeventlabeldelimiter:"",maskeventlabelend:"",maskdatelabel:"D, jS",masktimelabel:{"00":"g:i <\\sp\\a\\n>A",noon:"\\N\\O\\O\\N"},resources:false,minwidth:130,minheight:null,overlapoffset:15,daytimestart:"00:00:00",daytimeend:"24:00:00",weekstart:1,dragincrement:"15 mins",gridincrement:"15 mins",creationsize:"15 mins",allowcreation:"both",allowmove:false,allowresize:false,allowselect:false,allowremove:false,allowoverlap:false,allownotesedit:false,allowhtml:false,easing:{eventupdate:"linear",eventremove:"linear",eventeditin:"linear",eventeditout:"linear",datechange:"linear"},eventcreate:e.noop,eventnotesedit:e.noop,eventremove:e.noop,eventselect:e.noop,eventmove:e.noop,eventresize:e.noop,eventdraw:e.noop,dayclick:e.noop,daydblclick:e.noop,onload:e.noop};var u={prevent:function(e){e.preventDefault()},scrollbarSize:function(){if(!u._scrollbarSize){var t=e(document.body),n=t.css({overflow:"hidden"}).width();n-=t.css({overflow:"scroll"}).width();if(!n)n=t.width()-t[0].clientWidth;t.css({overflow:""});u._scrollbarSize=n}return u._scrollbarSize},_scrollbarSize:false,selectrange:function(e,t){return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,t)}else if(this.createTextRange){var n=this.createTextRange();n.collapse(true);n.moveEnd("character",t);n.moveStart("character",e);n.select()}})},onscroll:function(n){var r=e(this),i=r.parent(".ui-"+t+"-container"),s=r.scrollLeft(),o=r.scrollTop(),u=i.data(t);if(u){i.find(".ui-"+t+"-timeline").scrollTop(o);i.find(".ui-"+t+"-dateline").scrollLeft(s);i.find(".ui-"+t+"-resourceline").scrollLeft(s)}},between:function(e,t,n){if(e instanceof Date){var r=e.getTime();return r>=t.getTime()&&r<=n.getTime()}else if(!isNaN(Number(e))){return e>=t&&e<=n}return false},inrange:function(e,t,n,r){return!(t.getTime()r.getTime())},resource:function(e,t){var n=0;if(t.settings.resources!==false){for(var r in t.settings.resources){if(t.settings.resources.hasOwnProperty(r)){if(n==e){return{id:r,name:t.settings.resources[r]}}n++}}}return{id:null,name:null}},resourceIndex:function(t,n){var r=0;if(n.settings.resources!==false){if(e.isArray(n.settings.resources)){for(var i in n.settings.resources){if(n.settings.resources[i]==t){return r}r++}}else{for(var i in n.settings.resources){if(n.settings.resources.hasOwnProperty(i)){if(i==t){return r}r++}}}}return false},repetitions:function(n,r){var i=[],s,o,u,a,f,l,c;e:for(var h in r.repeat.rules.include){s=r.repeat.rules.include[h];o=r.begins>n.settings.startdate?r.begins:n.settings.startdate;u="until"in s?e[t].date(s.until):n.cache.enddate,a="interval"in s?+s.interval:1;if(r.begins>n.cache.enddate||u<=n.settings.startdate)continue;if("freq"in s){switch(s.freq){case"daily":f=a+" Day";break;case"weekly":f=a+" Week";break;case"monthly":f=a+" Month";break;case"yearly":f=a+" Year";break;default:continue e}l=r.begins.copy();if(r.beginsn&&a[f].resource===i){a[f].overlap={partial:true,inset:0,count:0,index:0,items:{},uid:f};u.push(a[f])}}if(u.length>1){var l=0;u.sort(function(e,t){return e.begins.getTime()-t.begins.getTime()});for(var c in u){if(u.hasOwnProperty(c)){u[c].overlap.index=l++;for(var h in u){if(c===h)continue;if(u.hasOwnProperty(h)&&!(u[c].overlap.uid in u[h].overlap.items)&&!(u[h].overlap.uid in u[c].overlap.items)&&u[c].beginsu[h].begins&&u[c].resource===u[h].resource){u[c].overlap.items[u[h].overlap.uid]=u[h];u[h].overlap.items[u[c].overlap.uid]=u[c];u[c].overlap.count++;u[h].overlap.count++;if(u[c].begins.getTime()==u[h].begins.getTime()){u[c].overlap.partial=false;u[h].overlap.partial=false;u[h].overlap.inset=u[c].overlap.inset+1}else if(u[c].begins.getTime()0;h--){var p=i.folds.exec(a[h]);if(p){a[h-1]+=p[1];a[h]=""}}e.each(a,function(n,u){if(!u)return;switch(s){case"cal_begin":if(u.indexOf("BEGIN:VCALENDAR")==-1)throw new r("Expecting BEGIN:VCALENDAR but found '"+u+"' instead.",n,u);l={events:[]};s="cal_info";break;case"cal_info":if(u.indexOf("BEGIN:VEVENT")==0){f=e.extend(true,{},c);s="cal_event"}if(u.indexOf("END:VCALENDAR")==0){o.push(l);s="done"}if(s!=="cal_info")return;break;case"cal_event":if(u.indexOf("END:VEVENT")==0){l.events.push(f);s="cal_info"}if(s!=="cal_event")return;var a=i.entry.exec(u);if(!a){throw new r("Missing entry name.",n,u)}switch(a[1].toLowerCase()){case"uid":f.uid=a[3];break;case"dtstart":f.begins=e[t].date(a[3]);break;case"dtend":f.ends=e[t].date(a[3]);break;case"summary":f.title=a[3].replace(/\\([;,])/g,"$1").replace(/\\n/g,"\n");break;case"description":f.notes=a[3].replace(/\\([;,])/g,"$1").replace(/\\n/g,"\n");break;case"rrule":f.repeat.rules.include.push(i._rrule(a[3]));break;case"exrule":f.repeat.rules.exclude.push(i._rrule(a[3]));break;case"rdate":f.repeat.dates.include.push(e[t].date(a[3]));break;case"exdate":f.repeat.dates.exclude.push(e[t].date(a[3]));break}break}});if(s!=="done")throw new r("Unexpected end of file. Expecting END:VCALENDAR.",a.length,"");return o.length>0?o.pop():false}},event:{calculateElementCount:function(e){return Math.ceil(e.cache.begins.getDaysBetween(e.cache.ends,true))},update:function(n,r,i){var s=e(this),o=s.data(t),a=o&&o.calendar?o.calendar.data(t):false;if(a&&o){var f=o.elems;if("begins"in n)o.begins=e[t].date(n.begins);if("ends"in n)o.ends=e[t].date(n.ends);if("color"in n)o.colors=n.color?e[t].colors.generate(n.color):a.settings.defaultcolor;if("title"in n)o.title=n.title||null;if("notes"in n)o.notes=n.notes||"";if(o.endsa.cache.enddate)return false;o.cache.ends=a.cache.enddateo.begins?a.settings.startdate.copy():o.begins;var l=a.settings.allowhtml?"html":"text";f.find("pre.details")[l](o.notes);f.find("p.title")[l](o.title||o.begins.format(a.settings.maskeventlabel)+(a.settings.maskeventlabelend!==""?a.settings.maskeventlabeldelimiter+o.ends.format(a.settings.maskeventlabelend):""));f.data(t,o);a.cache.events[o.uid]=o;o.calendar.data(t,a);u.draw[a.type].position.apply(f,[r,i]);return true}return false},edit:function(n){var r=n&&!e(this).is("div.ui-"+t+"-event")?e(this).parents("div.ui-"+t+"-event"):e(this),i=r.data(t),s=i&&i.calendar?i.calendar.data(t):false;if(s&&i){if(!s.settings.allownotesedit)return;var o=r.find("pre.details"),a=o.height();var f=s.settings.allowhtml?"html":"text";var l=e('