1 if ( typeof Dataface == 'undefined' ) Dataface = {}; 2 Dataface.Calendar = function(id, date){ 3 if ( !id ) id = 'df-calendar-'+Math.random(); 4 if ( !date ) date = new Date(); 5 if ( typeof date != 'Date' ){ 6 var d = new Date(); 7 d.setTime(date); 8 date = d; 9 } 10 this.selectedDate = date; 11 this.id = id; 12 Dataface.Calendar.addInstance(this); 13 14 }; 15 16 Dataface.Calendar.instances = {}; 17 Dataface.Calendar.addInstance = function(calendar){ 18 this.instances[calendar.id] = calendar; 19 }; 20 Dataface.Calendar.getInstance = function(id){ 21 return this.instances[id]; 22 }; 23 24 Dataface.Calendar.prototype = { 25 'selectedEvent': null, 26 'selectedDate': new Date(), 27 'defaultStartTime': 8, 28 'defaultEndTime': 22, 29 'monthPanel':null, 30 'weekPanel':null, 31 'dayPanel':null, 32 'detailsPanel':null, 33 34 35 'handleSelectDay': function(date){ 36 if ( typeof date != 'Date' ){ 37 date = new Date(date); 38 } 39 this.selectedDate = date; 40 if ( this.dayPanel ){ 41 document.getElementById(this.dayPanel).innerHTML = this.drawDay(9,21,0.25); 42 } 43 44 }, 45 46 'handleSelectEvent': function(event){ 47 if ( this.selectedEvent ){ 48 var eventDiv = document.getElementById('event-preview-'+this.selectedEvent.id); 49 50 var cls = eventDiv.className; //eventDiv.getAttribute('class'); 51 if ( !cls ) cls = ''; 52 eventDiv.className = cls.replace(/Dataface-Calendar-selected-event/, ''); //eventDiv.setAttribute('class', cls.replace(/Dataface-Calendar-selected-event/, '')); 53 54 } 55 this.selectedEvent = Dataface.Calendar.Event.getInstance(event); 56 if ( this.detailsPanel ){ 57 document.getElementById(this.detailsPanel).innerHTML = this.selectedEvent.showDetails(); 58 59 60 } 61 var div = document.getElementById('event-preview-'+this.selectedEvent.id); 62 var cls2 = div.className; //div.getAttribute('class'); 63 if ( !cls2 ) cls2 = ''; 64 if ( div ) div.className = cls2+' Dataface-Calendar-selected-event'; //div.setAttribute('class', cls2+' Dataface-Calendar-selected-event'); 65 66 } 67 68 }; 69 70 Dataface.Calendar.Event = function(id, data){ 71 this.id = 'event-'+Math.random(); 72 for ( var key in data){ 73 if ( (key == 'date' || key == 'endTime') && typeof data[key] != 'Date' ){ 74 var d = new Date(); 75 d.setTime(data[key]+d.getTimezoneOffset()*60*1000); 76 data[key] = d; 77 78 } 79 this[key] = data[key]; 80 } 81 Dataface.Calendar.Event.addInstance(this); 82 }; 83 84 Dataface.Calendar.Event.instances = {}; 85 Dataface.Calendar.Event.addInstance = function(event){ 86 this.instances[event.id] = event; 87 }; 88 Dataface.Calendar.Event.getInstance = function(id){ 89 return this.instances[id]; 90 }; 91 92 93 94 Dataface.Calendar.Event.prototype = { 95 'title': null, 96 'date': null, 97 'endTime': null, 98 'description': null, 99 'url': null, 100 'showDetails': function(){ 101 var out = '<div "Dataface-Calendar-details">'; 102 out += '<h3 class="Dataface-Calendar-details-title">'+this.title+'</h3>'; 103 out += '<table class="Dataface-Calendar-details-data"><tbody>'; 104 out += '<tr><th>from</th><td>'+this.date.asString('%Y-%m-%d')+' at '+this.date.asString('%H:%i')+'</td></tr>'; 105 if ( this.endTime ) { 106 out += '<tr><th>to</th><td>'+this.endTime.asString('%Y-%m-%d')+' at '+this.endTime.asString('%H:%i')+'</td></tr>'; 107 } 108 out += '</table>'; 109 out += '<div class="Dataface-Calendar-details-description">'+this.getDescription()+'</div>'; 110 111 out += ' </div>'; 112 return out; 113 }, 114 'getDescription': function(){ 115 return this.description; 116 } 117 }; 118 119 120 121 122 Dataface.Calendar.prototype.events = { 123 'list': [], 124 'sorted': false, 125 126 'add': function(e){ 127 this.list[this.list.length] = e; 128 this.sorted = false; 129 }, 130 131 'compare': function(a,b){ 132 return (a.date.getTime() < a.date.getTime()); 133 }, 134 135 'sort': function(){ 136 if ( !this.sorted ){ 137 this.list.sort(this.compare); 138 } 139 }, 140 141 'month': function(date){ 142 this.sort(); 143 var out = []; 144 for ( var i=0; i<this.list.length; i++){ 145 var e = this.list[i]; 146 if ( (e.date.getFullYear() == date.getFullYear()) && (e.date.getMonth() == date.getMonth()) ){ 147 out[out.length] = this.list[i]; 148 } 149 } 150 return out; 151 }, 152 153 'day': function(date){ 154 this.sort(); 155 var out = []; 156 for ( var i=0; i<this.list.length; i++){ 157 var e = this.list[i]; 158 if ( (e.date.getFullYear() == date.getFullYear()) && 159 ( e.date.getMonth() == date.getMonth() ) && 160 ( e.date.getDate() == date.getDate() ) ){ 161 out[out.length] = this.list[i]; 162 } 163 } 164 return out; 165 }, 166 167 'week': function(date){ 168 this.sort(); 169 var firstDay = date.getDate() - date.getDay(); 170 var lastDay = date.getDate() + ( 6 - date.getDay() ); 171 172 var out = []; 173 for ( var i=0; i<this.list.length; i++){ 174 var e = this.list[i]; 175 if ( (e.date.getFullYear() == date.getFullYear()) && 176 ( e.date.getMonth() == date.getMonth() ) && 177 ( e.date.getDate() >= firstDay ) && 178 ( e.date.getDate() <= lastDay ) ){ 179 out[out.length] = this.list[i]; 180 } 181 } 182 return out; 183 184 }, 185 186 'range': function(start,end){ 187 this.sort(); 188 var out = []; 189 for ( var i =0; i<this.list.length; i++ ){ 190 var e = this.list[i]; 191 192 if ( (start.getTime() <= e.date.getTime()) && (end.getTime() > e.date.getTime()) ){ 193 out[ out.length ] = e; 194 } 195 } 196 return out; 197 } 198 199 200 }; 201 202 203 Date.daysOfWeek = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']; 204 Date.monthsOfYear = ['January','February','March','April','May','June','July','August','September','October','November','December']; 205 206 207 Date.prototype.daysInMonth = function(/*iMonth, iYear*/){ 208 return 32 - new Date(this.getFullYear(), this.getMonth(), 32).getDate(); 209 } 210 211 Dataface.Calendar.prototype.drawMonth = function(){ 212 var firstDay = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1); 213 214 var out = '<table class="Dataface-Calendar-month" cellspacing="0"><thead><tr><th>'+Date.daysOfWeek.join('</th><th>')+'</th></tr></thead>'; 215 out += '<tbody>'; 216 217 var day = -1; 218 for ( var i=0; i<5; i++ ){ 219 out += '<tr>'; 220 221 for ( var j=0; j<7; j++ ){ 222 223 224 if ( (day == -1) && ( firstDay.getDay() == j ) ){ 225 // We have arrived at the first day of the month so we can start the day counter 226 day = 0; 227 } 228 229 if ( day == this.selectedDate.daysInMonth() ){ 230 day = -1; 231 } 232 var cls = ''; 233 if ( day >= 0 ) cls = 'Dataface-Calendar-day'; 234 else cls = 'Dataface-Calendar-empty-day'; 235 236 out += '<td class="'+cls+'"><div class="day-wrapper"'; 237 238 if ( day >= 0 ){ 239 var currDay = this.selectedDate.clone(); 240 currDay.setDate(day+1); 241 out += '<div class="day-number"><a href="javascript:Dataface.Calendar.getInstance(\''+this.id+'\').handleSelectDay(\''+currDay.toString()+'\')">'+(day+1)+'</a></div>'; 242 243 244 //var events = Date.events.range(startTime, endTime); 245 var events = this.events.day(currDay); 246 247 for ( var k=0; k<events.length; k++){ 248 out += '<div class="Dataface-Calendar-event" id="event-preview-'+events[k].id+'"><a href="javascript:Dataface.Calendar.getInstance(\''+this.id+'\').handleSelectEvent(\''+events[k].id+'\');">'+events[k].title+'</a></div>'; 249 } 250 251 day++; 252 } 253 254 out += '</div></td>'; 255 256 } 257 out += '</tr>'; 258 259 } 260 out += '</tbody></table>'; 261 return out; 262 }; 263 264 Dataface.Calendar.prototype.drawWeek = function(startHour, endHour){ 265 266 if ( !startHour ) startHour = 8; 267 if ( !endHour ) endHour = 20; 268 269 var thisDayOfWeek = this.selectedDate.getDay(); 270 var thisWeeksFirstDay = this.selectedDate.getDate()-this.selectedDate.getDay(); 271 272 var headings = []; 273 274 for ( var i=0; i<Date.daysOfWeek.length; i++){ 275 var date = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), thisWeeksFirstDay+i); 276 headings[headings.length] = Date.daysOfWeek[i]+' '+Date.monthsOfYear[ date.getMonth() ]+' '+date.getDate()+', '+date.getFullYear(); 277 } 278 var out = '<table class="jsCalendar-week"><thead><tr><th></th><th>'+headings.join('</th><th>')+'</th></tr></thead>'; 279 out += '<tbody>'; 280 for ( var hour=startHour; hour<=endHour; hour++ ){ 281 out += '<tr><th>'+(hour+1)+':00</th>'; 282 for ( var j=0; j<Date.daysOfWeek.length; j++){ 283 out += '<td></td>'; 284 } 285 out += '</tr>'; 286 } 287 out += '</tbody></table>'; 288 289 return out; 290 291 292 }; 293 294 Dataface.Calendar.prototype.drawDay = function(startHour, endHour, precision){ 295 if ( !startHour ) startHour = 8; 296 if ( !endHour ) endHour = 20; 297 if ( !precision ) precision = 1.0; 298 299 var thisDayOfWeek = this.selectedDate.getDay(); 300 var thisWeeksFirstDay = this.selectedDate.getDate()-this.selectedDate.getDay(); 301 302 var headings = []; 303 304 for ( var i=0; i<Date.daysOfWeek.length; i++){ 305 var date = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), thisWeeksFirstDay+i); 306 headings[headings.length] = Date.daysOfWeek[i]+' '+Date.monthsOfYear[ date.getMonth() ]+' '+date.getDate()+', '+date.getFullYear(); 307 } 308 var out = '<table class="jsCalendar-week"><thead><tr><th></th><th>'+headings[this.selectedDate.getDay()]+'</th></thead>'; 309 out += '<tbody>'; 310 var startTimems = this.selectedDate.clone(); 311 startTimems.setHours(startHour); 312 startTimems.setMinutes(0); 313 startTimems.setSeconds(0); 314 315 var endTimems = this.selectedDate.clone(); 316 endTimems.setHours(endHour); 317 endTimems.setMinutes(0); 318 endTimems.setSeconds(0); 319 320 //for ( var hour=startHour; hour<=endHour; hour++ ){ 321 for ( var time=startTimems.getTime(); time <= endTimems; time += (precision*60*60*1000) ){ 322 323 var startTime = this.selectedDate.clone(); 324 startTime.setTime(time); 325 var minutes = startTime.getMinutes() + ""; 326 if ( minutes.length == 1 ) minutes = '0'+minutes; 327 out += '<tr><th>'+(startTime.getHours())+':'+minutes+'</th>'; 328 //startTime.setHours(hour); 329 //startTime.setMinutes(0); 330 //startTime.setSeconds(0); 331 332 var endTime = this.selectedDate.clone(); 333 endTime.setTime(time + (precision*60*60*1000) ); 334 //endTime.setHours(hour+1); 335 //endTime.setMinutes(0); 336 //endTime.setSeconds(0); 337 338 //var events = Date.events.range(startTime, endTime); 339 var events = this.events.range(startTime, endTime); 340 out += '<td>'; 341 for ( var j=0; j<events.length; j++){ 342 out += '<div class="jsCalendar-event"><a href="javascript:Dataface.Calendar.getInstance(\''+this.id+'\').handleSelectEvent(\''+events[j].id+'\');">'+events[j].title+'</a></div>'; 343 } 344 out += '</td></tr>'; 345 } 346 out += '</tbody></table>'; 347 348 return out; 349 }; 350 351 Date.prototype.clone = function(){ 352 return new Date(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds()); 353 }; 354 355 Date.prototype.asString = function (format){ 356 var out = format.replace(/%Y/, this.getFullYear()); 357 out = out.replace(/%m/, pad(this.getMonth()+1,2)); 358 out = out.replace(/%d/, pad(this.getDate(),2)); 359 out = out.replace(/%H/, pad(this.getHours(),2)); 360 out = out.replace(/%i/, pad(this.getMinutes(),2)); 361 return out; 362 }; 363 364 function pad(number, length) { 365 366 var str = '' + number; 367 while (str.length < length) { 368 str = '0' + str; 369 } 370 371 return str; 372 373 } 374 375 376 377