1 /*if(!window.LOG){ 2 window.LOG = {warn:function(){}}; 3 }*/ 4 5 // TODO: try to change RichFaces.$ to $$ if possible 6 7 (function ($, rf) { 8 9 rf.ui = rf.ui || {}; 10 11 //calendar templates 12 var CalendarView = { 13 getControl: function(text, attributes, functionName, paramsStr) { 14 var attr = $.extend({ 15 onclick: (functionName ? "RichFaces.$$('Calendar',this)." + functionName + "(" + (paramsStr ? paramsStr : "") + ");" : "") + "return true;" 16 }, attributes); 17 return new E('div', attr, [new T(text)]); 18 }, 19 20 getSelectedDateControl: function(calendar) { 21 22 if (!calendar.selectedDate || calendar.options.showApplyButton) return ""; 23 24 var text = rf.calendarUtils.formatDate(calendar.selectedDate, (calendar.timeType ? calendar.datePattern : calendar.options.datePattern), calendar.options.monthLabels, calendar.options.monthLabelsShort); 25 var onclick = "RichFaces.$$('Calendar',this).showSelectedDate(); return true;" 26 var markup = ( calendar.options.disabled ? 27 new E('div', {'class': 'rf-cal-tl-btn-dis'}, [new ET(text)]) : 28 new E('div', {'class': 'rf-cal-tl-btn', 'onclick': onclick}, [new ET(text)]) ); 29 30 return markup; 31 }, 32 33 getTimeControl: function(calendar) { 34 35 if (!calendar.selectedDate || !calendar.timeType) return ""; 36 37 var text = rf.calendarUtils.formatDate(calendar.selectedDate, calendar.timePattern, calendar.options.monthLabels, calendar.options.monthLabelsShort); 38 39 var onmouseover = "RichFaces.jQuery(this).removeClass('rf-cal-btn-press');"; 40 var onmouseout = "RichFaces.jQuery(this).addClass('rf-cal-btn-press');"; 41 var onclick = "RichFaces.$$('Calendar',this).showTimeEditor();return true;"; 42 var markup = calendar.options.disabled || calendar.options.readonly ? 43 new E('div', {'class': 'rf-cal-tl-btn-btn-dis'}, [new ET(text)]) : 44 new E('div', {'class': 'rf-cal-tl-btn rf-cal-tl-btn-hov rf-cal-btn-press', 'onclick': onclick, 45 'onmouseover': + onmouseover , 46 'onmouseout' : + onmouseout}, [new ET(text)]); 47 48 return markup; 49 }, 50 51 toolButtonAttributes: {className: "rf-cal-tl-btn", onmouseover:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov'", onmouseout:"this.className='rf-cal-tl-btn'", onmousedown:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov rf-cal-tl-btn-btn-press'", onmouseup:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov'"}, 52 nextYearControl: function (context) { 53 return (!context.calendar.options.disabled ? CalendarView.getControl(">>", CalendarView.toolButtonAttributes, "nextYear") : ""); 54 }, 55 previousYearControl: function (context) { 56 return (!context.calendar.options.disabled ? CalendarView.getControl("<<", CalendarView.toolButtonAttributes, "prevYear") : ""); 57 }, 58 nextMonthControl: function (context) { 59 return (!context.calendar.options.disabled ? CalendarView.getControl(">", CalendarView.toolButtonAttributes, "nextMonth") : ""); 60 }, 61 previousMonthControl: function (context) { 62 return (!context.calendar.options.disabled ? CalendarView.getControl("<", CalendarView.toolButtonAttributes, "prevMonth") : ""); 63 }, 64 currentMonthControl: function (context) { 65 var text = rf.calendarUtils.formatDate(context.calendar.getCurrentDate(), "MMMM, yyyy", context.monthLabels, context.monthLabelsShort); 66 var markup = context.calendar.options.disabled ? 67 new E('div', {className: "rf-cal-tl-btn-dis"}, [new T(text)]) : 68 CalendarView.getControl(text, CalendarView.toolButtonAttributes, "showDateEditor"); 69 return markup; 70 }, 71 todayControl: function (context) { 72 return (!context.calendar.options.disabled && context.calendar.options.todayControlMode != 'hidden' ? CalendarView.getControl(context.controlLabels.today, CalendarView.toolButtonAttributes, "today") : ""); 73 }, 74 closeControl: function (context) { 75 return (context.calendar.options.popup ? CalendarView.getControl(context.controlLabels.close, CalendarView.toolButtonAttributes, "close", "false") : ""); 76 }, 77 applyControl: function (context) { 78 return (!context.calendar.options.disabled && !context.calendar.options.readonly && context.calendar.options.showApplyButton ? CalendarView.getControl(context.controlLabels.apply, CalendarView.toolButtonAttributes, "close", "true") : ""); 79 }, 80 cleanControl: function (context) { 81 return (!context.calendar.options.disabled && !context.calendar.options.readonly && context.calendar.selectedDate ? CalendarView.getControl(context.controlLabels.clean, CalendarView.toolButtonAttributes, "__resetSelectedDate") : ""); 82 }, 83 84 selectedDateControl: function (context) { 85 return CalendarView.getSelectedDateControl(context.calendar); 86 }, 87 timeControl: function (context) { 88 return CalendarView.getTimeControl(context.calendar); 89 }, 90 timeEditorFields: function (context) { 91 return context.calendar.timePatternHtml; 92 }, 93 94 header: [ 95 new E('table', {'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'width': '100%'}, 96 [ 97 new E('tbody', {}, 98 [ 99 new E('tr', {}, 100 [ 101 new E('td', {'class': 'rf-cal-tl'}, 102 [ 103 new ET(function (context) { 104 return rf.calendarTemplates.evalMacro("previousYearControl", context) 105 }) 106 ]), 107 new E('td', {'class': 'rf-cal-tl'}, 108 [ 109 new ET(function (context) { 110 return rf.calendarTemplates.evalMacro("previousMonthControl", context) 111 }) 112 ]), 113 new E('td', {'class': 'rf-cal-hdr-month'}, 114 [ 115 new ET(function (context) { 116 return rf.calendarTemplates.evalMacro("currentMonthControl", context) 117 }) 118 ]), 119 new E('td', {'class': 'rf-cal-tl'}, 120 [ 121 new ET(function (context) { 122 return rf.calendarTemplates.evalMacro("nextMonthControl", context) 123 }) 124 ]), 125 new E('td', {'class': 'rf-cal-tl'}, 126 [ 127 new ET(function (context) { 128 return rf.calendarTemplates.evalMacro("nextYearControl", context) 129 }) 130 ]), 131 new E('td', {'class': 'rf-cal-tl rf-cal-btn-close', 'style':function(context) { 132 return (this.isEmpty ? 'display:none;' : ''); 133 }}, 134 [ 135 new ET(function (context) { 136 return rf.calendarTemplates.evalMacro("closeControl", context) 137 }) 138 ]) 139 ]) 140 ]) 141 ] 142 )], 143 144 footer: [ 145 new E('table', {'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'width': '100%'}, 146 [ 147 new E('tbody', {}, 148 [ 149 new E('tr', {}, 150 [ 151 new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) { 152 return (this.isEmpty ? 'display:none;' : ''); 153 }}, 154 [ 155 new ET(function (context) { 156 return rf.calendarTemplates.evalMacro("selectedDateControl", context) 157 }) 158 ]), 159 new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) { 160 return (this.isEmpty ? 'display:none;' : ''); 161 }}, 162 [ 163 new ET(function (context) { 164 return rf.calendarTemplates.evalMacro("cleanControl", context) 165 }) 166 ]), 167 new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) { 168 return (this.isEmpty ? 'display:none;' : ''); 169 }}, 170 [ 171 new ET(function (context) { 172 return rf.calendarTemplates.evalMacro("timeControl", context) 173 }) 174 ]), 175 new E('td', {'class': 'rf-cal-tl-ftr', 'style': 'background-image:none;', 'width': '100%'}, []), 176 new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) { 177 return (this.isEmpty ? 'display:none;' : '') + (context.calendar.options.disabled || context.calendar.options.readonly || !context.calendar.options.showApplyButton ? 'background-image:none;' : ''); 178 }}, 179 [ 180 new ET(function (context) { 181 return rf.calendarTemplates.evalMacro("todayControl", context) 182 }) 183 ]), 184 new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) { 185 return (this.isEmpty ? 'display:none;' : '') + 'background-image:none;'; 186 }}, 187 [ 188 new ET(function (context) { 189 return rf.calendarTemplates.evalMacro("applyControl", context) 190 }) 191 ]) 192 ]) 193 ]) 194 ] 195 )], 196 197 timeEditorLayout: [ 198 199 new E('table', {'id': function(context) { 200 return context.calendar.TIME_EDITOR_LAYOUT_ID 201 }, 'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'class': 'rf-cal-timepicker-cnt'}, 202 [ 203 new E('tbody', {}, 204 [ 205 new E('tr', {}, 206 [ 207 new E('td', {'class': 'rf-cal-timepicker-inp', 'colspan': '2', 'align': 'center'}, 208 [ 209 new ET(function (context) { 210 return rf.calendarTemplates.evalMacro("timeEditorFields", context) 211 }) 212 ]) 213 ]), 214 new E('tr', {}, 215 [ 216 new E('td', {'class': 'rf-cal-timepicker-ok'}, 217 [ 218 new E('div', {'id': function(context) { 219 return context.calendar.TIME_EDITOR_BUTTON_OK 220 }, 'class': 'rf-cal-time-btn', 'style': 'float:right;', 'onmousedown': "RichFaces.jQuery(this).addClass('rf-cal-time-btn-press');", 'onmouseout': "RichFaces.jQuery(this).removeClass('rf-cal-time-btn-press');", 'onmouseup': "RichFaces.jQuery(this).removeClass('rf-cal-time-btn-press');", 'onclick': function(context) { 221 return "RichFaces.component('" + context.calendar.id + "').hideTimeEditor(true)"; 222 }}, 223 [ 224 new E('span', {}, 225 [ 226 new ET(function (context) { 227 return context.controlLabels.ok; 228 }) 229 ]) 230 ]) 231 ]) 232 , 233 new E('td', {'class': 'rf-cal-timepicker-cancel'}, 234 [ 235 new E('div', {'id': function(context) { 236 return context.calendar.TIME_EDITOR_BUTTON_CANCEL 237 }, 'class': 'rf-cal-time-btn', 'style': 'float:left;', 'onmousedown': "RichFaces.jQuery(this).addClass('rf-cal-time-btn-press');", 'onmouseout': "RichFaces.jQuery(this).removeClass('rf-cal-time-btn-press');", 'onmouseup': "RichFaces.jQuery(this).removeClass('rf-cal-time-btn-press');", 'onclick': function(context) { 238 return "RichFaces.component('" + context.calendar.id + "').hideTimeEditor(false)"; 239 }}, 240 [ 241 new E('span', {}, 242 [ 243 new ET(function (context) { 244 return context.controlLabels.cancel; 245 }) 246 ]) 247 ]) 248 ]) 249 ]) 250 ]) 251 ] 252 )], 253 254 dayList: [new ET(function (context) { 255 return context.day 256 })], 257 weekNumber: [new ET(function (context) { 258 return context.weekNumber 259 })], 260 weekDay: [new ET(function (context) { 261 return context.weekDayLabelShort 262 })] 263 }; 264 // calendar templates end 265 266 // calendar context 267 var CalendarContext = function(calendar) { 268 this.calendar = calendar; 269 this.monthLabels = calendar.options.monthLabels; 270 this.monthLabelsShort = calendar.options.monthLabelsShort; 271 this.weekDayLabels = calendar.options.weekDayLabels; 272 this.weekDayLabelsShort = calendar.options.weekDayLabelsShort; 273 this.controlLabels = calendar.options.labels; 274 }; 275 276 $.extend(CalendarContext.prototype, { 277 nextYearControl: CalendarView.nextYearControl, 278 previousYearControl: CalendarView.previousYearControl, 279 nextMonthControl: CalendarView.nextMonthControl, 280 previousMonthControl: CalendarView.previousMonthControl, 281 currentMonthControl: CalendarView.currentMonthControl, 282 selectedDateControl: CalendarView.selectedDateControl, 283 cleanControl: CalendarView.cleanControl, 284 timeControl: CalendarView.timeControl, 285 todayControl: CalendarView.todayControl, 286 closeControl: CalendarView.closeControl, 287 applyControl: CalendarView.applyControl, 288 timeEditorFields: CalendarView.timeEditorFields 289 }); 290 291 // must be :defaultTime, minDaysInFirstWeek, firstWeekday, weekDayLabels, weekDayLabelsShort, monthLabels, monthLabelsShort 292 293 // defaults definition 294 var defaultOptions = { 295 showWeekDaysBar: true, 296 showWeeksBar: true, 297 datePattern: "MMM d, yyyy", 298 horizontalOffset: 0, 299 verticalOffset: 0, 300 dayListMarkup: CalendarView.dayList, 301 weekNumberMarkup: CalendarView.weekNumber, 302 weekDayMarkup: CalendarView.weekDay, 303 headerMarkup: CalendarView.header, 304 footerMarkup: CalendarView.footer, 305 isDayEnabled: function (context) { 306 return true; 307 }, 308 dayStyleClass: function (context) { 309 return ""; 310 }, 311 showHeader: true, 312 showFooter: true, 313 direction: "AA", 314 jointPoint: "AA", 315 popup: true, 316 boundaryDatesMode: "inactive", 317 todayControlMode: "select", 318 style: "", 319 className: "", 320 disabled: false, 321 readonly: false, 322 enableManualInput: false, 323 showInput: true, 324 resetTimeOnDateSelect: false, 325 style: "z-index: 3;", 326 showApplyButton: false, 327 selectedDate: null, 328 currentDate: null, 329 defaultTime: {hours:12,minutes:0, seconds:0}, 330 mode: "client", 331 hidePopupOnScroll: true, 332 defaultLabel:"" 333 }; 334 335 var defaultLabels = {apply:'Apply', today:'Today', clean:'Clean', ok:'OK', cancel:'Cancel', close:'x'}; 336 337 var eventHandlerNames = ["change", "dateselect", "beforedateselect", "currentdateselect", 338 "beforecurrentdateselect", "currentdateselect", "clean", "complete", "collapse", 339 "datemouseout", "datemouseover", "show", "hide", "timeselect", "beforetimeselect"]; 340 341 var updateDefaultLabel = function (value) { 342 var field = rf.getDomElement(this.INPUT_DATE_ID); 343 if ( 344 (field.value == this.options.defaultLabel && !value) || 345 (value == this.options.defaultLabel && !field.value) 346 ) { 347 field.value = value; 348 if (value) { 349 $(field).addClass("rf-cal-dflt-lbl"); 350 } else { 351 $(field).removeClass("rf-cal-dflt-lbl"); 352 } 353 } 354 } 355 356 var onFocusBlur = function (event) { 357 this.isFocused = event.type == "focus"; 358 if (!this.isFocused && this.isVisible) return; 359 updateDefaultLabel.call(this, (event.type == "focus" ? "" : this.options.defaultLabel)); 360 } 361 362 // Constructor definition 363 rf.ui.Calendar = function(componentId, locale, options, markups) { 364 365 // dayListMarkup - day cell markup 366 // context: {day, date, weekNumber, weekDayNumber, isWeekend, isCurrentMonth, elementId, component} 367 // weekNumberMarkup - week number cell markup 368 // context: {weekNumber, elementId, component} 369 // weekDayMarkup - week day cell markup 370 // context: {weekDayLabel, weekDayLabelShort, weekDayNumber, isWeekend, elementId, component} 371 372 // headerMarkup 373 // footerMarkup 374 // optionalHeaderMarkup - user defined header (optional) 375 // optionalFooterMarkup - user defined footer (optional) 376 377 // currentDate - date to show month (day not used) (MM/yyyy) 378 // selectedDate - selected date (mm/dd/yyyy) 379 // weekDayLabels - collection of week day labels keyed by week day numbers 380 // weekDayLabelsShort - collection of week day short labels keyed by week day numbers 381 // minDaysInFirstWeek - locale-specific constant defining number of days in the first week 382 // firstWeekDay - (0..6) locale-specific constant defining number of the first week day 383 // showWeekDaysBar - show WeekDays Bar [default value is true] 384 // showWeeksBar - show Weeks numbers bar [default value is true] 385 // showApplyButton 386 // showHeader 387 // showFooter 388 389 // POPUP description 390 // direction - [top-left, top-right, bottom-left, bottom-right, auto] 391 // jointPoint - [top-left, top-right, bottom-left, bottom-right] 392 // popup - true 393 // id+PopupButton, id+InputDate, 394 395 // boundaryDatesMode - boundary dates onclick action: 396 // "inactive" or undefined - no action (default) 397 // "scroll" - change current month 398 // "select" - change current month and select date 399 // "hidden" - does not render content for boundary dates 400 // 401 // todayControlMode - today control onclick action: 402 // "scroll" 403 // "select" 404 // "hidden" 405 406 // isDayEnabled - end-developer JS function 407 // dayStyleClass - end-developer JS function that provide style class for day's cells. 408 409 // dayCellClass - add div to day cell with class 'rf-cal-c-cnt' and add this class to TD if defined 410 // style - table style 411 // styleClass - table class 412 413 // disabled 414 // readonly 415 416 //var _d = new Date(); 417 418 // call constructor of parent class 419 $super.constructor.call(this, componentId); 420 421 this.namespace = "." + rf.Event.createNamespace(this.name, componentId); 422 423 //create parameters 424 //this.options = $.extend(this.options, defaultOptions, options); 425 this.options = $.extend(this.options, defaultOptions, locales[locale], options, markups); 426 427 // labels 428 var value = options.labels || {}; 429 for (var name in defaultLabels) { 430 if (!value[name]) value[name] = defaultLabels[name]; 431 } 432 this.options.labels = value; 433 434 this.popupOffset = [this.options.horizontalOffset, this.options.verticalOffset]; 435 436 // 437 if (!this.options.popup) this.options.showApplyButton = false; 438 439 // 440 this.options.boundaryDatesMode = this.options.boundaryDatesMode.toLowerCase(); 441 this.hideBoundaryDatesContent = this.options.boundaryDatesMode == "hidden"; 442 this.options.todayControlMode = this.options.todayControlMode.toLowerCase(); 443 444 // time 445 this.setTimeProperties(); 446 447 this.customDayListMarkup = (this.options.dayListMarkup != CalendarView.dayList); 448 449 this.currentDate = this.options.currentDate ? this.options.currentDate : (this.options.selectedDate ? this.options.selectedDate : new Date()); 450 this.currentDate.setDate(1); 451 this.selectedDate = this.options.selectedDate; 452 453 this.todayDate = new Date(); 454 455 this.firstWeekendDayNumber = 6 - this.options.firstWeekDay; 456 this.secondWeekendDayNumber = (this.options.firstWeekDay > 0 ? 7 - this.options.firstWeekDay : 0); 457 458 this.calendarContext = new CalendarContext(this); 459 460 // TODO: move it from constructor 461 this.DATE_ELEMENT_ID = this.id + 'DayCell'; 462 this.WEEKNUMBER_BAR_ID = this.id + "WeekNum"; 463 this.WEEKNUMBER_ELEMENT_ID = this.WEEKNUMBER_BAR_ID + 'Cell'; 464 this.WEEKDAY_BAR_ID = this.id + "WeekDay"; 465 this.WEEKDAY_ELEMENT_ID = this.WEEKDAY_BAR_ID + 'Cell'; 466 this.POPUP_ID = this.id + 'Popup'; 467 this.POPUP_BUTTON_ID = this.id + 'PopupButton'; 468 this.INPUT_DATE_ID = this.id + 'InputDate'; 469 this.EDITOR_ID = this.id + 'Editor'; 470 this.EDITOR_SHADOW_ID = this.id + 'EditorShadow'; 471 472 this.TIME_EDITOR_LAYOUT_ID = this.id + 'TimeEditorLayout'; 473 this.DATE_EDITOR_LAYOUT_ID = this.id + 'DateEditorLayout'; 474 this.EDITOR_LAYOUT_SHADOW_ID = this.id + 'EditorLayoutShadow'; 475 this.TIME_EDITOR_BUTTON_OK = this.id + 'TimeEditorButtonOk'; 476 this.TIME_EDITOR_BUTTON_CANCEL = this.id + 'TimeEditorButtonCancel'; 477 this.DATE_EDITOR_BUTTON_OK = this.id + 'DateEditorButtonOk'; 478 this.DATE_EDITOR_BUTTON_CANCEL = this.id + 'DateEditorButtonCancel'; 479 this.CALENDAR_CONTENT = this.id + "Content"; 480 481 this.firstDateIndex = 0; 482 483 this.daysData = {startDate:null, days:[]}; 484 this.days = []; 485 this.todayCellId = null; 486 this.todayCellColor = ""; 487 488 this.selectedDateCellId = null; 489 this.selectedDateCellColor = ""; 490 491 var popupStyles = ""; 492 this.isVisible = true; 493 if (this.options.popup == true) { 494 // popup mode initialisation 495 popupStyles = "display:none; position:absolute;" 496 this.isVisible = false; 497 } 498 499 var tempStr = "RichFaces.component('" + this.id + "')."; 500 501 var htmlTextHeader = '<table id="' + this.CALENDAR_CONTENT + '" border="0" cellpadding="0" cellspacing="0" class="rf-cal-extr rf-cal-popup ' + this.options.styleClass + '" style="' + popupStyles + this.options.style + '" onclick="' + tempStr + 'skipEventOnCollapse=true;"><tbody>'; 502 var colspan = (this.options.showWeeksBar ? "8" : "7"); 503 var htmlHeaderOptional = (this.options.optionalHeaderMarkup) ? '<tr><td class="rf-cal-hdr-optnl" colspan="' + colspan + '" id="' + this.id + 'HeaderOptional"></td></tr>' : ''; 504 var htmlFooterOptional = (this.options.optionalFooterMarkup) ? '<tr><td class="rf-cal-ftr-optl" colspan="' + colspan + '" id="' + this.id + 'FooterOptional"></td></tr>' : ''; 505 var htmlControlsHeader = (this.options.showHeader ? '<tr><td class="rf-cal-hdr" colspan="' + colspan + '" id="' + this.id + 'Header"></td></tr>' : ''); 506 var htmlControlsFooter = (this.options.showFooter ? '<tr><td class="rf-cal-ftr" colspan="' + colspan + '" id="' + this.id + 'Footer"></td></tr>' : ''); 507 var htmlTextFooter = '</tbody></table>' 508 509 // days bar creation 510 var styleClass; 511 var bottomStyleClass; 512 var htmlTextWeekDayBar = []; 513 var context; 514 515 var eventsStr = this.options.disabled || this.options.readonly ? '' : 'onclick="' + tempStr + 'eventCellOnClick(event, this);" onmouseover="' + tempStr + 'eventCellOnMouseOver(event, this);" onmouseout="' + tempStr + 'eventCellOnMouseOut(event, this);"'; 516 if (this.options.showWeekDaysBar) { 517 htmlTextWeekDayBar.push('<tr id="' + this.WEEKDAY_BAR_ID + '">'); 518 if (this.options.showWeeksBar) htmlTextWeekDayBar.push('<td class="rf-cal-day-lbl"><br/></td>'); 519 var weekDayCounter = this.options.firstWeekDay; 520 for (var i = 0; i < 7; i++) { 521 context = {weekDayLabel: this.options.weekDayLabels[weekDayCounter], weekDayLabelShort: this.options.weekDayLabelsShort[weekDayCounter], weekDayNumber:weekDayCounter, isWeekend:this.isWeekend(i), elementId:this.WEEKDAY_ELEMENT_ID + i, component:this}; 522 var weekDayHtml = this.evaluateMarkup(this.options.weekDayMarkup, context); 523 if (weekDayCounter == 6) weekDayCounter = 0; else weekDayCounter++; 524 525 styleClass = "rf-cal-day-lbl"; 526 if (context.isWeekend) { 527 styleClass += " rf-cal-holliday-lbl"; 528 } 529 if (i == 6) styleClass += " rf-cal-right-c"; 530 htmlTextWeekDayBar.push('<td class="' + styleClass + '" id="' + context.elementId + '">' + weekDayHtml + '</td>'); 531 } 532 htmlTextWeekDayBar.push('</tr>\n'); 533 } 534 535 // week & weekNumber creation 536 var htmlTextWeek = []; 537 var p = 0; 538 this.dayCellClassName = []; 539 540 for (k = 1; k < 7; k++) { 541 bottomStyleClass = (k == 6 ? "rf-btm-c " : ""); 542 htmlTextWeek.push('<tr id="' + this.WEEKNUMBER_BAR_ID + k + '">'); 543 if (this.options.showWeeksBar) { 544 context = {weekNumber: k, elementId:this.WEEKNUMBER_ELEMENT_ID + k, component:this}; 545 var weekNumberHtml = this.evaluateMarkup(this.options.weekNumberMarkup, context); 546 htmlTextWeek.push('<td class="rf-cal-week ' + bottomStyleClass + '" id="' + context.elementId + '">' + weekNumberHtml + '</td>'); 547 } 548 549 // day cells creation 550 for (var i = 0; i < 7; i++) { 551 styleClass = bottomStyleClass + (!this.options.dayCellClass ? "rf-cal-c-cnt-overflow" : (!this.customDayListMarkup ? this.options.dayCellClass : "")) + " rf-cal-c"; 552 if (i == this.firstWeekendDayNumber || i == this.secondWeekendDayNumber) styleClass += " rf-cal-holiday"; 553 if (i == 6) styleClass += " rf-cal-right-c"; 554 555 this.dayCellClassName.push(styleClass); 556 htmlTextWeek.push('<td class="' + styleClass + '" id="' + this.DATE_ELEMENT_ID + p + '" ' + 557 eventsStr + 558 '>' + (this.customDayListMarkup ? '<div class="rf-cal-c-cnt' + (this.options.dayCellClass ? ' ' + this.options.dayCellClass : '') + '"></div>' : '') + '</td>'); 559 p++; 560 } 561 htmlTextWeek.push('</tr>'); 562 } 563 564 var div = rf.getDomElement(this.CALENDAR_CONTENT); 565 div = $(div).replaceWith(htmlTextHeader + htmlHeaderOptional + htmlControlsHeader + htmlTextWeekDayBar.join('') + htmlTextWeek.join('') + htmlControlsFooter + htmlFooterOptional + htmlTextFooter); 566 this.attachToDom(); // TODO: optimize double $ 567 568 // memory leaks fix // from old 3.3.x code, may be not needed now 569 div = null; 570 571 // add onclick event handlers to input field and popup button 572 if (this.options.popup && !this.options.disabled) { 573 var handler = new Function('event', "RichFaces.component('" + this.id + "').switchPopup();"); 574 rf.Event.bindById(this.POPUP_BUTTON_ID, "click" + this.namespace, handler, this); 575 if (!this.options.enableManualInput) { 576 rf.Event.bindById(this.INPUT_DATE_ID, "click" + this.namespace, handler, this); 577 } 578 if (this.options.defaultLabel) { 579 updateDefaultLabel.call(this, this.options.defaultLabel); 580 rf.Event.bindById(this.INPUT_DATE_ID, "focus" + this.namespace + " blur" + this.namespace, onFocusBlur, this); 581 } 582 } 583 584 this.scrollElements = null; 585 586 //define isAjaxMode variable 587 this.isAjaxMode = this.options.mode == "ajax"; 588 589 //alert(new Date().getTime()-_d.getTime()); 590 }; 591 592 // Extend component class and add protected methods from parent class to our container 593 rf.BaseComponent.extend(rf.ui.Calendar); 594 595 // define super class link 596 var $super = rf.ui.Calendar.$super; 597 598 // static methods definition 599 var locales = {}; 600 601 rf.ui.Calendar.addLocale = function (locale, symbols) { 602 if (!locales[locale]) { 603 locales[locale] = symbols; 604 } 605 }; 606 607 /* 608 * Prototype definition 609 */ 610 $.extend(rf.ui.Calendar.prototype, { 611 name: "Calendar", 612 destroy: function() { 613 if (this.options.popup && this.isVisible) { 614 this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this); 615 this.scrollElements = null; 616 rf.Event.unbind(window.document, "click" + this.namespace); 617 } 618 $super.destroy.call(this); 619 }, 620 621 dateEditorSelectYear: function(value) { 622 if (this.dateEditorYearID) { 623 $(rf.getDomElement(this.dateEditorYearID)).removeClass('rf-cal-edtr-btn-sel'); 624 } 625 this.dateEditorYear = this.dateEditorStartYear + value; 626 this.dateEditorYearID = this.DATE_EDITOR_LAYOUT_ID + 'Y' + value; 627 $(rf.getDomElement(this.dateEditorYearID)).addClass('rf-cal-edtr-btn-sel'); 628 }, 629 630 dateEditorSelectMonth: function(value) { 631 this.dateEditorMonth = value; 632 $(rf.getDomElement(this.dateEditorMonthID)).removeClass('rf-cal-edtr-btn-sel'); 633 this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + value; 634 $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel'); 635 }, 636 637 scrollEditorYear: function(value) { 638 var element = rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID + 'TR'); 639 640 if (this.dateEditorYearID) { 641 $(rf.getDomElement(this.dateEditorYearID)).removeClass('rf-cal-edtr-btn-sel'); 642 this.dateEditorYearID = ''; 643 } 644 645 if (!value) { 646 // update month selection when open editor (value == 0) 647 if (this.dateEditorMonth != this.getCurrentMonth()) { 648 this.dateEditorMonth = this.getCurrentMonth(); 649 $(rf.getDomElement(this.dateEditorMonthID)).removeClass('rf-cal-edtr-btn-sel'); 650 this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + this.dateEditorMonth; 651 $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel'); 652 } 653 } 654 655 if (element) { 656 var div; 657 var year = this.dateEditorStartYear = this.dateEditorStartYear + value * 10; 658 for (var i = 0; i < 5; i++) { 659 element = element.nextSibling; 660 div = element.firstChild.nextSibling.nextSibling; 661 div.firstChild.innerHTML = year; 662 if (year == this.dateEditorYear) { 663 $(div.firstChild).addClass('rf-cal-edtr-btn-sel'); 664 this.dateEditorYearID = div.firstChild.id; 665 } 666 div = div.nextSibling; 667 div.firstChild.innerHTML = year + 5; 668 if (year + 5 == this.dateEditorYear) { 669 $(div.firstChild).addClass('rf-cal-edtr-btn-sel'); 670 this.dateEditorYearID = div.firstChild.id; 671 } 672 year++; 673 } 674 } 675 }, 676 677 updateDateEditor: function() { 678 this.dateEditorYear = this.getCurrentYear(); 679 this.dateEditorStartYear = this.getCurrentYear() - 4; 680 this.scrollEditorYear(0); 681 }, 682 683 updateTimeEditor: function() { 684 var th = rf.getDomElement(this.id + 'TimeHours'); 685 var ts = rf.getDomElement(this.id + 'TimeSign'); 686 var tm = rf.getDomElement(this.id + 'TimeMinutes'); 687 688 var h = this.selectedDate.getHours(); 689 var m = this.selectedDate.getMinutes(); 690 if (this.timeType == 2) { 691 var a = (h < 12 ? 'AM' : 'PM'); 692 ts.value = a; 693 h = (h == 0 ? '12' : (h > 12 ? h - 12 : h)); 694 } 695 th.value = (this.timeHoursDigits == 2 && h < 10 ? '0' + h : h); 696 tm.value = (m < 10 ? '0' + m : m); 697 698 if (this.showSeconds) { 699 var tsec = rf.getDomElement(this.id + 'TimeSeconds'); 700 var s = this.selectedDate.getSeconds(); 701 tsec.value = (s < 10 ? '0' + s : s); 702 } 703 }, 704 705 706 createEditor: function() { 707 var element = $(rf.getDomElement(this.CALENDAR_CONTENT)); 708 var zindex = parseInt(element.css('z-index'), 10); 709 var htmlBegin = '<div id="' + this.EDITOR_SHADOW_ID + '" class="rf-cal-edtr-shdw" style="position:absolute; display:none;z-index:' + zindex + '"></div><table border="0" cellpadding="0" cellspacing="0" id="' + this.EDITOR_ID + '" style="position:absolute; display:none;z-index:' + (zindex + 1) + '" onclick="RichFaces.component(\'' + this.id + '\').skipEventOnCollapse=true;"><tbody><tr><td class="rf-cal-edtr-cntr" align="center"><div style="position:relative; display:inline-block;">'; 710 var htmlContent = '<div id="' + this.EDITOR_LAYOUT_SHADOW_ID + '" class="rf-cal-edtr-layout-shdw"></div>'; 711 712 var htmlEnd = '</div></td></tr></tbody></table>'; 713 element.after(htmlBegin + htmlContent + htmlEnd); 714 715 this.isEditorCreated = true; 716 717 return rf.getDomElement(this.EDITOR_ID); 718 }, 719 720 createTimeEditorLayout: function(editor) { 721 $(rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID)).after(this.evaluateMarkup(CalendarView.timeEditorLayout, this.calendarContext)); 722 723 var th = rf.getDomElement(this.id + 'TimeHours'); 724 var ts; 725 var tm = rf.getDomElement(this.id + 'TimeMinutes'); 726 if (this.timeType == 1) { 727 sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:0,max:23}); 728 } 729 else { 730 sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:1,max:12}); 731 ts = rf.getDomElement(this.id + 'TimeSign'); 732 sbjQuery(ts).SpinButton({}); 733 } 734 sbjQuery(tm).SpinButton({digits:2,min:0,max:59}); 735 if (this.showSeconds) { 736 var tsec = rf.getDomElement(this.id + 'TimeSeconds'); 737 sbjQuery(tsec).SpinButton({digits:2,min:0,max:59}); 738 } 739 740 this.correctEditorButtons(editor, this.TIME_EDITOR_BUTTON_OK, this.TIME_EDITOR_BUTTON_CANCEL); 741 742 this.isTimeEditorLayoutCreated = true; 743 }, 744 745 correctEditorButtons: function(editor, buttonID1, buttonID2) { 746 var button1 = rf.getDomElement(buttonID1); 747 var button2 = rf.getDomElement(buttonID2); 748 editor.style.visibility = "hidden"; 749 editor.style.display = ""; 750 var width1 = $(button1.firstChild).width(); 751 var width2 = $(button2.firstChild).width(); 752 editor.style.display = "none"; 753 editor.style.visibility = ""; 754 755 if (width1 != width2) { 756 button1.style.width = button2.style.width = (width1 > width2 ? width1 : width2) + "px"; 757 } 758 }, 759 760 createDECell: function(id, value, buttonType, param, className) { 761 if (buttonType == 0) { 762 return '<div id="' + id + '" class="rf-cal-edtr-btn' + (className ? ' ' + className : '') + 763 '" onmouseover="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-over\';" onmouseout="this.className=\'rf-cal-edtr-btn\';" onmousedown="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-press\';" onmouseup="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-over\';" onclick="RichFaces.component(\'' + this.id + '\').scrollEditorYear(' + param + ');">' + value + '</div>'; 764 } 765 else { 766 var onclick = (buttonType == 1 ? 'RichFaces.component(\'' + this.id + '\').dateEditorSelectMonth(' + param + ');' : 767 'RichFaces.component(\'' + this.id + '\').dateEditorSelectYear(' + param + ');' ); 768 return '<div id="' + id + '" class="rf-cal-edtr-btn' + (className ? ' ' + className : '') + 769 '" onmouseover="RichFaces.jQuery(this).addClass(\'rf-cal-edtr-btn-over\');" onmouseout="$(this).removeClass(\'rf-cal-edtr-btn-over\');" onclick="' + onclick + '">' + value + '</div>'; 770 } 771 }, 772 773 createDateEditorLayout: function(editor) { 774 var htmlBegin = '<table id="' + this.DATE_EDITOR_LAYOUT_ID + '" class="rf-cal-monthpicker-cnt" border="0" cellpadding="0" cellspacing="0"><tbody><tr id="' + this.DATE_EDITOR_LAYOUT_ID + 'TR">'; 775 var htmlEnd = '</tr></tbody></table>'; 776 var month = 0; 777 this.dateEditorYear = this.getCurrentYear(); 778 var year = this.dateEditorStartYear = this.dateEditorYear - 4; 779 var htmlContent = '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + month, this.options.monthLabelsShort[month], 1, month) + '</td>' 780 + '<td align="center" class="rf-cal-monthpicker-split">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + (month + 6), this.options.monthLabelsShort[month + 6], 1, month + 6) + '</td>' 781 + '<td align="center">' + this.createDECell('', '<', 0, -1) + '</td>' 782 + '<td align="center">' + this.createDECell('', '>', 0, 1) + '</td>'; 783 month++; 784 785 for (var i = 0; i < 5; i++) { 786 htmlContent += '</tr><tr><td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + month, this.options.monthLabelsShort[month], 1, month) + '</td>' 787 + '<td align="center" class="rf-cal-monthpicker-split">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + (month + 6), this.options.monthLabelsShort[month + 6], 1, month + 6) + '</td>' 788 + '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'Y' + i, year, 2, i, (i == 4 ? 'rf-cal-edtr-btn-sel' : '')) + '</td>' 789 + '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'Y' + (i + 5), year + 5, 2, i + 5) + '</td>'; 790 month++; 791 year++; 792 } 793 this.dateEditorYearID = this.DATE_EDITOR_LAYOUT_ID + 'Y4'; 794 this.dateEditorMonth = this.getCurrentMonth(); 795 this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + this.dateEditorMonth; 796 797 htmlContent += '</tr><tr><td colspan="2" class="rf-cal-monthpicker-ok">' + 798 '<div id="' + this.DATE_EDITOR_BUTTON_OK + '" class="rf-cal-time-btn" style="float:right;" onmousedown="RichFaces.jQuery(this).addClass(\'rf-cal-time-btn-press\');" onmouseout="RichFaces.jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onmouseup="RichFaces.jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onclick="RichFaces.component(\'' + this.id + '\').hideDateEditor(true);"><span>' + this.options.labels.ok + '</span></div>' + 799 '</td><td colspan="2" class="rf-cal-monthpicker-cancel">' + 800 '<div id="' + this.DATE_EDITOR_BUTTON_CANCEL + '" class="rf-cal-time-btn" style="float:left;" onmousedown="RichFaces.jQuery(this).addClass(\'rf-cal-time-btn-press\');" onmouseout="RichFaces.jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onmouseup="RichFaces.jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onclick="RichFaces.component(\'' + this.id + '\').hideDateEditor(false);"><span>' + this.options.labels.cancel + '</span></div>' + 801 '</td>'; 802 803 804 $(rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID)).after(htmlBegin + htmlContent + htmlEnd); 805 806 $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel'); 807 808 this.correctEditorButtons(editor, this.DATE_EDITOR_BUTTON_OK, this.DATE_EDITOR_BUTTON_CANCEL); 809 810 this.isDateEditorLayoutCreated = true; 811 }, 812 813 createSpinnerTable: function(id) { 814 return '<table cellspacing="0" cellpadding="0" border="0"><tbody><tr>' + 815 '<td class="rf-cal-sp-inp-ctnr">' + 816 '<input id="' + id + '" name="' + id + '" class="rf-cal-sp-inp" type="text" />' + 817 '</td>' + 818 '<td class="rf-cal-sp-btn">' + 819 '<table border="0" cellspacing="0" cellpadding="0"><tbody>' + 820 '<tr><td>' + 821 '<div id="' + id + 'BtnUp" class="rf-cal-sp-up"' + 822 ' onmousedown="this.className=\'rf-cal-sp-up rf-cal-sp-press\'"' + 823 ' onmouseup="this.className=\'rf-cal-sp-up\'"' + 824 ' onmouseout="this.className=\'rf-cal-sp-up\'"><span></span></div>' + 825 '</td></tr>' + 826 '<tr><td>' + 827 '<div id="' + id + 'BtnDown" class="rf-cal-sp-down"' + 828 ' onmousedown="this.className=\'rf-cal-sp-down rf-cal-sp-press\'"' + 829 ' onmouseup="this.className=\'rf-cal-sp-down\'"' + 830 ' onmouseout="this.className=\'rf-cal-sp-down\'"><span></span></div>' + 831 '</td></tr>' + 832 '</tbody></table>' + 833 '</td>' + 834 '</tr></tbody></table>'; 835 }, 836 837 setTimeProperties: function() { 838 this.timeType = 0; 839 840 var dateTimePattern = this.options.datePattern; 841 var pattern = []; 842 var re = /(\\\\|\\[yMdaHhms])|(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g; 843 var r; 844 while (r = re.exec(dateTimePattern)) 845 if (!r[1]) 846 pattern.push({str:r[0],marker:r[2],idx:r.index}); 847 848 var datePattern = ""; 849 var timePattern = ""; 850 851 var digits,h,hh,m,s,a; 852 var id = this.id; 853 854 var getString = function (p) { 855 return (p.length == 0 ? obj.marker : dateTimePattern.substring(pattern[i - 1].str.length + pattern[i - 1].idx, obj.idx + obj.str.length)); 856 }; 857 858 for (var i = 0; i < pattern.length; i++) { 859 var obj = pattern[i]; 860 var ch = obj.marker.charAt(0); 861 if (ch == 'y' || ch == 'M' || ch == 'd') datePattern += getString(datePattern); 862 else if (ch == 'a') { 863 a = true; 864 timePattern += getString(timePattern); 865 } 866 else if (ch == 'H') { 867 h = true; 868 digits = obj.marker.length; 869 timePattern += getString(timePattern); 870 } 871 else if (ch == 'h') { 872 hh = true; 873 digits = obj.marker.length; 874 timePattern += getString(timePattern); 875 } 876 else if (ch == 'm') { 877 m = true; 878 timePattern += getString(timePattern); 879 } 880 else if (ch == 's') { 881 this.showSeconds = true; 882 timePattern += getString(timePattern); 883 } 884 885 886 } 887 this.datePattern = datePattern; 888 this.timePattern = timePattern; 889 890 var calendar = this; 891 892 this.timePatternHtml = timePattern.replace(/(\\\\|\\[yMdaHhms])|(H{1,2}|h{1,2}|m{2}|s{2}|a)/g, 893 function($1, $2, $3) { 894 if ($2) return $2.charAt(1); 895 switch ($3) { 896 case 'a' : 897 return '</td><td>' + calendar.createSpinnerTable(id + 'TimeSign') + '</td><td>'; 898 case 'H' : 899 case 'HH' : 900 case 'h' : 901 case 'hh' : 902 return '</td><td>' + calendar.createSpinnerTable(id + 'TimeHours') + '</td><td>'; 903 case 'mm' : 904 return '</td><td>' + calendar.createSpinnerTable(id + 'TimeMinutes') + '</td><td>'; 905 case 'ss' : 906 return '</td><td>' + calendar.createSpinnerTable(id + 'TimeSeconds') + '</td><td>'; 907 } 908 } 909 ); 910 911 this.timePatternHtml = '<table border="0" cellpadding="0"><tbody><tr><td>' + this.timePatternHtml + '</td></tr></tbody></table>'; 912 913 if (m && h) { 914 this.timeType = 1; 915 } 916 else if (m && hh && a) { 917 this.timeType = 2; 918 } 919 this.timeHoursDigits = digits; 920 }, 921 922 eventOnScroll: function (e) { 923 this.hidePopup(); 924 }, 925 926 hidePopup: function() { 927 928 if (!this.options.popup || !this.isVisible) return; 929 930 if (this.invokeEvent("hide", rf.getDomElement(this.id))) { 931 if (this.isEditorVisible) this.hideEditor(); 932 this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this); 933 this.scrollElements = null; 934 rf.Event.unbind(window.document, "click" + this.namespace); 935 936 $(rf.getDomElement(this.CALENDAR_CONTENT)).hide(); 937 this.isVisible = false; 938 if (this.options.defaultLabel && !this.isFocused) { 939 updateDefaultLabel.call(this, this.options.defaultLabel); 940 } 941 } 942 }, 943 944 showPopup: function(e) { 945 if (!this.isRendered) { 946 this.isRendered = true; 947 this.render(); 948 } 949 this.skipEventOnCollapse = false; 950 if (e && e.type == 'click') this.skipEventOnCollapse = true; 951 if (!this.options.popup || this.isVisible) return; 952 953 var element = rf.getDomElement(this.id); 954 955 if (this.invokeEvent("show", element, e)) { 956 var base = rf.getDomElement(this.POPUP_ID) 957 var baseInput = base.firstChild; 958 var baseButton = baseInput.nextSibling; 959 960 if (this.options.defaultLabel) { 961 if (!this.isFocused) updateDefaultLabel.call(this, ""); 962 } 963 if (baseInput.value) { 964 this.__selectDate(baseInput.value, false, {event:e, element:element}); 965 } 966 967 //rect calculation 968 969 if (this.options.showInput) { 970 base = base.children; 971 } else { 972 base = baseButton; 973 } 974 ; 975 976 $(rf.getDomElement(this.CALENDAR_CONTENT)).setPosition(base, {type:"DROPDOWN", from: this.options.jointPoint, to:this.options.direction, offset: this.popupOffset}).show(); 977 978 this.isVisible = true; 979 980 rf.Event.bind(window.document, "click" + this.namespace, this.eventOnCollapse, this); 981 982 this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this); 983 this.scrollElements = null; 984 if (this.options.hidePopupOnScroll) { 985 this.scrollElements = rf.Event.bindScrollEventHandlers(element, this.eventOnScroll, this); 986 } 987 } 988 }, 989 990 switchPopup: function(e) { 991 this.isVisible ? this.hidePopup() : this.showPopup(e); 992 }, 993 994 eventOnCollapse: function (e) { 995 if (this.skipEventOnCollapse) { 996 this.skipEventOnCollapse = false; 997 return true; 998 } 999 1000 if (e.target.id == this.POPUP_BUTTON_ID || (!this.options.enableManualInput && e.target.id == this.INPUT_DATE_ID)) return true; 1001 1002 this.hidePopup(); 1003 1004 return true; 1005 }, 1006 1007 setInputField: function(dateStr, event) { 1008 var field = rf.getDomElement(this.INPUT_DATE_ID); 1009 if (field.value != dateStr) { 1010 field.value = dateStr; 1011 this.invokeEvent("change", rf.getDomElement(this.id), event, this.selectedDate); 1012 $(rf.getDomElement(this.INPUT_DATE_ID)).blur(); 1013 } 1014 }, 1015 1016 getCurrentDate: function() { 1017 return this.currentDate; 1018 }, 1019 __getSelectedDate: function() { 1020 if (!this.selectedDate) return null; else return this.selectedDate; 1021 }, 1022 __getSelectedDateString: function(pattern) { 1023 if (!this.selectedDate) return ""; 1024 if (!pattern) pattern = this.options.datePattern; 1025 return rf.calendarUtils.formatDate(this.selectedDate, pattern, this.options.monthLabels, this.options.monthLabelsShort); 1026 }, 1027 1028 getPrevYear: function() { 1029 var value = this.currentDate.getFullYear() - 1; 1030 if (value < 0) value = 0; 1031 return value; 1032 }, 1033 getPrevMonth: function(asMonthLabel) { 1034 var value = this.currentDate.getMonth() - 1; 1035 if (value < 0) value = 11; 1036 if (asMonthLabel) { 1037 return this.options.monthLabels[value]; 1038 } else return value; 1039 }, 1040 getCurrentYear: function() { 1041 return this.currentDate.getFullYear(); 1042 }, 1043 getCurrentMonth: function(asMonthLabel) { 1044 var value = this.currentDate.getMonth(); 1045 if (asMonthLabel) { 1046 return this.options.monthLabels[value]; 1047 } else return value; 1048 }, 1049 getNextYear: function() { 1050 return this.currentDate.getFullYear() + 1; 1051 }, 1052 getNextMonth: function(asMonthLabel) { 1053 var value = this.currentDate.getMonth() + 1; 1054 if (value > 11) value = 0; 1055 if (asMonthLabel) { 1056 return this.options.monthLabels[value]; 1057 } else return value; 1058 }, 1059 1060 isWeekend: function(weekday) { 1061 return (weekday == this.firstWeekendDayNumber || weekday == this.secondWeekendDayNumber); 1062 }, 1063 1064 setupTimeForDate: function (date) { 1065 var result = new Date(date); 1066 if (this.selectedDate && (!this.options.resetTimeOnDateSelect || 1067 (this.selectedDate.getFullYear() == date.getFullYear() && 1068 this.selectedDate.getMonth() == date.getMonth() && 1069 this.selectedDate.getDate() == date.getDate()))) { 1070 result = rf.calendarUtils.createDate(date.getFullYear(), date.getMonth(), date.getDate(), this.selectedDate.getHours(), this.selectedDate.getMinutes(), this.selectedDate.getSeconds()); 1071 } else { 1072 result = rf.calendarUtils.createDate(date.getFullYear(), date.getMonth(), date.getDate(), this.options.defaultTime.hours, this.options.defaultTime.minutes, this.options.defaultTime.seconds); 1073 } 1074 return result; 1075 }, 1076 1077 eventCellOnClick: function (e, obj) { 1078 var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)]; 1079 if (daydata.enabled && daydata._month == 0) { 1080 var date = rf.calendarUtils.createDate(this.currentDate.getFullYear(), this.currentDate.getMonth(), daydata.day); 1081 if (this.timeType) { 1082 date = this.setupTimeForDate(date); 1083 } 1084 1085 if (this.__selectDate(date, true, {event:e, element:obj}) && !this.options.showApplyButton) { 1086 this.hidePopup(); 1087 } 1088 1089 } else if (daydata._month != 0) { 1090 if (this.options.boundaryDatesMode == "scroll") 1091 if (daydata._month == -1) this.prevMonth(); else this.nextMonth(); 1092 else if (this.options.boundaryDatesMode == "select") { 1093 var date = new Date(daydata.date); 1094 if (this.timeType) { 1095 date = this.setupTimeForDate(date); 1096 } 1097 1098 if (this.__selectDate(date, false, {event:e, element:obj}) && !this.options.showApplyButton) { 1099 this.hidePopup(); 1100 } 1101 } 1102 } 1103 }, 1104 1105 eventCellOnMouseOver: function (e, obj) { 1106 var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)]; 1107 if (this.invokeEvent("datemouseover", obj, e, daydata.date) && daydata.enabled) { 1108 if (daydata._month == 0 && obj.id != this.selectedDateCellId && obj.id != this.todayCellId) { 1109 $(obj).addClass('rf-cal-hov'); 1110 } 1111 } 1112 }, 1113 1114 eventCellOnMouseOut: function (e, obj) { 1115 var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)]; 1116 if (this.invokeEvent("datemouseout", obj, e, daydata.date) && daydata.enabled) { 1117 if (daydata._month == 0 && obj.id != this.selectedDateCellId && obj.id != this.todayCellId) { 1118 $(obj).removeClass('rf-cal-hov'); 1119 } 1120 } 1121 }, 1122 1123 load:function(daysData, isAjaxMode) { 1124 // startDate, 1125 // daysData:array[] 1126 // { 1127 // day 1128 // enabled boolean 1129 // text1: 'Meeting...', 1130 // text2: 'Meeting...' 1131 // tooltip 1132 // hasTooltip 1133 // styleClass 1134 // } 1135 1136 1137 if (daysData) { 1138 this.daysData = this.indexData(daysData, isAjaxMode); 1139 } else { 1140 this.daysData = null; 1141 } 1142 1143 this.isRendered = false; 1144 if (this.isVisible) { 1145 this.render(); 1146 } 1147 ; 1148 1149 if (typeof this.afterLoad == 'function') { 1150 this.afterLoad(); 1151 this.afterLoad = null; 1152 } 1153 }, 1154 1155 indexData:function(daysData, isAjaxMode) { 1156 1157 var dateYear = daysData.startDate.year; 1158 var dateMonth = daysData.startDate.month; 1159 daysData.startDate = new Date(dateYear, dateMonth) 1160 1161 daysData.index = []; 1162 daysData.index[dateYear + '-' + dateMonth] = 0; 1163 if (isAjaxMode) { 1164 this.currentDate = daysData.startDate; 1165 this.currentDate.setDate(1); 1166 return daysData; 1167 } 1168 var idx = rf.calendarUtils.daysInMonthByDate(daysData.startDate) - daysData.startDate.getDate() + 1; 1169 1170 while (daysData.days[idx]) { 1171 if (dateMonth == 11) { 1172 dateYear++; 1173 dateMonth = 0; 1174 } else dateMonth++; 1175 daysData.index[dateYear + '-' + dateMonth] = idx; 1176 idx += (32 - new Date(dateYear, dateMonth, 32).getDate()); 1177 } 1178 return daysData; 1179 }, 1180 1181 getCellBackgroundColor: function(element) { 1182 return $(element).css('background-color'); 1183 }, 1184 1185 clearEffect: function (element_id, className, className1) { 1186 if (element_id) { 1187 var e = $(rf.getDomElement(element_id)).stop(true, true); 1188 if (className) e.removeClass(className); 1189 if (className1) e.addClass(className1); 1190 } 1191 return null; 1192 }, 1193 1194 render:function() { 1195 //var _d=new Date(); 1196 this.isRendered = true; 1197 this.todayDate = new Date(); 1198 1199 var currentYear = this.getCurrentYear(); 1200 var currentMonth = this.getCurrentMonth(); 1201 1202 var todayflag = (currentYear == this.todayDate.getFullYear() && currentMonth == this.todayDate.getMonth()); 1203 var todaydate = this.todayDate.getDate(); 1204 1205 var selectedflag = this.selectedDate && (currentYear == this.selectedDate.getFullYear() && currentMonth == this.selectedDate.getMonth()) 1206 var selecteddate = this.selectedDate && this.selectedDate.getDate(); 1207 1208 var wd = rf.calendarUtils.getDay(this.currentDate, this.options.firstWeekDay); 1209 var currentMonthDays = rf.calendarUtils.daysInMonthByDate(this.currentDate); 1210 var previousMonthDays = rf.calendarUtils.daysInMonth(currentYear, currentMonth - 1); 1211 1212 var p = 0; 1213 var month = -1; 1214 this.days = []; 1215 var dayCounter = previousMonthDays - wd + 1; 1216 1217 // previuos month days 1218 if (wd > 0) while (dayCounter <= previousMonthDays) { 1219 this.days.push({day:dayCounter, isWeekend: this.isWeekend(p), _month:month}); 1220 dayCounter++; 1221 p++; 1222 } 1223 1224 dayCounter = 1; 1225 month = 0; 1226 1227 this.firstDateIndex = p; 1228 1229 // current month days 1230 if (this.daysData && this.daysData.index[currentYear + '-' + currentMonth] != undefined) { 1231 var idx = this.daysData.index[currentYear + '-' + currentMonth]; 1232 if (this.daysData.startDate.getFullYear() == currentYear && this.daysData.startDate.getMonth() == currentMonth) { 1233 var firstDay = firstDay = (this.daysData.days[idx].day ? this.daysData.days[idx].day : this.daysData.startDate.getDate()); 1234 while (dayCounter < firstDay) { 1235 this.days.push({day:dayCounter, isWeekend:this.isWeekend(p % 7), _month:month}); 1236 1237 dayCounter++; 1238 p++; 1239 } 1240 } 1241 1242 var len = this.daysData.days.length; 1243 var obj; 1244 var flag; 1245 while (idx < len && dayCounter <= currentMonthDays) { 1246 flag = this.isWeekend(p % 7); 1247 obj = this.daysData.days[idx]; 1248 obj.day = dayCounter; 1249 obj.isWeekend = flag; 1250 obj._month = month; 1251 this.days.push(obj); 1252 idx++; 1253 dayCounter++; 1254 p++; 1255 } 1256 } 1257 while (p < 42) { 1258 if (dayCounter > currentMonthDays) { 1259 dayCounter = 1; 1260 month = 1; 1261 } 1262 this.days.push({day:dayCounter, isWeekend: this.isWeekend(p % 7), _month:month}); 1263 dayCounter++; 1264 p++; 1265 } 1266 1267 // render 1268 this.renderHF(); 1269 1270 //days render 1271 p = 0; 1272 var element; 1273 var dataobj; 1274 var wn; 1275 if (this.options.showWeeksBar) wn = rf.calendarUtils.weekNumber(currentYear, currentMonth, this.options.minDaysInFirstWeek, this.options.firstWeekDay); /// fix it 1276 this.selectedDayElement = null; 1277 var weekflag = true; 1278 1279 var e; 1280 1281 var boundaryDatesModeFlag = (this.options.boundaryDatesMode == "scroll" || this.options.boundaryDatesMode == "select"); 1282 1283 this.todayCellId = this.clearEffect(this.todayCellId); 1284 this.selectedDateCellId = this.clearEffect(this.selectedDateCellId); 1285 1286 //var _d=new Date(); 1287 var obj = rf.getDomElement(this.WEEKNUMBER_BAR_ID + "1"); 1288 for (var k = 1; k < 7; k++) { 1289 // 1290 dataobj = this.days[p]; 1291 1292 element = obj.firstChild; 1293 var weeknumber; 1294 1295 // week number update 1296 if (this.options.showWeeksBar) { 1297 // TODO: fix: there is no weekNumber in dataobj if showWeeksBar == false; 1298 if (weekflag && currentMonth == 11 && 1299 (k == 5 || k == 6) && 1300 (dataobj._month == 1 || (7 - (currentMonthDays - dataobj.day + 1)) >= this.options.minDaysInFirstWeek)) { 1301 wn = 1; 1302 weekflag = false; 1303 } 1304 weeknumber = wn; 1305 element.innerHTML = this.evaluateMarkup(this.options.weekNumberMarkup, {weekNumber: wn++, elementId:element.id, component:this}); 1306 if (k == 1 && wn > 52) wn = 1; 1307 element = element.nextSibling; 1308 } 1309 1310 var weekdaycounter = this.options.firstWeekDay; 1311 var contentElement = null; 1312 1313 while (element) { 1314 dataobj.elementId = element.id; 1315 dataobj.date = new Date(currentYear, currentMonth + dataobj._month, dataobj.day); 1316 dataobj.weekNumber = weeknumber; 1317 dataobj.component = this; 1318 dataobj.isCurrentMonth = (dataobj._month == 0); 1319 dataobj.weekDayNumber = weekdaycounter; 1320 1321 // call user function to get day state 1322 if (dataobj.enabled != false) dataobj.enabled = this.options.isDayEnabled(dataobj); 1323 // call user function to custom class style 1324 if (!dataobj.styleClass) dataobj.customStyleClass = this.options.dayStyleClass(dataobj); 1325 else { 1326 var styleclass = this.options.dayStyleClass(dataobj); 1327 dataobj.customStyleClass = dataobj.styleClass; 1328 if (styleclass) dataobj.customStyleClass += " " + styleclass; 1329 } 1330 1331 contentElement = (this.customDayListMarkup ? element.firstChild : element); 1332 contentElement.innerHTML = this.hideBoundaryDatesContent && dataobj._month != 0 ? "" : this.evaluateMarkup(this.options.dayListMarkup, dataobj); 1333 1334 if (weekdaycounter == 6) weekdaycounter = 0; else weekdaycounter++; 1335 1336 var classNames = this.dayCellClassName[p]; 1337 1338 // class styles 1339 if (dataobj._month != 0) { 1340 classNames += ' rf-cal-boundary-day'; 1341 if (!this.options.disabled && !this.options.readonly && boundaryDatesModeFlag) { 1342 classNames += ' rf-cal-btn'; 1343 } 1344 } 1345 else { 1346 if (todayflag && dataobj.day == todaydate) { 1347 this.todayCellId = element.id; 1348 this.todayCellColor = this.getCellBackgroundColor(element); 1349 classNames += " rf-cal-today"; 1350 } 1351 1352 if (selectedflag && dataobj.day == selecteddate) { 1353 this.selectedDateCellId = element.id; 1354 this.selectedDateCellColor = this.getCellBackgroundColor(element); 1355 classNames += " rf-cal-sel"; 1356 } 1357 else if (!this.options.disabled && !this.options.readonly && dataobj.enabled) classNames += ' rf-cal-btn'; 1358 1359 // add custom style class 1360 if (dataobj.customStyleClass) { 1361 classNames += ' ' + dataobj.customStyleClass; 1362 } 1363 } 1364 element.className = classNames; 1365 1366 p++; 1367 1368 dataobj = this.days[p]; 1369 element = element.nextSibling; 1370 } 1371 obj = obj.nextSibling; 1372 } 1373 1374 //alert(new Date().getTime()-_d.getTime()); 1375 1376 }, 1377 1378 renderHF: function() { 1379 if (this.options.showHeader) this.renderMarkup(this.options.headerMarkup, this.id + "Header", this.calendarContext); 1380 if (this.options.showFooter) this.renderMarkup(this.options.footerMarkup, this.id + "Footer", this.calendarContext); 1381 1382 this.renderHeaderOptional(); 1383 this.renderFooterOptional(); 1384 }, 1385 1386 renderHeaderOptional: function() { 1387 this.renderMarkup(this.options.optionalHeaderMarkup, this.id + "HeaderOptional", this.calendarContext); 1388 }, 1389 1390 renderFooterOptional: function() { 1391 this.renderMarkup(this.options.optionalFooterMarkup, this.id + "FooterOptional", this.calendarContext); 1392 }, 1393 1394 renderMarkup: function (markup, elementId, context) { 1395 if (!markup) return; 1396 1397 var e = rf.getDomElement(elementId); 1398 if (!e) return; 1399 1400 e.innerHTML = this.evaluateMarkup(markup, context); 1401 }, 1402 1403 evaluateMarkup: function(markup, context) { 1404 if (!markup) return ""; 1405 1406 var result = []; 1407 var m; 1408 for (var i = 0; i < markup.length; i++) { 1409 m = markup[i]; 1410 if (m['getContent']) { 1411 result.push(m.getContent(context)); 1412 } 1413 } 1414 return result.join(''); 1415 }, 1416 1417 onUpdate: function() { 1418 var formattedDate = rf.calendarUtils.formatDate(this.getCurrentDate(), "MM/yyyy"); 1419 rf.getDomElement(this.id + 'InputCurrentDate').value = formattedDate; 1420 1421 if (this.isAjaxMode && this.callAjax) 1422 this.callAjax.call(this, formattedDate); 1423 else 1424 this.render(); 1425 }, 1426 1427 callAjax: function(calendar, date) { 1428 var _this = this; 1429 var ajaxSuccess = function (event) { 1430 var dataDays = event && event.componentData && event.componentData[_this.id]; 1431 _this.load(dataDays, true); 1432 } 1433 var ajaxError = function (event) { 1434 // do nothing 1435 } 1436 var params = {}; 1437 params[this.id + ".ajax"] = "1"; 1438 1439 rf.ajax(this.id, null, {parameters: params, error: ajaxError, complete:ajaxSuccess}); 1440 1441 }, 1442 1443 nextMonth: function() { 1444 this.changeCurrentDateOffset(0, 1); 1445 }, 1446 1447 prevMonth: function() { 1448 this.changeCurrentDateOffset(0, -1); 1449 }, 1450 1451 nextYear: function() { 1452 this.changeCurrentDateOffset(1, 0); 1453 }, 1454 1455 prevYear: function() { 1456 this.changeCurrentDateOffset(-1, 0); 1457 }, 1458 1459 changeCurrentDate: function(year, month, noUpdate) { 1460 if (this.getCurrentMonth() != month || this.getCurrentYear() != year) { 1461 var date = new Date(year, month, 1); 1462 if (this.invokeEvent("beforecurrentdateselect", rf.getDomElement(this.id), null, date)) { 1463 // fix for RF-2450. 1464 // Additional event is fired: after the hidden input with current date 1465 // value is updated in function onUpdate() and then 1466 // the "currentdateselected" Event is fired. 1467 this.currentDate = date; 1468 if (noUpdate) this.render(); else this.onUpdate(); 1469 this.invokeEvent("currentdateselect", rf.getDomElement(this.id), null, date); 1470 return true; 1471 } 1472 } 1473 return false; 1474 }, 1475 1476 changeCurrentDateOffset: function(yearOffset, monthOffset) { 1477 var date = new Date(this.currentDate.getFullYear() + yearOffset, this.currentDate.getMonth() + monthOffset, 1); 1478 1479 if (this.invokeEvent("beforecurrentdateselect", rf.getDomElement(this.id), null, date)) { 1480 // fix for RF-2450. 1481 // Additional event is fired: after the hidden input with current date 1482 // value is updated in function onUpdate() and then 1483 // the "currentdateselected" Event is fired. 1484 this.currentDate = date; 1485 this.onUpdate(); 1486 this.invokeEvent("currentdateselect", rf.getDomElement(this.id), null, date); 1487 } 1488 }, 1489 1490 today: function(noUpdate, noHighlight) { 1491 1492 var now = new Date(); 1493 1494 var nowyear = now.getFullYear(); 1495 var nowmonth = now.getMonth(); 1496 var nowdate = now.getDate(); 1497 var updateflag = false; 1498 1499 if (nowdate != this.todayDate.getDate()) { 1500 updateflag = true; 1501 this.todayDate = now; 1502 } 1503 1504 if (nowyear != this.currentDate.getFullYear() || nowmonth != this.currentDate.getMonth()) { 1505 updateflag = true; 1506 this.currentDate = new Date(nowyear, nowmonth, 1); 1507 } 1508 1509 if (this.options.todayControlMode == 'select') { 1510 noHighlight = true; 1511 } 1512 1513 if (updateflag) { 1514 if (noUpdate) this.render(); else this.onUpdate(); 1515 } 1516 else { 1517 // highlight today 1518 1519 if (this.isVisible && this.todayCellId && !noHighlight) { 1520 this.clearEffect(this.todayCellId); 1521 if (this.todayCellColor != "transparent") { 1522 $(rf.getDomElement(this.todayCellId)).effect("highlight", {easing:'easeInOutSine', color: this.todayCellColor}, 300); 1523 } 1524 } 1525 } 1526 1527 // todayControl select mode 1528 if (this.options.todayControlMode == 'select' && !this.options.disabled && !this.options.readonly) 1529 if (updateflag && !noUpdate && this.submitFunction) { 1530 this.afterLoad = this.selectToday; 1531 } 1532 else this.selectToday(); 1533 1534 }, 1535 1536 selectToday: function() { 1537 if (this.todayCellId) { 1538 var daydata = this.days[parseInt(this.todayCellId.substr(this.DATE_ELEMENT_ID.length), 10)]; 1539 var today = new Date(); 1540 var date = new Date(today); 1541 if (this.timeType) { 1542 date = this.setupTimeForDate(date); 1543 } 1544 if (daydata.enabled && this.__selectDate(date, true) && !this.options.showApplyButton) { 1545 this.hidePopup(); 1546 } 1547 } 1548 }, 1549 1550 __selectDate: function(date, noUpdate, eventData, applySelection) { 1551 1552 if (!eventData) { 1553 eventData = {event: null, element: null}; 1554 } 1555 1556 if (typeof applySelection === "undefined") { 1557 applySelection = !this.options.showApplyButton 1558 } 1559 1560 var oldSelectedDate = this.selectedDate; 1561 var newSelectedDate; 1562 if (date) { 1563 if (typeof date == 'string') { 1564 date = rf.calendarUtils.parseDate(date, this.options.datePattern, this.options.monthLabels, this.options.monthLabelsShort); 1565 } 1566 newSelectedDate = date; 1567 } 1568 else { 1569 newSelectedDate = null; 1570 } 1571 1572 // fire user event 1573 var flag = true; 1574 var isDateChange = false; 1575 if ((oldSelectedDate - newSelectedDate) && (oldSelectedDate != null || newSelectedDate != null)) { 1576 isDateChange = true; 1577 flag = this.invokeEvent("beforedateselect", eventData.element, eventData.event, date); 1578 } 1579 1580 if (flag) { 1581 if (newSelectedDate != null) { 1582 if (newSelectedDate.getMonth() == this.currentDate.getMonth() && newSelectedDate.getFullYear() == this.currentDate.getFullYear()) { 1583 this.selectedDate = newSelectedDate; 1584 if (!oldSelectedDate || (oldSelectedDate - this.selectedDate)) { 1585 // find cell and change style class 1586 var e = $(rf.getDomElement(this.DATE_ELEMENT_ID + (this.firstDateIndex + this.selectedDate.getDate() - 1))); 1587 1588 this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn")); 1589 this.selectedDateCellId = e.attr('id'); 1590 this.selectedDateCellColor = this.getCellBackgroundColor(e); 1591 1592 e.removeClass("rf-cal-btn"); 1593 e.removeClass("rf-cal-hov"); 1594 e.addClass("rf-cal-sel"); 1595 1596 this.renderHF(); 1597 } 1598 else if (this.timeType != 0) this.renderHF(); 1599 } 1600 else { 1601 //RF-5600 1602 this.selectedDate = newSelectedDate; 1603 1604 // change currentDate and call this.onUpdate(); 1605 if (this.changeCurrentDate(newSelectedDate.getFullYear(), newSelectedDate.getMonth(), noUpdate)) { 1606 //this.selectedDate = newSelectedDate; 1607 } else { 1608 this.selectedDate = oldSelectedDate; 1609 isDateChange = false; 1610 } 1611 } 1612 } 1613 else { 1614 this.selectedDate = null; 1615 1616 this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn")); 1617 1618 if (this.selectedDateCellId) { 1619 this.selectedDateCellId = null; 1620 this.renderHF(); 1621 } 1622 1623 var date = new Date(); 1624 if (this.currentDate.getMonth() == date.getMonth() && this.currentDate.getFullYear() == date.getFullYear()) { 1625 this.renderHF(); 1626 } 1627 1628 var todayControlMode = this.options.todayControlMode; 1629 this.options.todayControlMode = ''; 1630 this.today(noUpdate, true); 1631 this.options.todayControlMode = todayControlMode; 1632 } 1633 1634 // call user event 1635 if (isDateChange) { 1636 this.invokeEvent("dateselect", eventData.element, eventData.event, this.selectedDate); 1637 if (applySelection === true) { 1638 this.setInputField(this.selectedDate != null ? this.__getSelectedDateString(this.options.datePattern) : "", eventData.event); 1639 } 1640 } 1641 } 1642 1643 return isDateChange; 1644 }, 1645 1646 __resetSelectedDate: function() { 1647 if (!this.selectedDate) return; 1648 if (this.invokeEvent("beforedateselect", null, null, null)) { 1649 this.selectedDate = null; 1650 this.invokeEvent("dateselect", null, null, null); 1651 1652 this.selectedDateCellId = this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn")); 1653 this.invokeEvent("clean", null, null, null); 1654 this.renderHF(); 1655 if (!this.options.showApplyButton) { 1656 this.setInputField("", null); 1657 this.hidePopup(); 1658 } 1659 } 1660 }, 1661 1662 showSelectedDate: function() { 1663 if (!this.selectedDate) return; 1664 if (this.currentDate.getMonth() != this.selectedDate.getMonth() || this.currentDate.getFullYear() != this.selectedDate.getFullYear()) { 1665 this.currentDate = new Date(this.selectedDate); 1666 this.currentDate.setDate(1); 1667 this.onUpdate(); 1668 } 1669 else { 1670 // highlight Selected Date 1671 if (this.isVisible && this.selectedDateCellId) { 1672 this.clearEffect(this.selectedDateCellId); 1673 if (this.selectedDateCellColor != "transparent") { 1674 $(rf.getDomElement(this.selectedDateCellId)).effect("highlight", {easing:'easeInOutSine', color: this.selectedDateCellColor}, 300); 1675 1676 } 1677 } 1678 } 1679 }, 1680 1681 close: function(updateDate) { 1682 if (updateDate) { 1683 this.setInputField(this.__getSelectedDateString(this.options.datePattern), null); 1684 } 1685 this.hidePopup(); 1686 }, 1687 1688 clonePosition: function (source, elements, offset) { 1689 var jqe = $(source); 1690 if (!elements.length) elements = [elements]; 1691 offset = offset || {left:0,top:0}; 1692 var width = jqe.outerWidth() + "px", height = jqe.outerHeight() + "px"; 1693 var pos = jqe.position(); 1694 var left = Math.floor(pos.left) + offset.left + "px", top = Math.floor(pos.top) + offset.top + "px"; 1695 var element; 1696 for (var i = 0; i < elements.length; i++) { 1697 element = elements[i]; 1698 element.style.width = width; 1699 element.style.height = height; 1700 element.style.left = left; 1701 element.style.top = top; 1702 } 1703 }, 1704 1705 showTimeEditor: function() { 1706 var editor; 1707 if (this.timeType == 0) return; 1708 if (!this.isEditorCreated) editor = this.createEditor(); 1709 else editor = rf.getDomElement(this.EDITOR_ID); 1710 if (!this.isTimeEditorLayoutCreated) this.createTimeEditorLayout(editor); 1711 1712 $(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID)).show(); 1713 1714 var editor_shadow = rf.getDomElement(this.EDITOR_SHADOW_ID); 1715 1716 this.clonePosition(rf.getDomElement(this.CALENDAR_CONTENT), [editor, editor_shadow]); 1717 1718 this.updateTimeEditor(); 1719 1720 $(editor_shadow).show(); 1721 1722 $(editor).show(); 1723 1724 this.clonePosition(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID), rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID), {left: 3, top: 3}); 1725 this.isEditorVisible = true; 1726 }, 1727 1728 hideEditor: function() { 1729 if (this.isTimeEditorLayoutCreated) $(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID)).hide(); 1730 if (this.isDateEditorLayoutCreated) $(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID)).hide(); 1731 $(rf.getDomElement(this.EDITOR_ID)).hide(); 1732 $(rf.getDomElement(this.EDITOR_SHADOW_ID)).hide(); 1733 this.isEditorVisible = false; 1734 }, 1735 1736 hideTimeEditor: function(updateTime) { 1737 this.hideEditor(); 1738 if (updateTime && this.selectedDate) { 1739 var s = this.showSeconds ? parseInt(rf.getDomElement(this.id + 'TimeSeconds').value, 10) : this.options.defaultTime.seconds; 1740 var m = parseInt(rf.getDomElement(this.id + 'TimeMinutes').value, 10); 1741 var h = parseInt(rf.getDomElement(this.id + 'TimeHours').value, 10); 1742 if (this.timeType == 2) { 1743 if (rf.getDomElement(this.id + 'TimeSign').value.toLowerCase() == "am") { 1744 if (h == 12) h = 0; 1745 } 1746 else { 1747 if (h != 12) h += 12; 1748 } 1749 } 1750 var date = rf.calendarUtils.createDate(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate(), h, m, s); 1751 if (date - this.selectedDate && this.invokeEvent("beforetimeselect", null, null, date)) { 1752 this.selectedDate = date; 1753 this.renderHF(); 1754 if (!this.options.popup || !this.options.showApplyButton) this.setInputField(this.__getSelectedDateString(this.options.datePattern), null); 1755 this.invokeEvent("timeselect", null, null, this.selectedDate); 1756 } 1757 } 1758 if (this.options.popup && !this.options.showApplyButton) this.close(false); 1759 }, 1760 1761 showDateEditor: function() { 1762 var editor; 1763 if (!this.isEditorCreated) editor = this.createEditor(); 1764 else editor = rf.getDomElement(this.EDITOR_ID); 1765 if (!this.isDateEditorLayoutCreated) this.createDateEditorLayout(editor); 1766 else this.updateDateEditor(); 1767 1768 $(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID)).show(); 1769 1770 var editor_shadow = rf.getDomElement(this.EDITOR_SHADOW_ID); 1771 1772 this.clonePosition(rf.getDomElement(this.CALENDAR_CONTENT), [editor, editor_shadow]); 1773 1774 $(editor_shadow).show(); 1775 $(editor).show(); 1776 1777 this.clonePosition(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID), rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID), {left: 3, top: 3}); 1778 1779 this.isEditorVisible = true; 1780 }, 1781 1782 hideDateEditor: function(updateCurrentDate) { 1783 this.hideEditor(); 1784 if (updateCurrentDate) { 1785 this.changeCurrentDate(this.dateEditorYear, this.dateEditorMonth); 1786 } 1787 }, 1788 1789 getValue: function() { 1790 return this.__getSelectedDate(); 1791 }, 1792 1793 getValueAsString: function(pattern) { 1794 return this.__getSelectedDateString(pattern); 1795 }, 1796 1797 setValue: function(value) { 1798 this.__selectDate(value, undefined, undefined, true); 1799 }, 1800 1801 resetValue: function() { 1802 this.__resetSelectedDate(); 1803 if (this.options.defaultLabel && !this.isFocused) { 1804 updateDefaultLabel.call(this, this.options.defaultLabel); 1805 } 1806 }, 1807 1808 getNamespace: function () { 1809 return this.namespace; 1810 } 1811 }); 1812 })(RichFaces.jQuery, RichFaces); 1813