1/** 2 * jQuery.calendar 3 * 4 * @version 1.0.4 5 * @author rew <[email protected]> 6 * @link http://rewish.org/javascript/jquery_calendar 7 * @license http://rewish.org/license/mit The MIT License 8 */ 9(function($) { 10 11$.fn.calendar = function(option) { 12 return this.each(function() { 13 (new Calendar).init($(this), option).build().show(); 14 }); 15}; 16 17var _weekName = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 18var _today = new Date; 19 20function Calendar() {} 21 22Calendar.prototype = $.extend({ 23 init: function(elem, option) { 24 this.setOption(option); 25 this.elem = $('<div/>') 26 .addClass(this.option.cssClass) 27 .css('z-index', 2); 28 this.wrap = $('<div/>') 29 .append(this.elem) 30 .css({ 31 position: 'relative', 32 overflow: 'hidden' 33 }); 34 elem.append(this.wrap); 35 this.view = {}; 36 this.preloadEvents = {}; 37 return this 38 .buildNavi() 39 .buildTable() 40 .buildCaption() 41 .buildTodayLink(); 42 }, 43 44 setOption: function(option) { 45 if (this.option && !option) { 46 return this; 47 } 48 if (this.option) { 49 $.extend(this.option, option); 50 return this; 51 } 52 this.option = $.extend({ 53 lang : 'ja', 54 year : _today.getFullYear(), 55 month: _today.getMonth() + 1, 56 week: { 57 en: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 58 ja: ['\u65e5', '\u6708', '\u706b', '\u6c34', '\u6728', '\u91d1', '\u571f'] 59 }, 60 caption: { 61 en: '%Y-%M', 62 ja: '%Y\u5e74%M\u6708' 63 }, 64 navi: { 65 en: ['Prev', 'Next'], 66 ja: ['\u524d\u306e\u6708', '\u6b21\u306e\u6708'] 67 }, 68 todayLink: { 69 en: 'Today [%Y-%M-%D]', 70 ja: '\u4eca\u65e5 [%Y\u5e74%M\u6708%D\u65e5]' 71 }, 72 moveTime : 700, 73 events : {}, 74 hideOther: false, 75 cssClass : 'jqueryCalendar', 76 // Callback functions 77 addDay : function() {}, 78 addEvent: function(td, evt) { 79 var elem = typeof evt.url !== 'undefined' 80 ? $('<a/>').attr('href', evt.url) : $('<span/>'); 81 if (evt.id) { 82 elem.attr('id', 'event-' + evt.id); 83 } 84 if (evt.title) { 85 elem.attr('title', evt.title); 86 } 87 if (evt.isNotMine) { 88 elem.css('background', "#ccc"); 89 } 90 elem.text(td.text()); 91 td.text('').append(elem).addClass('event'); 92 }, 93 beforeMove : function() {}, 94 afterMove : function() {}, 95 preloadEvent: function() {} 96 }, option); 97 return this; 98 }, 99 100 buildNavi: function() { 101 if (!this.option.navi) { 102 return this; 103 } 104 var self = this; 105 var list = function(className, number, text) { 106 var date = new Date(self.option.year, (self.option.month + number) - 1, 1); 107 var link = $('<a/>') 108 .text(text) 109 .attr('href', 'javascript:void(0)') 110 .click(function() { 111 self.move(number); 112 return false; 113 }); 114 return $('<li/>').addClass(className).append(link); 115 }; 116 var text = typeof this.option.navi === 'object' 117 ? this.option.navi[this.option.lang] : this.option.navi; 118 this.elem.append( 119 $('<ul/>') 120 .addClass('navi') 121 .append(list('prev', -1, text[0]), 122 list('next', 1, text[1])) 123 ); 124 return this; 125 }, 126 127 buildTable: function() { 128 this.tr = $('<tr/>'); 129 this.td = $('<td/>'); 130 // table 131 this.table = $('<table/>'); 132 // thead 133 var week = []; 134 var weekName = this.option.week[this.option.lang] || this.option.week; 135 for (var i = 0, w; w = weekName[i]; i++) { 136 week[week.length] = '<th class="'+ _weekName[i] +'">'+ w +'</th>'; 137 } 138 this.thead = $('<thead/>').append(this.tr.clone().html(week.join(''))) 139 // tbody 140 this.tbody = $('<tbody/>'); 141 this.elem.append( 142 $('<div/>') 143 .addClass('main') 144 .append( 145 this.table 146 .addClass('calendar') 147 .append(this.thead) 148 .append(this.tbody) 149 ) 150 ); 151 return this; 152 }, 153 154 buildCaption: function() { 155 if (this.option.caption && !this.caption) { 156 this.caption = $('<div/>').addClass('caption'); 157 this.table.before(this.caption); 158 } 159 return this; 160 }, 161 162 buildTodayLink: function() { 163 var date = this.getKey(_today).split('-'); 164 var linkText = typeof this.option.todayLink === 'object' 165 ? this.option.todayLink[this.option.lang] : this.option.todayLink; 166 var self = this; 167 this.table.after( 168 $('<div/>').addClass('todayLink').append( 169 $('<a/>') 170 .text( 171 linkText 172 .replace(/%Y/i, date[0]) 173 .replace(/%M/i, date[1]) 174 .replace(/%D/i, date[2]) 175 ) 176 .attr('href', 'javascript:void(0)') 177 .click(function() { 178 self.option.year = _today.getFullYear(); 179 self.option.month = _today.getMonth() + 1; 180 self.rebuild().show().resetWrap(); 181 }) 182 ) 183 ); 184 return this; 185 }, 186 187 build: function() { 188 this.prevFill(); 189 this.current = new Date(this.option.year, this.option.month - 1, 1); 190 var last = new Date(this.option.year, this.option.month, 0).getDate(); 191 for (var day = 1; day <= last; day++) { 192 this.current.setDate(day); 193 this.option.day = day;
194 this.option.addDay(this.addDay(this.current, 'currentMonth')); 195 } 196 this.option.day = null; 197 this.nextFill(); 198 this.addEvent(); 199 return this; 200 }, 201 202 rebuild: function() { 203 this.tbody.empty(); 204 this.view = {}; 205 return this.build(); 206 }, 207 208 prevFill: function() { 209 var 210 prev = new Date(this.option.year, this.option.month - 1, 0), 211 last = prev.getDate(), 212 day = last - prev.getDay(); 213 if (last - day >= 6) return this; 214 for (; day <= last; day++) { 215 prev.setDate(day); 216 this.addDay(prev, 'otherMonth', this.option.hideOther); 217 } 218 return this; 219 }, 220 221 nextFill: function() { 222 var 223 next = new Date(this.option.year, this.option.month, 1), 224 last = 7 - next.getDay(); 225 if (last >= 7) return this; 226 for (var day = 1; day <= last; day++) { 227 next.setDate(day); 228 this.addDay(next, 'otherMonth', this.option.hideOther); 229 } 230 return this; 231 }, 232 233 addDay: function(date, className, hide) { 234 var key = className === 'otherMonth' 235 ? className + this.getKey(date) 236 : this.getKey(date); 237 this.view[key] = this.td.clone() 238 .addClass(className) 239 .addClass(_weekName[date.getDay()]); 240 // White space for (IE <= 7) "empty-cells" fix 241 this.view[key].text(hide ? ' ' : date.getDate()); 242 if (key !== 'otherMonth') { 243 this.view[key].attr('id', ['calendar', this.getKey(date)].join('-')); 244 } 245 return this.view[key]; 246 }, 247 248 getKey: function(date, returnArray) { 249 if (typeof date === 'string') { 250 date = date.split('-'); 251 } 252 var key = [ 253 date[0] || date.getFullYear(), 254 ('0' + (date[1] || date.getMonth() + 1)).slice(-2), 255 ('0' + (date[2] || date.getDate())).slice(-2) 256 ]; 257 if (returnArray === true) { 258 return key; 259 } 260 return key.join('-') 261 }, 262 263 addEvent: function() { 264 var self = this; 265 $.each(self.option.events, function(date, event) { 266 var td = self.view[self.getKey(date)]; 267 try { 268 self.option.addEvent(td, event); 269 } catch(e) {} 270 }); 271 return this; 272 }, 273 274 show: function() { 275 var today = this.getKey(_today), tr, count = 0, self = this; 276 $.each(self.view, function(key) { 277 if (count % 7 === 0 || count === 0) { 278 tr = count % 2 === 0 279 ? self.tr.clone().addClass('even') 280 : self.tr.clone().addClass('odd'); 281 self.tbody.append(tr); 282 } 283 if (key === today && !key.match('otherMonth')) { 284 this.addClass('today'); 285 } 286 tr.append(this); 287 count++; 288 }); 289 this.setCaption(); 290 try { 291 var date = this.getKey(this.current).split('-'); 292 this.preloadEvents = this.option.preloadEvent(date[0], date[1]); 293 } catch(e) {} 294 return this; 295 }, 296 297 setCaption: function() { 298 if (!this.option.caption) { 299 return this; 300 } 301 this.caption.text(this.getCaption(this.current)); 302 return this; 303 }, 304 305 getCaption: function(date) { 306 date = this.getKey(date).split('-'); 307 var caption = typeof this.option.caption === 'object' 308 ? this.option.caption[this.option.lang] : this.option.caption; 309 return caption 310 .replace(/%Y/i, date[0]) 311 .replace(/%M/i, date[1]) 312 }, 313 314 move: function(number) { 315 var width = this.elem.innerWidth(); 316 var pos = this.elem.position(); 317 var clone = this.elem.clone().css({ 318 position: 'absolute', 319 top: pos.top + 'px', 320 left: pos.left + 'px', 321 zIndex: 1 322 }); 323 this.resetWrap(); 324 this.wrap.append(clone); 325 326 // Changing month 327 this.option.month = this.option.month + number; 328 329 // Before callback 330 var date = new Date(this.option.year, this.option.month - 1, 1); 331 date = this.getKey(date, true); 332 this.option.beforeMove(this.option, date[0], date[1]); 333 334 // Set Event 335 this.setPreloadEvent(number); 336 this.rebuild().show(); 337 338 // Moving animation 339 var time = this.option.moveTime;
340 this.wrap.animate({height: this.elem.innerHeight()}, time); 341 342 // Next moving 343 if ((number + '').charAt(0) !== '-') { 344 clone.animate({marginLeft: '-' + width + 'px'}, time, function() { 345 clone.remove(); 346 }); 347 348 // Prev moving 349 } else { 350 this.elem.css({ 351 position: 'absolute', 352 marginLeft: '-' + width + 'px' 353 }); 354 var self = this; 355 this.elem.animate({marginLeft: 0}, time, function() { 356 clone.remove(); 357 self.elem.css('position', 'static'); 358 }); 359 } 360 this.option.afterMove(this.option, date[0], date[1]); // Callback 361 }, 362 363 resetWrap: function() { 364 this.wrap.css({ 365 width : this.elem.innerWidth() + 'px', 366 height: this.elem.innerHeight() + 'px' 367 }); 368 return this; 369 }, 370 371 setPreloadEvent: function(number) { 372 var type = number === 1 ? 'next' : 'prev'; 373 try { 374 if (typeof this.preloadEvents[type] === 'object') { 375 return this.option.events = this.preloadEvents[type]; 376 } 377 if (typeof this.preloadEvents === 'object') { 378 return this.option.events = this.preloadEvents; 379 } 380 } catch(e) {} 381 } 382 383}, Calendar.prototype); 384 385})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.