1 /** 2 * @fileOverview This file is a source which be used to create a calendar 3 * @author <a href="mailto:support@fogtower.com">Fog Tower</a> 4 * @see <a href="http://www.fogtower.com">fogtower.com</a> 5 * @version 1.3 6 */ 7 8 /** 9 * Construct a namespace. 10 * @namespace JSCalender 11 */ 12 JSCalender = { 13 14 }; 15 16 /** 17 * Construct a new InlineCalender. 18 * @class Represents a InlineCalender. 19 * @constructor 20 * @example 21 * var myCalender = new JSCalender.InlineCalender("containerId"); 22 * @param {String} targetId The id of the Calender's input element. 23 * @param {String} onClickElementId The id of the Calender's input element. 24 * @return A new instance of a Calender. 25 */ 26 JSCalender.InlineCalender = function(id, left, top){ 27 /** 28 * The id of calender's parent node 29 * @type String 30 */ 31 this.id = id; 32 33 /** 34 * The left of calender 35 * @type Number 36 */ 37 this.left = left; 38 39 /** 40 * The top of calender 41 * @type Number 42 */ 43 this.top = top; 44 45 this._initialize(); 46 }; 47 48 /** 49 * Show calendar. 50 * @public 51 */ 52 JSCalender.InlineCalender.prototype.show = function(){ 53 this._createCalendarContainer(); 54 if(document.inlineCalendar){ 55 document.inlineCalendar = this; 56 this._addCalendarEvent(); 57 return; 58 } 59 //add event after dom was created. 60 this._addDocumentEvent(); 61 this._addCalendarEvent(); 62 this._addMonthComboboxEvent(); 63 this._addYearComboboxEvent(); 64 document.inlineCalendar = this; 65 }; 66 67 /** 68 * Initialize calendar. 69 * @private 70 */ 71 JSCalender.InlineCalender.prototype._initialize = function(){ 72 /** 73 * The id of calender's container 74 * @default "fogtower-calendar-calendarcontainer" 75 * @type String 76 */ 77 this.calendarContainerId = this.id ? this.id + "-calendarcontainer" : "fogtower-calendar-calendarcontainer"; 78 79 /** 80 * The config of calender 81 * @type Object 82 */ 83 this.config = Calender_Config; 84 85 /** 86 * The resource of calender 87 * @type Object 88 */ 89 this.resource = Calender_Resources[(this.config.language 90 || (navigator.browserLanguage?navigator.browserLanguage:navigator.language)).toLowerCase()] || Calender_Resources["en"]; 91 92 /** 93 * The first day in week 94 * @example 95 * this.firstDayInWeek = 0; 96 * The first day in week is Monday. 97 * this.firstDayInWeek = 6; 98 * The first day in week is Sunday. 99 * @type Number 100 */ 101 this.firstDayInWeek = this.config.firstDayInWeek; 102 103 /** 104 * The days' number in month 105 * @type Array 106 */ 107 this.monthDate = [31,28,31,30,31,30,31,31,30,31,30,31]; 108 109 /** 110 * Today 111 * @type Date 112 */ 113 this.thisDay = new Date(); 114 115 /** 116 * This year 117 * @type Number 118 */ 119 this.year = this.thisDay.getFullYear(); 120 121 /** 122 * This month 123 * @type Number 124 */ 125 this.month = this.thisDay.getMonth(); 126 127 }; 128 129 130 /** 131 * Get type of the browser. 132 * @namespace The browser's type 133 * @public 134 */ 135 JSCalender.InlineCalender.prototype.Browser = { 136 /** 137 * Browser is IE 138 * @public 139 * @type Boolean 140 */ 141 IE : !!(window.attachEvent && !window.opera), 142 143 /** 144 * Browser is Firefox 145 * @public 146 * @type Boolean 147 */ 148 FF : navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, 149 150 /** 151 * Browser is Opera 152 * @public 153 * @type Boolean 154 */ 155 Opera : !!window.opera, 156 157 /** 158 * Browser is WebKit 159 * @public 160 * @type Boolean 161 */ 162 WebKit : navigator.userAgent.indexOf('AppleWebKit/') > -1 163 }; 164 165 /** 166 * Create calendar's container. 167 * @private 168 */ 169 JSCalender.InlineCalender.prototype._createCalendarContainer = function(){ 170 this.calendarContainer = document.getElementById(this.calendarContainerId); 171 if(this.calendarContainer){ 172 this.calendarContainer.parentNode.removeChild(this.calendarContainer); 173 } 174 this.calendarContainer = document.createElement("div"); 175 this.calendarContainer.id = this.calendarContainerId; 176 this.calendarContainer.className = this.config.css; 177 this.calendarContainer.position = "relative"; 178 this.calendarContainer.onselectstart = function(){ 179 return false; 180 }; 181 if(this.left){ 182 this.calendarContainer.style.left = this.left + "px"; 183 } 184 if(this.top){ 185 this.calendarContainer.style.top = this.top + "px"; 186 } 187 var container = document.getElementById(this.id); 188 if(container){ 189 container.appendChild(this.calendarContainer); 190 } 191 else{ 192 document.body.appendChild(this.calendarContainer); 193 } 194 this.calendarContainer.innerHTML = this._createCalendarPanel(); 195 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 196 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 197 this._checkSlidePanel(this._getDateString(this.thisDay.getFullYear(), this.thisDay.getMonth() + 1, this.thisDay.getDate())); 198 }; 199 200 /** 201 * Create calendar's panel. 202 * @private 203 * @returns {String} Create panel of calendar. 204 */ 205 JSCalender.InlineCalender.prototype._createCalendarPanel = function(){ 206 var str = "<table class='panel' cellspacing='0' cellpadding='0'><tr><td style='height:1px;'>" 207 + "<div class='topleft'></div><div class='topright'></div><div class='monthcombobox' id='" 208 + this.calendarContainerId 209 + "-monthCombobox'>" 210 + this._createMonthCombobox() 211 + "</div><div class='yearcombobox' id='" 212 + this.calendarContainerId 213 + "-yearCombobox' >" 214 + this._createYearCombobox() 215 + "</div></td></tr><tr style='display:none;'><td>" 216 + this._createCalendarSlide() 217 + "</td></tr><tr><td>" 218 + this._createCalendarTop() 219 + "</td></tr><tr><td id='" 220 + this.calendarContainerId 221 + "-bodypanel'>" 222 + this._createCalendarBody() 223 + "</td></tr><tr><td style='height:10px;'>" 224 + this._createCalendarInfoPanel() 225 + "</td></tr><tr><td style='height:10px;'>" 226 + this._createCalendarBottom() 227 + "</td></tr></table>"; 228 return str; 229 }; 230 231 232 /** 233 * Create calendar's slide panel. 234 * @private 235 * @returns {String} Create slide panel of calendar. 236 */ 237 JSCalender.InlineCalender.prototype._createCalendarSlide = function(){ 238 var str = "<table class='slidepanel' id='" 239 + this.calendarContainerId + "-slidePanel" 240 + "'><tr><td></td><td class='slidepanel-text'></td></tr><tr><td class='slidepanel-text' colspan='2'></td></tr></table>"; 241 return str; 242 }; 243 244 /** 245 * Create calendar's top panel. 246 * @private 247 * @returns {String} Create top panel of calendar. 248 */ 249 JSCalender.InlineCalender.prototype._createCalendarTop = function(){ 250 var str = "<table class='toppanel'><tr>"; 251 var topPostionArray = this.config.topPanel; 252 for(var i = 0, len = topPostionArray.length; i < len; i++){ 253 str += "<td onmouseover='javascript:this.className=\"toppanel-hover\";' " 254 + " onmouseout='javascript:this.className=\"\";' "; 255 if(topPostionArray[i].width){ 256 str +=" style='width:" + topPostionArray[i].width + ";' "; 257 } 258 str += " id='" + this.calendarContainerId + "-" + topPostionArray[i].id 259 + "' title='" + (this.resource[topPostionArray[i].id] || "") + "' "; 260 if(topPostionArray[i].backgroundImage){ 261 str += "style='backgroundImage : " + topPostionArray[i].backgroundImage + ";' "; 262 } 263 if(topPostionArray[i].width){ 264 str += "width='" + topPostionArray[i].width + "' "; 265 } 266 if(topPostionArray[i].text){ 267 str += ">" + topPostionArray[i].text; 268 } 269 else{ 270 str += ">"; 271 } 272 str += "</td>"; 273 } 274 return str + "</tr></table>"; 275 }; 276 277 /** 278 * Create calendar's body panel. 279 * @private 280 * @returns {String} Create body panel of calendar. 281 */ 282 JSCalender.InlineCalender.prototype._createCalendarBody = function(){ 283 var str = "<table cellspacing='0' cellpadding='0' class='bodypanel'>" 284 + this._createCalendarDays() 285 + this._createCalendarDates() 286 + "</table>"; 287 return str; 288 }; 289 290 /** 291 * Create calendar's days in body panel. 292 * @private 293 * @returns {String} Create days in body panel of calendar. 294 */ 295 JSCalender.InlineCalender.prototype._createCalendarDays = function(){ 296 var weekTitle = this.resource.weekTitle; 297 var weekDays = this.resource.weekDays; 298 var firstDayInWeek = this.firstDayInWeek; 299 var arr = []; 300 if(typeof firstDayInWeek != "number" || firstDayInWeek > 6 || firstDayInWeek < 0){ 301 firstDayInWeek = 6; 302 } 303 for(var i = 0; i < 7; i++){ 304 if(i >= firstDayInWeek){ 305 arr[i - firstDayInWeek] = weekDays[i]; 306 } 307 else{ 308 arr[7- firstDayInWeek + i] = weekDays[i]; 309 } 310 } 311 var str = "<tr class='bodypanel-headrow'><td style='width:16%;' class='bodypanel-weekhead'>" + weekTitle + "</td>"; 312 for(var i = 0;i < 7; i++){ 313 str += "<td style='width:12%;' class='bodypanel-dayhead"; 314 if(arr[i] == weekDays[5] || arr[i] == weekDays[6]){ 315 str +=" bodypanel-weekendhead"; 316 } 317 str += "'>" + arr[i] + "</td>"; 318 } 319 str += "</tr>"; 320 return str; 321 }; 322 323 /** 324 * Create calendar's dates in body panel. 325 * @private 326 * @returns {String} Create dates in body panel of calendar. 327 */ 328 JSCalender.InlineCalender.prototype._createCalendarDates = function(){ 329 var firstDayInWeek = this.firstDayInWeek; 330 var preMonthDate = this._getMonthDate((this.month == 0)?11:(this.month-1)); 331 var thisMonthDate = this._getMonthDate(this.month); 332 var weekNumber = this._getYearWeek(new Date(this.year, this.month, 1)); 333 var _date = new Date(this.year, this.month, 1); 334 var weekDay = _date.getDay() - 1 - firstDayInWeek; 335 if(weekDay < 0){ 336 weekDay = weekDay + 7; 337 } 338 var str = "<tr><td class='bodypanel-week'>" 339 + weekNumber++ 340 + "</td>"; 341 342 //create last month dates 343 for(var i = 1; i < weekDay + 1; i++){ 344 var date = preMonthDate - weekDay + i; 345 var dateString = ""; 346 if(this.month == 0){ 347 dateString = this._getDateString(this.year - 1, 12, date); 348 }else{ 349 dateString = this._getDateString(this.year, this.month, date); 350 } 351 str += "<td class='bodypanel-othermonthday' date='" + dateString; 352 str += "'>" + date + "</td>"; 353 } 354 355 //create this month dates 356 var count = weekDay; 357 for(var j = 1; j < thisMonthDate + 1; j++){ 358 if(count != 0 && count%7 == 0){ 359 str += "<tr><td class='bodypanel-week'>" 360 + weekNumber++ 361 + "</td>"; 362 } 363 var _day = new Date(this.year, this.month, j).getDay(); 364 var dateString = this._getDateString(this.year, this.month+1, j); 365 str += "<td date='" + dateString + "' class='"; 366 if(_day == 0 || _day == 6){ 367 str += "bodypanel-date bodypanel-weekend"; 368 } 369 else{ 370 str += "bodypanel-date"; 371 } 372 var today = this._getDateString(this.thisDay.getFullYear(), this.thisDay.getMonth() + 1, this.thisDay.getDate()); 373 if(today == this._getDateString(this.year, this.month+1, j)){ 374 str += " bodypanel-today"; 375 } 376 if(this.config.dates[dateString] && this.config.dates[dateString].text){ 377 str += "' title='" + this.config.dates[dateString].text; 378 } 379 str += "'>" + j + "</td>"; 380 count++; 381 if(count != 0 && count%7 == 0){ 382 str += "</tr>"; 383 } 384 } 385 386 //create next month dates 387 _date = new Date(this.year, this.month + 1, 1); 388 weekDay = _date.getDay(); 389 if(((weekDay == 0)?6:weekDay - 1) != firstDayInWeek){ 390 var dayOfMonth = (firstDayInWeek >= 0)?(firstDayInWeek):6; 391 if(weekDay <= dayOfMonth){ 392 var nextMonthCount = dayOfMonth - weekDay; 393 } 394 else{ 395 var nextMonthCount = dayOfMonth + 7 - weekDay; 396 } 397 for(var n = 1; n < nextMonthCount + 2; n++){ 398 var dateString = ""; 399 if(this.month == 11){ 400 dateString = this._getDateString(this.year + 1,1, n); 401 }else{ 402 dateString = this._getDateString(this.year, this.month + 2, n); 403 } 404 str += "<td class='bodypanel-othermonthday' date='" 405 + dateString + "'>" + n + "</td>"; 406 } 407 } 408 str += "</tr>"; 409 return str; 410 }; 411 412 /** 413 * Get the number of dates by month. 414 * @param {Number} month The month. 415 * @return The number of dates. 416 */ 417 JSCalender.InlineCalender.prototype._getMonthDate = function(month){ 418 if(month == 1){ 419 return (0==this.year%4 && (this.year%100!=0 || this.year%400==0)) ? 29 : 28; 420 } 421 else{ 422 return this.monthDate[month]; 423 } 424 }; 425 426 /** 427 * Get the index of year's week by date. 428 * @param {Date} date The date. 429 * @return The index of week. 430 */ 431 JSCalender.InlineCalender.prototype._getYearWeek = function(date){ 432 var fistDay = new Date(this.year, 0, 1); 433 var d = Math.round((date.valueOf() - fistDay.valueOf()) / 86400000); 434 var weekDay = fistDay.getDay() - 1 - this.firstDayInWeek; 435 if(weekDay < 0){ 436 weekDay = weekDay + 7; 437 } 438 var value; 439 if(d==0){ 440 value = 1; 441 } 442 else{ 443 value = (d + weekDay)/7 + 1; 444 } 445 return parseInt(value, 10); 446 }; 447 448 /** 449 * Create calendar's info panel. 450 * @private 451 * @returns {String} Create info panel of calendar. 452 */ 453 JSCalender.InlineCalender.prototype._createCalendarInfoPanel = function(){ 454 return "<div class='inforpanel' id='" + this.calendarContainerId + "-info'>" 455 + this.resource.noSelected + "</div>"; 456 }; 457 458 /** 459 * Create calendar's bottom panel. 460 * @private 461 * @returns {String} Create bottom panel of calendar. 462 */ 463 JSCalender.InlineCalender.prototype._createCalendarBottom = function(){ 464 return "<div class='bottompanel'><div class='bottomleft'> </div><div class='bottomright'> </div></div>"; 465 }; 466 467 468 /** 469 * Create month combobox. 470 * @private 471 * @returns {String} Create month combobox of calendar. 472 */ 473 JSCalender.InlineCalender.prototype._createMonthCombobox = function(){ 474 var months = this.resource.monthArray; 475 var str = ""; 476 for(var i = 0; i < 12; i++){ 477 str += "<div value='" + i + "'"; 478 if(i == this.month){ 479 str += " class='monthcombobox-thismonth'"; 480 } 481 str += ">"; 482 str += months[i]; 483 str += "</div>"; 484 } 485 return str; 486 }; 487 488 /** 489 * Create year combobox. 490 * @private 491 * @returns {String} Create year combobox of calendar. 492 */ 493 JSCalender.InlineCalender.prototype._createYearCombobox = function(year){ 494 var thisYear = this.year; 495 if(typeof year == "undefined"){ 496 year = thisYear; 497 } 498 var str = "<div class='plus'>-</div>"; 499 for(var i = year - 5; i < year + 6; i++){ 500 str += "<div value='" + i + "'"; 501 if(i == thisYear){ 502 str += " class='yearcombobox-thisyear'"; 503 } 504 str += ">" + i + "</div>"; 505 } 506 str += "<div class='plus'>+</div>"; 507 return str; 508 }; 509 510 /** 511 * Add event to calendar. 512 * @private 513 */ 514 JSCalender.InlineCalender.prototype._addCalendarEvent = function(){ 515 var othis = this; 516 var preYear = document.getElementById(this.calendarContainerId + "-preYear"); 517 preYear.onclick = function(){ 518 othis._preYear(false); 519 }; 520 var nextYear = document.getElementById(this.calendarContainerId + "-nextYear"); 521 nextYear.onclick = function(){ 522 othis._nextYear(false); 523 }; 524 var preMonth = document.getElementById(this.calendarContainerId + "-preMonth"); 525 preMonth.onclick = function(){ 526 othis._preMonth(false); 527 }; 528 var nextMonth = document.getElementById(this.calendarContainerId + "-nextMonth"); 529 nextMonth.onclick = function(){ 530 othis._nextMonth(false); 531 }; 532 533 var thisMonth = document.getElementById(this.calendarContainerId + "-thisMonth"); 534 thisMonth.onclick = function(){ 535 var monthCombobox = document.getElementById(othis.calendarContainerId + "-monthCombobox"); 536 monthCombobox.innerHTML = othis._createMonthCombobox(); 537 othis._addMonthComboboxEvent(); 538 monthCombobox.style.display = "block"; 539 var thisMonth = document.getElementById(othis.calendarContainerId + "-thisMonth"); 540 monthCombobox.style.left = thisMonth.offsetLeft + "px"; 541 monthCombobox.style.top = thisMonth.offsetTop + thisMonth.offsetHeight + "px"; 542 monthCombobox.style.width = thisMonth.offsetWidth + 15 + "px"; 543 }; 544 545 var thisYear = document.getElementById(this.calendarContainerId + "-thisYear"); 546 thisYear.onclick = function(){ 547 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 548 yearCombobox.innerHTML = othis._createYearCombobox(); 549 othis._addYearComboboxEvent(); 550 yearCombobox.style.display = "block"; 551 var thisYear = document.getElementById(othis.calendarContainerId + "-thisYear"); 552 yearCombobox.style.left = thisYear.offsetLeft + "px"; 553 yearCombobox.style.top = thisYear.offsetTop + thisYear.offsetHeight + "px"; 554 yearCombobox.style.width = thisYear.offsetWidth-2 + "px"; 555 }; 556 557 var rows = document.getElementById(this.calendarContainerId + "-bodypanel").childNodes[0].rows; 558 for(var i = 1; i < rows.length; i++){ 559 var row = rows[i]; 560 row.onmouseover = function(){ 561 othis._addClass(this, "bodypanel-daterow-hover"); 562 }; 563 row.onmouseout = function(){ 564 othis._removeClass(this, "bodypanel-daterow-hover"); 565 }; 566 var cells = rows[i].cells; 567 for(var j = 1; j < cells.length; j++){ 568 var date = cells[j]; 569 var dateValue = date.getAttribute("date"); 570 if(dateValue == this.selectedDateValue || this._inDateRange(dateValue)){ 571 this._addClass(date, "bodypanel-date-select"); 572 } 573 date.onclick = function(event){ 574 var event = window.event || event; 575 if(event.shiftKey){ 576 othis.preSelectedDateValue = othis.selectedDateValue; 577 } 578 else{ 579 othis.preSelectedDateValue = ""; 580 } 581 othis._addClass(this, "bodypanel-date-select"); 582 othis.selectedDateValue = this.getAttribute("date"); 583 var month = parseInt(othis.selectedDateValue.split('-')[1],10); 584 var thisMonth = othis.month + 1; 585 if(thisMonth == 1 && month == 12){ 586 othis._preMonth(); 587 } 588 else if(thisMonth == 12 && month == 1){ 589 othis._nextMonth(); 590 } 591 else if(thisMonth > month){ 592 othis._preMonth(); 593 } 594 else if(thisMonth < month){ 595 othis._nextMonth(); 596 } 597 othis._freshDaysPanel(); 598 othis._print(othis.selectedDateValue); 599 othis._checkSlidePanel(othis.selectedDateValue); 600 }; 601 date.onmouseover = function(){ 602 othis._addClass(this, "bodypanel-date-hover"); 603 }; 604 date.onmouseout = function(){ 605 othis._removeClass(this, "bodypanel-date-hover"); 606 }; 607 } 608 } 609 }; 610 611 /** 612 * Add event to window.document. 613 * @private 614 */ 615 JSCalender.InlineCalender.prototype._addDocumentEvent = function(){ 616 if(document.addEventListener){ 617 document.addEventListener("keypress",this._keyEvent,false); 618 document.addEventListener("mousedown",this._clickCheck,false); 619 } 620 else{ 621 document.attachEvent("onkeydown",this._keyEvent); 622 document.attachEvent("onmousedown",this._clickCheck); 623 } 624 }; 625 626 /** 627 * Hide calendar or combobox when clicked 628 * @private 629 */ 630 JSCalender.InlineCalender.prototype._clickCheck = function(event){ 631 var calendar = document.inlineCalendar; 632 if (!calendar) { 633 return; 634 } 635 event = window.event || event; 636 var element = event.srcElement || event.target; 637 var calendarDom = document.getElementById(calendar.calendarContainerId); 638 var monthCombobox = document.getElementById(calendar.calendarContainerId + "-monthCombobox"); 639 var yearCombobox = document.getElementById(calendar.calendarContainerId + "-yearCombobox"); 640 for (; element != null && element != calendarDom; element = element.parentNode); 641 if (element == null) { 642 monthCombobox.style.display = "none"; 643 yearCombobox.style.display = "none"; 644 calendar.focus = false; 645 return; 646 } 647 else{ 648 calendar.focus = true; 649 } 650 element = event.srcElement || event.target; 651 for (; element != null && element != monthCombobox; element = element.parentNode); 652 if (element == null) { 653 monthCombobox.style.display = "none"; 654 } 655 element = event.srcElement || event.target; 656 for (; element != null && element != yearCombobox; element = element.parentNode); 657 if (element == null) { 658 yearCombobox.style.display = "none"; 659 } 660 }; 661 662 /** 663 * Check data to decide that whether show the slide panel 664 * @param {String} date The date. 665 * @private 666 */ 667 JSCalender.InlineCalender.prototype._checkSlidePanel = function(date){ 668 var dateInfo = this.config.dates[date]; 669 var defaultInfo = this.config.dates["default"]; 670 var slidePanelContainer = document.getElementById(this.calendarContainerId + "-slidePanel").parentNode.parentNode; 671 if(dateInfo){ 672 this._showSlidePanel(dateInfo.image, dateInfo.text, date); 673 slidePanelContainer.style.display = ""; 674 } 675 else if(defaultInfo){ 676 this._showSlidePanel(defaultInfo.image, defaultInfo.text, date); 677 slidePanelContainer.style.display = ""; 678 } 679 else{ 680 slidePanelContainer.style.display = "none"; 681 } 682 }; 683 684 /** 685 * Process key event when press keyboard 686 * @param {Object} event The event which comes from pressing keyboard. 687 * @private 688 */ 689 JSCalender.InlineCalender.prototype._keyEvent = function(event){ 690 var othis = document.inlineCalendar; 691 if(!othis.focus){ 692 return; 693 } 694 var KEY = { 695 LEFT : 37, 696 UP : 38, 697 RIGHT : 39, 698 DOWN : 40, 699 ESC : 27, 700 ENTER : 13, 701 SPACE : 32 702 }; 703 var code = event.keyCode || event.charCode; 704 if(event.ctrlKey){ 705 switch(code) 706 { 707 case KEY.LEFT: 708 othis._preMonth(); 709 break; 710 case KEY.RIGHT: 711 othis._nextMonth(); 712 break; 713 case KEY.UP: 714 othis._preYear(); 715 break; 716 case KEY.DOWN: 717 othis._nextYear(); 718 break; 719 default: 720 break; 721 } 722 } 723 else{ 724 switch(code){ 725 case KEY.LEFT: 726 othis._parseDate(1); 727 othis._print(othis.selectedDateValue); 728 break; 729 case KEY.RIGHT: 730 othis._parseDate(-1); 731 othis._print(othis.selectedDateValue); 732 break; 733 case KEY.UP: 734 othis._parseDate(7); 735 othis._print(othis.selectedDateValue); 736 break; 737 case KEY.DOWN: 738 othis._parseDate(-7); 739 othis._print(othis.selectedDateValue); 740 break; 741 case KEY.ESC: 742 othis._unfocus(); 743 break; 744 case KEY.ENTER: 745 othis._print(othis.selectedDateValue); 746 break; 747 case KEY.SPACE: 748 othis.selectedDateValue = othis._getDateString(othis.thisDay.getFullYear(),othis.thisDay.getMonth()+1,othis.thisDay.getDate()); 749 othis.year = othis.thisDay.getFullYear(); 750 othis.month = othis.thisDay.getMonth(); 751 document.getElementById(othis.calendarContainerId + "-thisYear").innerHTML = othis.year; 752 document.getElementById(othis.calendarContainerId + "-thisMonth").innerHTML = othis.resource.monthArray[othis.month]; 753 othis._freshDaysPanel(); 754 othis._print(othis.selectedDateValue); 755 break; 756 default: 757 break; 758 } 759 } 760 othis._checkSlidePanel(othis.selectedDateValue); 761 if(event.preventDefault){ 762 event.preventDefault(); 763 } 764 else{ 765 return false; 766 } 767 }; 768 769 /** 770 * Get last year's calendar 771 * @private 772 */ 773 JSCalender.InlineCalender.prototype._preYear = function(){ 774 this.year--; 775 this._freshDaysPanel(); 776 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 777 }; 778 779 /** 780 * Get next year's calendar 781 * @private 782 */ 783 JSCalender.InlineCalender.prototype._nextYear = function(){ 784 this.year++; 785 this._freshDaysPanel(); 786 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 787 }; 788 789 /** 790 * Get last month's calendar 791 * @private 792 */ 793 JSCalender.InlineCalender.prototype._preMonth = function(){ 794 if(this.month == 0){ 795 this.month = 11; 796 this.year--; 797 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 798 } 799 else{ 800 this.month--; 801 } 802 this._freshDaysPanel(); 803 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 804 }; 805 806 /** 807 * Get next month's calendar 808 * @private 809 */ 810 JSCalender.InlineCalender.prototype._nextMonth = function(){ 811 if(this.month == 11){ 812 this.month = 0; 813 this.year++; 814 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 815 } 816 else{ 817 this.month++; 818 } 819 this._freshDaysPanel(); 820 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 821 }; 822 823 /** 824 * Fresh calendar when press keyboard 825 * @param {Number} step The diff which compares with the selected date. 826 * @private 827 */ 828 JSCalender.InlineCalender.prototype._parseDate = function(step){ 829 if(this.selectedDateValue){ 830 var arr = this.selectedDateValue.split('-'); 831 var date = new Date(new Date(arr[0],arr[1]-1,arr[2]) - 24*60*60*1000*step); 832 } 833 else{ 834 var date = new Date(this.thisDay - 24*60*60*1000*step); 835 } 836 this.year = date.getFullYear(); 837 this.month = date.getMonth(); 838 this.date = date.getDate(); 839 this.selectedDateValue = this._getDateString(this.year,this.month + 1,this.date); 840 this._freshDaysPanel(); 841 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 842 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 843 }; 844 845 /** 846 * Convert Date to string 847 * @param {Number} year The year. 848 * @param {Number} month The month. 849 * @param {Date} date The date. 850 * @private 851 */ 852 JSCalender.InlineCalender.prototype._getDateString = function(year,month,date){ 853 return year + "-" + ((month < 10)?("0" + (month)):month) + "-" + ((date < 10)?("0" + (date)):date); 854 }; 855 856 857 /** 858 * Fresh calendar 859 * @private 860 */ 861 JSCalender.InlineCalender.prototype._freshDaysPanel = function(){ 862 var str = "<table cellspacing='0' cellpadding='0' class='bodypanel'>" 863 + this._createCalendarDays() + this._createCalendarDates() 864 + "</table>"; 865 document.getElementById(this.calendarContainerId + "-bodypanel").innerHTML = str; 866 this._addCalendarEvent(); 867 }; 868 869 /** 870 * Show slide panel 871 * @private 872 */ 873 JSCalender.InlineCalender.prototype._showSlidePanel = function(img, text, dateString){ 874 var slidePanel = document.getElementById(this.calendarContainerId + "-slidePanel"); 875 var imageContainer = slidePanel.rows[0].cells[0]; 876 var topTextContainer = slidePanel.rows[0].cells[1]; 877 var bottomTextContainer = slidePanel.rows[1].cells[0]; 878 if(img){ 879 imageContainer.style.display = ""; 880 imageContainer.innerHTML = "<img class='slidepanel-img' alt='" 881 + dateString + "' src='" + img + "'/>"; 882 } 883 else{ 884 imageContainer.style.display = "none"; 885 } 886 if(text){ 887 var textArr = text.split('\n'); 888 889 if(textArr.length < 2){ 890 topTextContainer.style.display = ""; 891 bottomTextContainer.style.display = "none"; 892 topTextContainer.innerHTML = textArr[0]; 893 } 894 else{ 895 topTextContainer.style.display = ""; 896 bottomTextContainer.style.display = ""; 897 topTextContainer.innerHTML = textArr[0]; 898 textArr[0] = ""; 899 bottomTextContainer.innerHTML = textArr.join(" "); 900 } 901 } 902 else{ 903 topTextContainer.style.display = "none"; 904 bottomTextContainer.style.display = "none"; 905 } 906 }; 907 908 /** 909 * Add event to month combobox 910 * @private 911 */ 912 JSCalender.InlineCalender.prototype._addMonthComboboxEvent = function(){ 913 var othis = this; 914 var monthCombobox = document.getElementById(this.calendarContainerId + "-monthCombobox"); 915 for(var i = 0, len = monthCombobox.childNodes.length; i < len; i++){ 916 var row = monthCombobox.childNodes[i]; 917 row.onclick = function(){ 918 document.getElementById(othis.calendarContainerId + "-thisMonth").innerHTML = this.innerHTML; 919 monthCombobox.style.display = "none"; 920 othis.month = parseInt(this.getAttribute("value"),10); 921 othis._freshDaysPanel(); 922 }; 923 row.onmouseover = function(){ 924 othis._addClass(this, "monthcombobox-hover"); 925 }; 926 row.onmouseout = function(){ 927 othis._removeClass(this, "monthcombobox-hover"); 928 }; 929 } 930 }; 931 932 /** 933 * Add event to year combobox 934 * @private 935 */ 936 JSCalender.InlineCalender.prototype._addYearComboboxEvent = function(){ 937 var othis = this; 938 var yearCombobox = document.getElementById(this.calendarContainerId + "-yearCombobox"); 939 940 for(var i = 0, len = yearCombobox.childNodes.length; i < len; i++){ 941 var row = yearCombobox.childNodes[i]; 942 if(i == 0){ 943 row.onclick = function(){ 944 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 945 yearCombobox.innerHTML = othis._createYearCombobox(parseInt(yearCombobox.childNodes[5].innerHTML,10)); 946 othis._addYearComboboxEvent(); 947 }; 948 } 949 else if(i == len - 1){ 950 row.onclick = function(){ 951 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 952 yearCombobox.innerHTML = othis._createYearCombobox(parseInt(yearCombobox.childNodes[5].innerHTML,10) + 2); 953 othis._addYearComboboxEvent(); 954 }; 955 } 956 else{ 957 row.onclick = function(){ 958 document.getElementById(othis.calendarContainerId + "-thisYear").innerHTML = this.innerHTML; 959 yearCombobox.style.display = "none"; 960 othis.year = parseInt(this.getAttribute("value"),10); 961 othis._freshDaysPanel(); 962 }; 963 } 964 row.onmouseover = function(){ 965 othis._addClass(this, "yearcombobox-hover"); 966 }; 967 row.onmouseout = function(){ 968 othis._removeClass(this, "yearcombobox-hover"); 969 }; 970 } 971 }; 972 973 /** 974 * Add css class to element. 975 * @param {Object} el The element where adds class. 976 * @param {String} className The css class which to be added.. 977 * @private 978 */ 979 JSCalender.InlineCalender.prototype._addClass = function(el, className) { 980 this._removeClass(el, className); 981 el.className += " " + className; 982 }; 983 984 /** 985 * Remove css class of element. 986 * @param {Object} el The element where removes class. 987 * @param {String} className The css class which to be removed. 988 * @private 989 */ 990 JSCalender.InlineCalender.prototype._removeClass = function(el, className) { 991 if (!(el && el.className)) { 992 return; 993 } 994 var cssArr = el.className.split(" "); 995 var newArr = new Array(); 996 for (var i = 0, len = cssArr.length; i< len; i++){ 997 if (cssArr[i] != className) { 998 newArr[newArr.length] = cssArr[i]; 999 } 1000 } 1001 el.className = newArr.join(" "); 1002 }; 1003 1004 /** 1005 * Judge the date is in date range or not. 1006 * @param {String} dataString The date which to be judged. 1007 * @returns {Boolean} in date range or not. 1008 * @private 1009 */ 1010 JSCalender.InlineCalender.prototype._inDateRange = function(dataString) { 1011 if(!this.selectedDateValue || !this.preSelectedDateValue){ 1012 return false; 1013 } 1014 if(this.selectedDateValue > this.preSelectedDateValue){ 1015 var earlyDate = this.preSelectedDateValue; 1016 var oldDate = this.selectedDateValue; 1017 } 1018 else{ 1019 var earlyDate = this.selectedDateValue; 1020 var oldDate = this.preSelectedDateValue; 1021 } 1022 if(dataString >= earlyDate && dataString <= oldDate){ 1023 return true; 1024 } 1025 return false; 1026 1027 }; 1028 1029 /** 1030 * Output the selected date 1031 * @param {String} dateString The format of outputed date 1032 * @private 1033 */ 1034 JSCalender.InlineCalender.prototype._print = function(dateString) { 1035 if(!dateString){ 1036 return; 1037 } 1038 var arr = dateString.split('-'); 1039 var printFormat = (this.config.printFormat || "").toLowerCase(); 1040 printFormat = printFormat.replace("yyyy", arr[0]); 1041 printFormat = printFormat.replace("yy", arr[0].substr(2)); 1042 printFormat = printFormat.replace("mm", arr[1]); 1043 printFormat = printFormat.replace("dd", arr[2]); 1044 var bottom = document.getElementById(this.calendarContainerId + "-info"); 1045 var number = this._getSelectedDatesNumber(); 1046 if(number > 1){ 1047 bottom.innerHTML = number + this.resource.selectedDates; 1048 } 1049 else{ 1050 bottom.innerHTML = this.resource.selectedSingleDate + printFormat; 1051 } 1052 }; 1053 1054 /** 1055 * Get the number of selected dates 1056 * @returns {Number} The number of selected dates 1057 * @private 1058 */ 1059 JSCalender.InlineCalender.prototype._getSelectedDatesNumber = function() { 1060 if(!this.selectedDateValue || !this.preSelectedDateValue){ 1061 return 0; 1062 } 1063 if(this.selectedDateValue > this.preSelectedDateValue){ 1064 var currentArr = this.selectedDateValue.split('-'); 1065 var preArr = this.preSelectedDateValue.split('-'); 1066 } 1067 else{ 1068 var currentArr = this.preSelectedDateValue.split('-'); 1069 var preArr = this.selectedDateValue.split('-'); 1070 } 1071 var cuurentSelectedDate = new Date(currentArr[0], currentArr[1], currentArr[2]); 1072 var preSelectedDate = new Date(preArr[0], preArr[1], preArr[2]); 1073 var number = Math.round((cuurentSelectedDate.valueOf() - preSelectedDate.valueOf()) / 86400000) + 1; 1074 return number; 1075 }; 1076 1077 /** 1078 * Set the config of calendar 1079 * @param {String} config The config which to be set 1080 * @public 1081 */ 1082 JSCalender.InlineCalender.prototype.setConfig = function(config) { 1083 this.config = config; 1084 }; 1085 1086 /** 1087 * Set the language of calendar 1088 * @param {String} lang The language which to be set 1089 * @public 1090 */ 1091 JSCalender.InlineCalender.prototype.setLanguage = function(lang) { 1092 this.resource = Calender_Resources[lang.toLowerCase()]|| Calender_Resources["en"]; 1093 }; 1094 1095 /** 1096 * Set the css of calendar 1097 * @param {String} css The css which to be set 1098 * @public 1099 */ 1100 JSCalender.InlineCalender.prototype.setCss = function(css) { 1101 this.config.css = css; 1102 }; 1103 1104 /** 1105 * Set the first day in week 1106 * @param {Number} day The day which to be set 1107 * @public 1108 */ 1109 JSCalender.InlineCalender.prototype.setFirstDayInWeek = function(day) { 1110 this.firstDayInWeek = day; 1111 }; 1112 1113 /** 1114 * Set the export format 1115 * @param {String} date The date which to be set 1116 * @param {String} image The image which to be show in slide panel 1117 * @param {String} text The text which to be show in slide panel 1118 * @public 1119 */ 1120 JSCalender.InlineCalender.prototype.setSlideDate = function(date, image, text) { 1121 this.config.dates[date] = {}; 1122 this.config.dates[date].text = text; 1123 this.config.dates[date].image = image; 1124 }; 1125 1126 /** 1127 * Construct a new PopCalender. 1128 * @class Represents a PopCalender. 1129 * @constructor 1130 * @example 1131 * var myCalender = new JSCalender.PopCalender("inputId", "buttonId"); 1132 * @param {String} targetId The id of the Calender's input element. 1133 * @param {String} onClickElementId The id of the Calender's input element. 1134 * @return A new instance of a Calender. 1135 */ 1136 JSCalender.PopCalender = function(targetId, onClickElementId){ 1137 /** 1138 * The id of input element where calender outputs 1139 * @type String 1140 */ 1141 this.targetId = targetId; 1142 1143 /** 1144 * The id of the element which be clicked to show calender 1145 * @type String 1146 */ 1147 this.onClickElementId = onClickElementId; 1148 1149 this._initialize(); 1150 }; 1151 1152 /** 1153 * Show the calendar. 1154 * @public 1155 */ 1156 JSCalender.PopCalender.prototype.show = function(){ 1157 if(document.popCalendar){ 1158 if(document.popCalendar.calendarContainerId == this.calendarContainerId){ 1159 this._show(); 1160 return; 1161 } 1162 else{ 1163 this._remove(); 1164 } 1165 } 1166 this._createCalendarContainer(); 1167 1168 //add event after dom was created. 1169 this._addDocumentEvent(); 1170 this._addCalendarEvent(); 1171 this._addMonthComboboxEvent(); 1172 this._addYearComboboxEvent(); 1173 document.popCalendar = this; 1174 }; 1175 1176 /** 1177 * Initialize calendar. 1178 * @private 1179 */ 1180 JSCalender.PopCalender.prototype._initialize = function(){ 1181 /** 1182 * The id of calender's container 1183 * @default "fogtower-calendar-calendarcontainer" 1184 * @type String 1185 */ 1186 this.calendarContainerId = this.targetId ? this.targetId + "-calendarcontainer" : "fogtower-calendar-calendarcontainer"; 1187 1188 /** 1189 * The config of calender 1190 * @type Object 1191 */ 1192 this.config = Calender_Config; 1193 1194 /** 1195 * The resource of calender 1196 * @type Object 1197 */ 1198 this.resource = Calender_Resources[(this.config.language 1199 || (navigator.browserLanguage?navigator.browserLanguage:navigator.language)).toLowerCase()] || Calender_Resources["en"]; 1200 1201 /** 1202 * The first day in week 1203 * @example 1204 * this.firstDayInWeek = 0; 1205 * The first day in week is Monday. 1206 * this.firstDayInWeek = 6; 1207 * The first day in week is Sunday. 1208 * @type Number 1209 */ 1210 this.firstDayInWeek = this.config.firstDayInWeek; 1211 1212 /** 1213 * The days' number in month 1214 * @type Array 1215 */ 1216 this.monthDate = [31,28,31,30,31,30,31,31,30,31,30,31]; 1217 1218 /** 1219 * Today 1220 * @type Date 1221 */ 1222 this.thisDay = new Date(); 1223 1224 /** 1225 * This year 1226 * @type Number 1227 */ 1228 this.year = this.thisDay.getFullYear(); 1229 1230 /** 1231 * This month 1232 * @type Number 1233 */ 1234 this.month = this.thisDay.getMonth(); 1235 }; 1236 1237 1238 /** 1239 * Get type of the browser. 1240 * @namespace The browser's type 1241 * @public 1242 */ 1243 JSCalender.PopCalender.prototype.Browser = { 1244 /** 1245 * Browser is IE 1246 * @public 1247 * @type Boolean 1248 */ 1249 IE : !!(window.attachEvent && !window.opera), 1250 1251 /** 1252 * Browser is Firefox 1253 * @public 1254 * @type Boolean 1255 */ 1256 FF : navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, 1257 1258 /** 1259 * Browser is Opera 1260 * @public 1261 * @type Boolean 1262 */ 1263 Opera : !!window.opera, 1264 1265 /** 1266 * Browser is WebKit 1267 * @public 1268 * @type Boolean 1269 */ 1270 WebKit : navigator.userAgent.indexOf('AppleWebKit/') > -1 1271 }; 1272 1273 1274 1275 /** 1276 * Create calendar's container. 1277 * @private 1278 */ 1279 JSCalender.PopCalender.prototype._createCalendarContainer = function(){ 1280 this.calendarContainer = document.getElementById(this.calendarContainerId); 1281 if(this.calendarContainer){ 1282 this.calendarContainer.parentNode.removeChild(this.calendarContainer); 1283 } 1284 var pos = this._getPosition(document.getElementById(this.onClickElementId)); 1285 this.top = pos.top; 1286 this.left = pos.left; 1287 this.calendarContainer = document.createElement("div"); 1288 this.calendarContainer.id = this.calendarContainerId; 1289 this.calendarContainer.className = this.config.css; 1290 this.calendarContainer.style.left = this.left + "px"; 1291 this.calendarContainer.style.top = this.top + "px"; 1292 document.body.appendChild(this.calendarContainer); 1293 this.calendarContainer.innerHTML = this._createCalendarPanel(); 1294 if(this.Browser.IE){ 1295 document.body.appendChild(this._createIframeShim()); 1296 } 1297 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1298 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 1299 this._checkSlidePanel(this._getDateString(this.thisDay.getFullYear(), this.thisDay.getMonth() + 1, this.thisDay.getDate())); 1300 }; 1301 1302 /** 1303 * Create a iframe to fix the combobox's bug of IE6. 1304 * @returns {Object} The created iframe. 1305 * @private 1306 */ 1307 JSCalender.PopCalender.prototype._createIframeShim = function(){ 1308 var iframe = document.getElementById(this.calendarContainerId + "-iframeshim"); 1309 if(iframe){ 1310 iframe.parentNode.removeChild(iframe); 1311 } 1312 iframe = document.createElement("iframe"); 1313 iframe.id = this.calendarContainerId + "-iframeshim"; 1314 iframe.className = this.config.css + "-iframeshim"; 1315 iframe.scrolling = "no"; 1316 iframe.frameBorder = "0"; 1317 iframe.style.position = "absolute"; 1318 iframe.style.left = this.left + "px"; 1319 iframe.style.top = this.top + "px"; 1320 iframe.style.width = this.calendarContainer.offsetWidth + "px"; 1321 iframe.style.height = this.calendarContainer.offsetHeight + "px"; 1322 return iframe; 1323 }; 1324 1325 /** 1326 * Create calendar's panel. 1327 * @private 1328 * @returns {String} Create panel of calendar. 1329 */ 1330 JSCalender.PopCalender.prototype._createCalendarPanel = function(){ 1331 var str = "<table class='panel' cellspacing='0' cellpadding='0'><tr><td style='height:1px;'>" 1332 + "<div class='topleft'></div><div class='topright'></div><div class='monthcombobox' id='" 1333 + this.calendarContainerId 1334 + "-monthCombobox'>" 1335 + this._createMonthCombobox() 1336 + "</div><div class='yearcombobox' id='" 1337 + this.calendarContainerId 1338 + "-yearCombobox' >" 1339 + this._createYearCombobox() 1340 + "</div></td></tr><tr style='display:none;'><td>" 1341 + this._createCalendarSlide() 1342 + "</td></tr><tr><td>" 1343 + this._createCalendarTop() 1344 + "</td></tr><tr><td id='" 1345 + this.calendarContainerId 1346 + "-bodypanel'>" 1347 + this._createCalendarBody() 1348 + "</td></tr><tr><td style='height:10px;'>" 1349 + this._createCalendarBottom() 1350 + "</td></tr></table>"; 1351 return str; 1352 }; 1353 1354 1355 /** 1356 * Create calendar's slide panel. 1357 * @private 1358 * @returns {String} Create slide panel of calendar. 1359 */ 1360 JSCalender.PopCalender.prototype._createCalendarSlide = function(){ 1361 var str = "<table class='slidepanel' id='" 1362 + this.calendarContainerId + "-slidePanel" 1363 + "'><tr><td></td><td class='slidepanel-text'></td></tr><tr><td class='slidepanel-text' colspan='2'></td></tr></table>"; 1364 return str; 1365 }; 1366 1367 /** 1368 * Create calendar's top panel. 1369 * @private 1370 * @returns {String} Create top panel of calendar. 1371 */ 1372 JSCalender.PopCalender.prototype._createCalendarTop = function(){ 1373 var str = "<table class='toppanel'><tr>"; 1374 var topPostionArray = this.config.topPanel; 1375 for(var i = 0, len = topPostionArray.length; i < len; i++){ 1376 str += "<td onmouseover='javascript:this.className=\"toppanel-hover\";' " 1377 + " onmouseout='javascript:this.className=\"\";' "; 1378 if(topPostionArray[i].width){ 1379 str +=" style='width:" + topPostionArray[i].width + ";' "; 1380 } 1381 str += " id='" + this.calendarContainerId + "-" + topPostionArray[i].id 1382 + "' title='" + (this.resource[topPostionArray[i].id] || "") + "' "; 1383 if(topPostionArray[i].backgroundImage){ 1384 str += "style='backgroundImage : " + topPostionArray[i].backgroundImage + ";' "; 1385 } 1386 if(topPostionArray[i].width){ 1387 str += "width='" + topPostionArray[i].width + "' "; 1388 } 1389 if(topPostionArray[i].text){ 1390 str += ">" + topPostionArray[i].text; 1391 } 1392 else{ 1393 str += ">"; 1394 } 1395 str += "</td>"; 1396 } 1397 return str + "</tr></table>"; 1398 }; 1399 1400 /** 1401 * Create calendar's body panel. 1402 * @private 1403 * @returns {String} Create body panel of calendar. 1404 */ 1405 JSCalender.PopCalender.prototype._createCalendarBody = function(){ 1406 var str = "<table cellspacing='0' cellpadding='0' class='bodypanel'>" 1407 + this._createCalendarDays() 1408 + this._createCalendarDates() 1409 + "</table>"; 1410 return str; 1411 }; 1412 1413 /** 1414 * Create calendar's days in body panel. 1415 * @private 1416 * @returns {String} Create days in body panel of calendar. 1417 */ 1418 JSCalender.PopCalender.prototype._createCalendarDays = function(){ 1419 var weekTitle = this.resource.weekTitle; 1420 var weekDays = this.resource.weekDays; 1421 var firstDayInWeek = this.firstDayInWeek; 1422 var arr = []; 1423 if(typeof firstDayInWeek != "number" || firstDayInWeek > 6 || firstDayInWeek < 0){ 1424 firstDayInWeek = 6; 1425 } 1426 for(var i = 0; i < 7; i++){ 1427 if(i >= firstDayInWeek){ 1428 arr[i - firstDayInWeek] = weekDays[i]; 1429 } 1430 else{ 1431 arr[7- firstDayInWeek + i] = weekDays[i]; 1432 } 1433 } 1434 var str = "<tr class='bodypanel-headrow'><td style='width:16%;' class='bodypanel-weekhead'>" + weekTitle + "</td>"; 1435 for(var i = 0;i < 7; i++){ 1436 str += "<td style='width:12%;' class='bodypanel-dayhead"; 1437 if(arr[i] == weekDays[5] || arr[i] == weekDays[6]){ 1438 str +=" bodypanel-weekendhead"; 1439 } 1440 str += "'>" + arr[i] + "</td>"; 1441 } 1442 str += "</tr>"; 1443 return str; 1444 }; 1445 1446 /** 1447 * Create calendar's dates in body panel. 1448 * @private 1449 * @returns {String} Create dates in body panel of calendar. 1450 */ 1451 JSCalender.PopCalender.prototype._createCalendarDates = function(){ 1452 var firstDayInWeek = this.firstDayInWeek; 1453 var preMonthDate = this._getMonthDate((this.month == 0)?11:(this.month-1)); 1454 var thisMonthDate = this._getMonthDate(this.month); 1455 var weekNumber = this._getYearWeek(new Date(this.year, this.month, 1)); 1456 var _date = new Date(this.year, this.month, 1); 1457 var weekDay = _date.getDay() - 1 - firstDayInWeek; 1458 if(weekDay < 0){ 1459 weekDay = weekDay + 7; 1460 } 1461 var str = "<tr><td class='bodypanel-week'>" 1462 + weekNumber++ 1463 + "</td>"; 1464 1465 //create last month dates 1466 for(var i = 1; i < weekDay + 1; i++){ 1467 var date = preMonthDate - weekDay + i; 1468 var dateString = ""; 1469 if(this.month == 0){ 1470 dateString = this._getDateString(this.year - 1, 12, date); 1471 }else{ 1472 dateString = this._getDateString(this.year, this.month, date); 1473 } 1474 str += "<td class='bodypanel-othermonthday' date='" + dateString; 1475 str += "'>" + date + "</td>"; 1476 } 1477 1478 //create this month dates 1479 var count = weekDay; 1480 for(var j = 1; j < thisMonthDate + 1; j++){ 1481 if(count != 0 && count%7 == 0){ 1482 str += "<tr><td class='bodypanel-week'>" 1483 + weekNumber++ 1484 + "</td>"; 1485 } 1486 var _day = new Date(this.year, this.month, j).getDay(); 1487 var dateString = this._getDateString(this.year, this.month+1, j); 1488 str += "<td date='" + dateString + "' class='"; 1489 if(_day == 0 || _day == 6){ 1490 str += "bodypanel-date bodypanel-weekend"; 1491 } 1492 else{ 1493 str += "bodypanel-date"; 1494 } 1495 var today = this._getDateString(this.thisDay.getFullYear(), this.thisDay.getMonth() + 1, this.thisDay.getDate()); 1496 if(today == this._getDateString(this.year, this.month+1, j)){ 1497 str += " bodypanel-today"; 1498 } 1499 if(this.config.dates[dateString] && this.config.dates[dateString].text){ 1500 str += "' title='" + this.config.dates[dateString].text; 1501 } 1502 str += "'>" + j + "</td>"; 1503 count++; 1504 if(count != 0 && count%7 == 0){ 1505 str += "</tr>"; 1506 } 1507 } 1508 1509 //create next month dates 1510 _date = new Date(this.year, this.month + 1, 1); 1511 weekDay = _date.getDay(); 1512 if(((weekDay == 0)?6:weekDay - 1) != firstDayInWeek){ 1513 var dayOfMonth = (firstDayInWeek >= 0)?(firstDayInWeek):6; 1514 if(weekDay <= dayOfMonth){ 1515 var nextMonthCount = dayOfMonth - weekDay; 1516 } 1517 else{ 1518 var nextMonthCount = dayOfMonth + 7 - weekDay; 1519 } 1520 for(var n = 1; n < nextMonthCount + 2; n++){ 1521 var dateString = ""; 1522 if(this.month == 11){ 1523 dateString = this._getDateString(this.year + 1,1, n); 1524 }else{ 1525 dateString = this._getDateString(this.year, this.month + 2, n); 1526 } 1527 str += "<td class='bodypanel-othermonthday' date='" 1528 + dateString + "'>" + n + "</td>"; 1529 } 1530 } 1531 str += "</tr>"; 1532 return str; 1533 }; 1534 1535 /** 1536 * Get the number of dates by month. 1537 * @param {Number} month The month. 1538 * @return The number of dates. 1539 */ 1540 JSCalender.PopCalender.prototype._getMonthDate = function(month){ 1541 if(month == 1){ 1542 return (0==this.year%4 && (this.year%100!=0 || this.year%400==0)) ? 29 : 28; 1543 } 1544 else{ 1545 return this.monthDate[month]; 1546 } 1547 }; 1548 1549 /** 1550 * Get the index of year's week by date. 1551 * @param {Date} date The date. 1552 * @return The index of week. 1553 */ 1554 JSCalender.PopCalender.prototype._getYearWeek = function(date){ 1555 var fistDay = new Date(this.year, 0, 1); 1556 var d = Math.round((date.valueOf() - fistDay.valueOf()) / 86400000); 1557 var weekDay = fistDay.getDay() - 1 - this.firstDayInWeek; 1558 if(weekDay < 0){ 1559 weekDay = weekDay + 7; 1560 } 1561 var value; 1562 if(d==0){ 1563 value = 1; 1564 } 1565 else{ 1566 value = (d + weekDay)/7 + 1; 1567 } 1568 return parseInt(value, 10); 1569 }; 1570 1571 /** 1572 * Create calendar's bottom panel. 1573 * @private 1574 * @returns {String} Create bottom panel of calendar. 1575 */ 1576 JSCalender.PopCalender.prototype._createCalendarBottom = function(){ 1577 return "<div class='bottompanel'><div class='bottomleft'> </div><div class='bottomright'> </div></div>"; 1578 }; 1579 1580 /** 1581 * Create month combobox. 1582 * @private 1583 * @returns {String} Create month combobox of calendar. 1584 */ 1585 JSCalender.PopCalender.prototype._createMonthCombobox = function(){ 1586 var months = this.resource.monthArray; 1587 var str = ""; 1588 for(var i = 0; i < 12; i++){ 1589 str += "<div value='" + i + "'"; 1590 if(i == this.month){ 1591 str += " class='monthcombobox-thismonth'"; 1592 } 1593 str += ">"; 1594 str += months[i]; 1595 str += "</div>"; 1596 } 1597 return str; 1598 }; 1599 1600 /** 1601 * Create year combobox. 1602 * @private 1603 * @returns {String} Create year combobox of calendar. 1604 */ 1605 JSCalender.PopCalender.prototype._createYearCombobox = function(year){ 1606 var thisYear = this.year; 1607 if(typeof year == "undefined"){ 1608 year = thisYear; 1609 } 1610 var str = "<div class='plus'>-</div>"; 1611 for(var i = year - 5; i < year + 6; i++){ 1612 str += "<div value='" + i + "'"; 1613 if(i == thisYear){ 1614 str += " class='yearcombobox-thisyear'"; 1615 } 1616 str += ">" + i + "</div>"; 1617 } 1618 str += "<div class='plus'>+</div>"; 1619 return str; 1620 }; 1621 1622 /** 1623 * Add event to calendar. 1624 * @private 1625 */ 1626 JSCalender.PopCalender.prototype._addCalendarEvent = function(){ 1627 var othis = this; 1628 var preYear = document.getElementById(this.calendarContainerId + "-preYear"); 1629 preYear.onclick = function(){ 1630 othis._preYear(false); 1631 }; 1632 var nextYear = document.getElementById(this.calendarContainerId + "-nextYear"); 1633 nextYear.onclick = function(){ 1634 othis._nextYear(false); 1635 }; 1636 var preMonth = document.getElementById(this.calendarContainerId + "-preMonth"); 1637 preMonth.onclick = function(){ 1638 othis._preMonth(false); 1639 }; 1640 var nextMonth = document.getElementById(this.calendarContainerId + "-nextMonth"); 1641 nextMonth.onclick = function(){ 1642 othis._nextMonth(false); 1643 }; 1644 1645 var thisMonth = document.getElementById(this.calendarContainerId + "-thisMonth"); 1646 thisMonth.onclick = function(){ 1647 var monthCombobox = document.getElementById(othis.calendarContainerId + "-monthCombobox"); 1648 monthCombobox.innerHTML = othis._createMonthCombobox(); 1649 othis._addMonthComboboxEvent(); 1650 monthCombobox.style.display = "block"; 1651 var thisMonth = document.getElementById(othis.calendarContainerId + "-thisMonth"); 1652 monthCombobox.style.left = thisMonth.offsetLeft + "px"; 1653 monthCombobox.style.top = thisMonth.offsetHeight + (othis.Browser.IE?5:4) + "px"; 1654 monthCombobox.style.width = thisMonth.offsetWidth + 15 + "px"; 1655 }; 1656 1657 var thisYear = document.getElementById(this.calendarContainerId + "-thisYear"); 1658 thisYear.onclick = function(){ 1659 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 1660 yearCombobox.innerHTML = othis._createYearCombobox(); 1661 othis._addYearComboboxEvent(); 1662 yearCombobox.style.display = "block"; 1663 var thisYear = document.getElementById(othis.calendarContainerId + "-thisYear"); 1664 yearCombobox.style.left = thisYear.offsetLeft + "px"; 1665 yearCombobox.style.top = thisYear.offsetHeight + (othis.Browser.IE?5:4) + "px"; 1666 yearCombobox.style.width = thisYear.offsetWidth-2 + "px"; 1667 }; 1668 1669 var rows = document.getElementById(this.calendarContainerId + "-bodypanel").childNodes[0].rows; 1670 for(var i = 1; i < rows.length; i++){ 1671 var row = rows[i]; 1672 row.onmouseover = function(){ 1673 othis._addClass(this, "bodypanel-daterow-hover"); 1674 }; 1675 row.onmouseout = function(){ 1676 othis._removeClass(this, "bodypanel-daterow-hover"); 1677 }; 1678 var cells = rows[i].cells; 1679 for(var j = 1; j < cells.length; j++){ 1680 var date = cells[j]; 1681 var dateValue = date.getAttribute("date"); 1682 if(dateValue == this.selectedDateValue){ 1683 this._addClass(date, "bodypanel-date-select"); 1684 othis.selectedDate = date; 1685 } 1686 date.onclick = function(){ 1687 if(othis.selectedDate){ 1688 othis._removeClass(othis.selectedDate, "bodypanel-date-select"); 1689 } 1690 othis._addClass(this, "bodypanel-date-select"); 1691 othis.selectedDate = this; 1692 othis.selectedDateValue = this.getAttribute("date"); 1693 var month = parseInt(othis.selectedDateValue.split('-')[1],10); 1694 var thisMonth = othis.month + 1; 1695 if(thisMonth == 1 && month == 12){ 1696 othis._preMonth(); 1697 } 1698 else if(thisMonth == 12 && month == 1){ 1699 othis._nextMonth(); 1700 } 1701 else if(thisMonth > month){ 1702 othis._preMonth(); 1703 } 1704 else if(thisMonth < month){ 1705 othis._nextMonth(); 1706 } 1707 othis._print(othis.selectedDateValue); 1708 othis._checkSlidePanel(othis.selectedDateValue); 1709 }; 1710 date.ondblclick = function(){ 1711 this.onclick(); 1712 othis._hide(); 1713 }; 1714 date.onmouseover = function(){ 1715 othis._addClass(this, "bodypanel-date-hover"); 1716 }; 1717 date.onmouseout = function(){ 1718 othis._removeClass(this, "bodypanel-date-hover"); 1719 }; 1720 } 1721 } 1722 }; 1723 1724 /** 1725 * Add event to window.document. 1726 * @private 1727 */ 1728 JSCalender.PopCalender.prototype._addDocumentEvent = function(){ 1729 if(document.addEventListener){ 1730 document.addEventListener("keypress",this._keyEvent,false); 1731 document.addEventListener("mousedown",this._clickCheck,false); 1732 } 1733 else{ 1734 document.attachEvent("onkeydown",this._keyEvent); 1735 document.attachEvent("onmousedown",this._clickCheck); 1736 } 1737 }; 1738 1739 /** 1740 * Hide calendar or combobox when clicked 1741 * @private 1742 */ 1743 JSCalender.PopCalender.prototype._clickCheck = function(event){ 1744 var calendar = document.popCalendar; 1745 if (!calendar) { 1746 return; 1747 } 1748 event = window.event || event; 1749 var element = event.srcElement || event.target; 1750 var calendarDom = document.getElementById(calendar.calendarContainerId); 1751 var monthCombobox = document.getElementById(calendar.calendarContainerId + "-monthCombobox"); 1752 var yearCombobox = document.getElementById(calendar.calendarContainerId + "-yearCombobox"); 1753 for (; element != null && element != calendarDom; element = element.parentNode); 1754 if (element == null) { 1755 monthCombobox.style.display = "none"; 1756 yearCombobox.style.display = "none"; 1757 calendar._hide(); 1758 return; 1759 } 1760 element = event.srcElement || event.target; 1761 for (; element != null && element != monthCombobox; element = element.parentNode); 1762 if (element == null) { 1763 monthCombobox.style.display = "none"; 1764 } 1765 element = event.srcElement || event.target; 1766 for (; element != null && element != yearCombobox; element = element.parentNode); 1767 if (element == null) { 1768 yearCombobox.style.display = "none"; 1769 } 1770 }; 1771 1772 /** 1773 * Check data to decide that whether show the slide panel 1774 * @param {String} date The date. 1775 * @private 1776 */ 1777 JSCalender.PopCalender.prototype._checkSlidePanel = function(date){ 1778 var dateInfo = this.config.dates[date]; 1779 var defaultInfo = this.config.dates["default"]; 1780 var slidePanelContainer = document.getElementById(this.calendarContainerId + "-slidePanel").parentNode.parentNode; 1781 if(dateInfo){ 1782 this._showSlidePanel(dateInfo.image, dateInfo.text, date); 1783 slidePanelContainer.style.display = ""; 1784 } 1785 else if(defaultInfo){ 1786 this._showSlidePanel(defaultInfo.image, defaultInfo.text, date); 1787 slidePanelContainer.style.display = ""; 1788 } 1789 else{ 1790 slidePanelContainer.style.display = "none"; 1791 } 1792 }; 1793 1794 /** 1795 * Process key event when press keyboard 1796 * @param {Object} event The event which comes from pressing keyboard. 1797 * @private 1798 */ 1799 JSCalender.PopCalender.prototype._keyEvent = function(event){ 1800 var othis = document.popCalendar; 1801 var KEY = { 1802 LEFT : 37, 1803 UP : 38, 1804 RIGHT : 39, 1805 DOWN : 40, 1806 ESC : 27, 1807 ENTER : 13, 1808 SPACE : 32 1809 }; 1810 var code = event.keyCode || event.charCode; 1811 if(event.ctrlKey){ 1812 switch(code) 1813 { 1814 case KEY.LEFT: 1815 othis._preMonth(); 1816 break; 1817 case KEY.RIGHT: 1818 othis._nextMonth(); 1819 break; 1820 case KEY.UP: 1821 othis._preYear(); 1822 break; 1823 case KEY.DOWN: 1824 othis._nextYear(); 1825 break; 1826 default: 1827 break; 1828 } 1829 } 1830 else{ 1831 switch(code){ 1832 case KEY.LEFT: 1833 othis._parseDate(1); 1834 break; 1835 case KEY.RIGHT: 1836 othis._parseDate(-1); 1837 break; 1838 case KEY.UP: 1839 othis._parseDate(7); 1840 break; 1841 case KEY.DOWN: 1842 othis._parseDate(-7); 1843 break; 1844 case KEY.ESC: 1845 othis._hide(); 1846 break; 1847 case KEY.ENTER: 1848 othis._print(othis.selectedDateValue); 1849 othis._hide(); 1850 break; 1851 case KEY.SPACE: 1852 othis.selectedDateValue = othis._getDateString(othis.thisDay.getFullYear(),othis.thisDay.getMonth()+1,othis.thisDay.getDate()); 1853 othis.year = othis.thisDay.getFullYear(); 1854 othis.month = othis.thisDay.getMonth(); 1855 document.getElementById(othis.calendarContainerId + "-thisYear").innerHTML = othis.year; 1856 document.getElementById(othis.calendarContainerId + "-thisMonth").innerHTML = othis.resource.monthArray[othis.month]; 1857 othis._freshDaysPanel(); 1858 othis._print(othis.selectedDateValue); 1859 break; 1860 default: 1861 break; 1862 } 1863 } 1864 othis._checkSlidePanel(othis.selectedDateValue); 1865 if(othis.Browser.IE){ 1866 return false; 1867 } 1868 else{ 1869 event.preventDefault(); 1870 } 1871 }; 1872 1873 /** 1874 * Get last year's calendar 1875 * @private 1876 */ 1877 JSCalender.PopCalender.prototype._preYear = function(){ 1878 this.year--; 1879 this._freshDaysPanel(); 1880 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1881 }; 1882 1883 /** 1884 * Get next year's calendar 1885 * @private 1886 */ 1887 JSCalender.PopCalender.prototype._nextYear = function(){ 1888 this.year++; 1889 this._freshDaysPanel(); 1890 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1891 }; 1892 1893 /** 1894 * Get last month's calendar 1895 * @private 1896 */ 1897 JSCalender.PopCalender.prototype._preMonth = function(){ 1898 if(this.month == 0){ 1899 this.month = 11; 1900 this.year--; 1901 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1902 } 1903 else{ 1904 this.month--; 1905 } 1906 this._freshDaysPanel(); 1907 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 1908 }; 1909 1910 /** 1911 * Get next month's calendar 1912 * @private 1913 */ 1914 JSCalender.PopCalender.prototype._nextMonth = function(){ 1915 if(this.month == 11){ 1916 this.month = 0; 1917 this.year++; 1918 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1919 } 1920 else{ 1921 this.month++; 1922 } 1923 this._freshDaysPanel(); 1924 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 1925 }; 1926 1927 /** 1928 * Fresh calendar when press keyboard 1929 * @param {Number} step The diff which compares with the selected date. 1930 * @private 1931 */ 1932 JSCalender.PopCalender.prototype._parseDate = function(step){ 1933 if(this.selectedDateValue){ 1934 var arr = this.selectedDateValue.split('-'); 1935 var date = new Date(new Date(arr[0],arr[1]-1,arr[2]) - 24*60*60*1000*step); 1936 } 1937 else{ 1938 var date = new Date(this.thisDay - 24*60*60*1000*step); 1939 } 1940 this.year = date.getFullYear(); 1941 this.month = date.getMonth(); 1942 this.date = date.getDate(); 1943 this.selectedDateValue = this._getDateString(this.year,this.month + 1,this.date); 1944 this._freshDaysPanel(); 1945 document.getElementById(this.calendarContainerId + "-thisYear").innerHTML = this.year; 1946 document.getElementById(this.calendarContainerId + "-thisMonth").innerHTML = this.resource.monthArray[this.month]; 1947 }; 1948 1949 /** 1950 * Convert Date to string 1951 * @param {Number} year The year. 1952 * @param {Number} month The month. 1953 * @param {Date} date The date. 1954 * @private 1955 */ 1956 JSCalender.PopCalender.prototype._getDateString = function(year,month,date){ 1957 return year + "-" + ((month < 10)?("0" + (month)):month) + "-" + ((date < 10)?("0" + (date)):date); 1958 }; 1959 1960 1961 /** 1962 * Fresh calendar 1963 * @private 1964 */ 1965 JSCalender.PopCalender.prototype._freshDaysPanel = function(){ 1966 var str = "<table cellspacing='0' cellpadding='0' class='bodypanel'>" 1967 + this._createCalendarDays() + this._createCalendarDates() 1968 + "</table>"; 1969 document.getElementById(this.calendarContainerId + "-bodypanel").innerHTML = str; 1970 this._addCalendarEvent(); 1971 document.getElementById(this.calendarContainerId).focus(); 1972 }; 1973 1974 /** 1975 * Show slide panel 1976 * @private 1977 */ 1978 JSCalender.PopCalender.prototype._showSlidePanel = function(img, text, dateString){ 1979 var slidePanel = document.getElementById(this.calendarContainerId + "-slidePanel"); 1980 var imageContainer = slidePanel.rows[0].cells[0]; 1981 var topTextContainer = slidePanel.rows[0].cells[1]; 1982 var bottomTextContainer = slidePanel.rows[1].cells[0]; 1983 if(img){ 1984 imageContainer.style.display = ""; 1985 imageContainer.innerHTML = "<img class='slidepanel-img' alt='" 1986 + dateString + "' src='" + img + "'/>"; 1987 } 1988 else{ 1989 imageContainer.style.display = "none"; 1990 } 1991 if(text){ 1992 var textArr = text.split('\n'); 1993 1994 if(textArr.length < 2){ 1995 topTextContainer.style.display = ""; 1996 bottomTextContainer.style.display = "none"; 1997 topTextContainer.innerHTML = textArr[0]; 1998 } 1999 else{ 2000 topTextContainer.style.display = ""; 2001 bottomTextContainer.style.display = ""; 2002 topTextContainer.innerHTML = textArr[0]; 2003 textArr[0] = ""; 2004 bottomTextContainer.innerHTML = textArr.join(" "); 2005 } 2006 } 2007 else{ 2008 topTextContainer.style.display = "none"; 2009 bottomTextContainer.style.display = "none"; 2010 } 2011 }; 2012 2013 /** 2014 * Add event to month combobox 2015 * @private 2016 */ 2017 JSCalender.PopCalender.prototype._addMonthComboboxEvent = function(){ 2018 var othis = this; 2019 var monthCombobox = document.getElementById(this.calendarContainerId + "-monthCombobox"); 2020 for(var i = 0, len = monthCombobox.childNodes.length; i < len; i++){ 2021 var row = monthCombobox.childNodes[i]; 2022 row.onclick = function(){ 2023 document.getElementById(othis.calendarContainerId + "-thisMonth").innerHTML = this.innerHTML; 2024 monthCombobox.style.display = "none"; 2025 othis.month = parseInt(this.getAttribute("value"),10); 2026 othis._freshDaysPanel(); 2027 }; 2028 row.onmouseover = function(){ 2029 othis._addClass(this, "monthcombobox-hover"); 2030 }; 2031 row.onmouseout = function(){ 2032 othis._removeClass(this, "monthcombobox-hover"); 2033 }; 2034 } 2035 }; 2036 2037 /** 2038 * Add event to year combobox 2039 * @private 2040 */ 2041 JSCalender.PopCalender.prototype._addYearComboboxEvent = function(){ 2042 var othis = this; 2043 var yearCombobox = document.getElementById(this.calendarContainerId + "-yearCombobox"); 2044 2045 for(var i = 0, len = yearCombobox.childNodes.length; i < len; i++){ 2046 var row = yearCombobox.childNodes[i]; 2047 if(i == 0){ 2048 row.onclick = function(){ 2049 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 2050 yearCombobox.innerHTML = othis._createYearCombobox(parseInt(yearCombobox.childNodes[5].innerHTML,10)); 2051 othis._addYearComboboxEvent(); 2052 }; 2053 } 2054 else if(i == len - 1){ 2055 row.onclick = function(){ 2056 var yearCombobox = document.getElementById(othis.calendarContainerId + "-yearCombobox"); 2057 yearCombobox.innerHTML = othis._createYearCombobox(parseInt(yearCombobox.childNodes[5].innerHTML,10) + 2); 2058 othis._addYearComboboxEvent(); 2059 }; 2060 } 2061 else{ 2062 row.onclick = function(){ 2063 document.getElementById(othis.calendarContainerId + "-thisYear").innerHTML = this.innerHTML; 2064 yearCombobox.style.display = "none"; 2065 othis.year = parseInt(this.getAttribute("value"),10); 2066 othis._freshDaysPanel(); 2067 }; 2068 } 2069 row.onmouseover = function(){ 2070 othis._addClass(this, "yearcombobox-hover"); 2071 }; 2072 row.onmouseout = function(){ 2073 othis._removeClass(this, "yearcombobox-hover"); 2074 }; 2075 } 2076 }; 2077 2078 /** 2079 * Get left and top of element 2080 * @param {Object} el The element which will be get left and top. 2081 * @private 2082 */ 2083 JSCalender.PopCalender.prototype._getPosition = function(el){ 2084 var positionElement = el; 2085 var positionElementHeight = positionElement.offsetHeight; 2086 var positionElementWidth = positionElement.offsetWidth; 2087 2088 var defaultTop = positionElement.offsetTop + positionElement.offsetHeight; 2089 var defaultLeft = positionElement.offsetLeft; 2090 while((positionElement = positionElement.offsetParent) != null){ 2091 defaultTop += positionElement.offsetTop; 2092 defaultLeft += positionElement.offsetLeft; 2093 } 2094 return {top:defaultTop, left:defaultLeft}; 2095 }; 2096 2097 /** 2098 * Add css class to element. 2099 * @param {Object} el The element where adds class. 2100 * @param {String} className The css class which to be added.. 2101 * @private 2102 */ 2103 JSCalender.PopCalender.prototype._addClass = function(el, className) { 2104 this._removeClass(el, className); 2105 el.className += " " + className; 2106 }; 2107 2108 /** 2109 * Remove css class of element. 2110 * @param {Object} el The element where removes class. 2111 * @param {String} className The css class which to be removed.. 2112 * @private 2113 */ 2114 JSCalender.PopCalender.prototype._removeClass = function(el, className) { 2115 if (!(el && el.className)) { 2116 return; 2117 } 2118 var cssArr = el.className.split(" "); 2119 var newArr = new Array(); 2120 for (var i = 0, len = cssArr.length; i< len; i++){ 2121 if (cssArr[i] != className) { 2122 newArr[newArr.length] = cssArr[i]; 2123 } 2124 } 2125 el.className = newArr.join(" "); 2126 }; 2127 2128 /** 2129 * Remove evnent of window.document 2130 * @private 2131 */ 2132 JSCalender.PopCalender.prototype._removeEvent = function() { 2133 if(document.removeEventListener){ 2134 document.removeEventListener("keypress",this._keyEvent,false); 2135 document.removeEventListener("mousedown",this._clickCheck,false); 2136 } 2137 else{ 2138 document.detachEvent("onkeydown",this._keyEvent); 2139 document.detachEvent("onmousedown",this._clickCheck); 2140 } 2141 }; 2142 2143 /** 2144 * Show calendar 2145 * @private 2146 */ 2147 JSCalender.PopCalender.prototype._show = function() { 2148 this._addDocumentEvent(); 2149 var calendar = document.getElementById(this.calendarContainerId); 2150 if(calendar){ 2151 calendar.style.display = ""; 2152 } 2153 var iframeShim = document.getElementById(this.calendarContainerId + "-iframeshim"); 2154 if(iframeShim){ 2155 iframeShim.style.display = ""; 2156 } 2157 }; 2158 2159 /** 2160 * Hide calendar 2161 * @private 2162 */ 2163 JSCalender.PopCalender.prototype._hide = function() { 2164 this._removeEvent(); 2165 var calendar = document.getElementById(this.calendarContainerId); 2166 if(calendar){ 2167 calendar.style.display = "none"; 2168 } 2169 var iframeShim = document.getElementById(this.calendarContainerId + "-iframeshim"); 2170 if(iframeShim){ 2171 iframeShim.style.display = "none"; 2172 } 2173 }; 2174 2175 /** 2176 * Remove calendar 2177 * @private 2178 */ 2179 JSCalender.PopCalender.prototype._remove = function() { 2180 this._removeEvent(); 2181 var calendarDom = document.getElementById(document.popCalendar.calendarContainerId); 2182 calendarDom.parentNode.removeChild(calendarDom); 2183 document.popCalendar = null; 2184 }; 2185 2186 /** 2187 * Output the selected date 2188 * @param {String} dateString The format of outputed date 2189 * @private 2190 */ 2191 JSCalender.PopCalender.prototype._print = function(dateString) { 2192 if(!dateString){ 2193 return; 2194 } 2195 var arr = dateString.split('-'); 2196 var printFormat = (this.config.printFormat || "").toLowerCase(); 2197 printFormat = printFormat.replace("yyyy", arr[0]); 2198 printFormat = printFormat.replace("yy", arr[0].substr(2)); 2199 printFormat = printFormat.replace("mm", arr[1]); 2200 printFormat = printFormat.replace("dd", arr[2]); 2201 var targetElement = document.getElementById(this.targetId); 2202 if(targetElement){ 2203 targetElement.value = printFormat; 2204 } 2205 }; 2206 2207 /** 2208 * Set the config of calendar 2209 * @param {String} config The config which to be set 2210 * @public 2211 */ 2212 JSCalender.PopCalender.prototype.setConfig = function(config) { 2213 this.config = config; 2214 }; 2215 2216 /** 2217 * Set the language of calendar 2218 * @param {String} lang The language which to be set 2219 * @public 2220 */ 2221 JSCalender.PopCalender.prototype.setLanguage = function(lang) { 2222 this.resource = Calender_Resources[lang.toLowerCase()]|| Calender_Resources["en"]; 2223 }; 2224 2225 /** 2226 * Set the css of calendar 2227 * @param {String} css The css which to be set 2228 * @public 2229 */ 2230 JSCalender.PopCalender.prototype.setCss = function(css) { 2231 this.config.css = css; 2232 }; 2233 2234 /** 2235 * Set the first day in week 2236 * @param {Number} day The day which to be set 2237 * @public 2238 */ 2239 JSCalender.PopCalender.prototype.setFirstDayInWeek = function(day) { 2240 this.firstDayInWeek = day; 2241 }; 2242 2243 /** 2244 * Set the export format 2245 * @param {String} printFormat The print format which to be set 2246 * @public 2247 */ 2248 JSCalender.PopCalender.prototype.setPrintFarmat = function(printFormat) { 2249 this.config.printFormat = printFormat; 2250 }; 2251 2252 /** 2253 * Set the export format 2254 * @param {String} date The date which to be set 2255 * @param {String} image The image which to be show in slide panel 2256 * @param {String} text The text which to be show in slide panel 2257 * @public 2258 */ 2259 JSCalender.PopCalender.prototype.setSlideDate = function(date, image, text) { 2260 this.config.dates[date] = {}; 2261 this.config.dates[date].text = text; 2262 this.config.dates[date].image = image; 2263 }; 2264