simplecalendar.js
上传用户:m68239277
上传日期:2014-10-12
资源大小:824k
文件大小:18k
源码类别:

Web服务器

开发平台:

PHP

  1. /*
  2. *****************************************************************************************************
  3. Author : Lea Smart
  4. Source : www.totallysmartit.com
  5. Date : 7/3/2001
  6. DHTML Calendar
  7. Version 1.2
  8. You are free to use this code if you retain this header.
  9. You do not need to link to my site (be nice though!)
  10. Amendments
  11. 22 Jan 2002; Added ns resize bug code; rewrote date functions into Date 'class';
  12.  Added support for yyyy-mm-dd date format
  13.  Added support for calendar beginning on any day
  14. 7th Feb 2002 Fixed day highlight when year wasn't current year bug
  15. 9th Jun 2002 Fixed bug with weekend colour
  16.  Amended the code for the date functions extensions.  Shortened addDays code considerably
  17. *****************************************************************************************************
  18. */
  19. var timeoutDelay = 2000; // milliseconds, change this if you like, set to 0 for the calendar to never auto disappear
  20. var g_startDay = 0// 0=sunday, 1=monday
  21. // preload images
  22. var imgUp = new Image(8,12);
  23. //imgUp.src = 'images/up.gif';
  24. var imgDown = new Image(8,12);
  25. //imgDown.src = 'images/down.gif';
  26. // used by timeout auto hide functions
  27. var timeoutId = false;
  28. // the now standard browser sniffer class
  29. function Browser(){
  30.   this.dom = document.getElementById?1:0;
  31.   this.ie4 = (document.all && !this.dom)?1:0;
  32.   this.ns4 = (document.layers && !this.dom)?1:0;
  33.   this.ns6 = (this.dom && !document.all)?1:0;
  34.   this.ie5 = (this.dom && document.all)?1:0;
  35.   this.ok = this.dom || this.ie4 || this.ns4;
  36.   this.platform = navigator.platform;
  37. }
  38. var browser = new Browser();
  39. // dom browsers require this written to the HEAD section
  40. if (browser.dom || browser.ie4){
  41.     document.writeln('<style>');
  42. document.writeln('#container {');
  43. document.writeln('position : absolute;');
  44. document.writeln('left : 100px;');
  45. document.writeln('top : 100px;');
  46. document.writeln('width : 124px;');;
  47. browser.platform=='Win32'?height=140:height=145;
  48. document.writeln('height : ' + height +'px;');
  49. document.writeln('clip:rect(0px 124px ' + height + 'px 0px);');
  50. //document.writeln('overflow : hidden;');
  51. document.writeln('visibility : hidden;');
  52. document.writeln('background-color : #ffffff');
  53. document.writeln('}');
  54. document.writeln('</style>')
  55. document.write('<div id="container"');
  56. if (timeoutDelay) document.write(' onmouseout="calendarTimeout();" onmouseover="if (timeoutId) clearTimeout(timeoutId);"');
  57. document.write('></div>');
  58. }
  59. var g_Calendar;  // global to hold the calendar reference, set by constructor
  60. function calendarTimeout(){
  61.   if (browser.ie4 || browser.ie5){
  62.     if (window.event.srcElement && window.event.srcElement.name!='month') timeoutId=setTimeout('g_Calendar.hide();',timeoutDelay);
  63.   }
  64.   if (browser.ns6 || browser.ns4){
  65.     timeoutId=setTimeout('g_Calendar.hide();',timeoutDelay);
  66.   }
  67. }
  68. // constructor for calendar class
  69. function Calendar(){
  70.   g_Calendar = this;
  71.   // some constants needed throughout the program
  72.   this.daysOfWeek = new Array("Su","Mo","Tu","We","Th","Fr","Sa");
  73.   this.months = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
  74.   this.daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  75.   
  76.   if (browser.ns4){
  77.     var tmpLayer = new Layer(127);
  78. if (timeoutDelay){
  79.   tmpLayer.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
  80.   tmpLayer.onmouseover = function(event) { if (timeoutId) clearTimeout(timeoutId); };
  81.   tmpLayer.onmouseout = function(event) { timeoutId=setTimeout('g_Calendar.hide()',timeoutDelay);};
  82. }
  83.     tmpLayer.x = 100;
  84.     tmpLayer.y = 100;
  85.     tmpLayer.bgColor = "#ffffff";
  86.   }
  87.   if (browser.dom || browser.ie4){
  88. var tmpLayer = browser.dom?document.getElementById('container'):document.all.container;
  89.   }
  90.   this.containerLayer = tmpLayer;
  91.   if (browser.ns4 && browser.platform=='Win32') {
  92.     this.containerLayer.clip.height=134;
  93.     this.containerLayer.clip.width=127;
  94.   }
  95. }
  96.   Calendar.prototype.getFirstDOM = function() {
  97. var thedate = new Date();
  98. thedate.setDate(1);
  99. thedate.setMonth(this.month);
  100. thedate.setFullYear(this.year);
  101. return thedate.getDay();
  102. }
  103. Calendar.prototype.getDaysInMonth = function (){
  104.    if (this.month!=1) {
  105.    return this.daysInMonth[this.month]
  106.    }
  107.    else {
  108.      // is it a leap year
  109.     if (Date.isLeapYear(this.year)) {
  110.   return 29;
  111. }
  112.     else {
  113.   return 28;
  114. }
  115.    }
  116. }
  117.  
  118. Calendar.prototype.buildString = function(){
  119.   var tmpStr = '<form onSubmit="this.year.blur();return false;"><table width="100%" border="0" cellspacing="0" cellpadding="2" class="calBorderColor"><tr><td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="1" class="calBgColor">';
  120.   tmpStr += '<tr>';
  121.   tmpStr += '<td width="60%" class="cal" align="left">';
  122.   if (this.hasDropDown) {
  123.     tmpStr += '<select class="month" name="month" onchange="g_Calendar.selectChange();">';
  124. for (var i=0;i<this.months.length;i++){
  125.       tmpStr += '<option value="' + i + '"' 
  126.   if (i == this.month) tmpStr += ' selected';
  127.   tmpStr += '>' + this.months[i] + '</option>';
  128.     }
  129.     tmpStr += '</select>';
  130.   } else {
  131.     tmpStr += '<table border="0" cellspacing="0" cellpadding="0"><tr><td><a href="javascript: g_Calendar.changeMonth(-1);"><img name="calendar" src="" width="8" height="12" border="0" alt=""></a></td><td class="cal" width="100%" align="center">' + this.months[this.month] + '</td><td class="cal"><a href="javascript: g_Calendar.changeMonth(+1);"><img name="calendar" src="" width="8" height="12" border="0" alt=""></a></td></tr></table>';
  132.   }
  133.   tmpStr += '</td>';
  134.   /* observation : for some reason if the below event is changed to 'onChange' rather than 'onBlur' it totally crashes IE (4 and 5)!
  135.   */
  136.   tmpStr += '<td width="40%" align="right" class="cal">';
  137.   
  138.   if (this.hasDropDown) { 
  139.     tmpStr += '<input class="year" type="text" size="';
  140.     // get round NS4 win32 lenght of year input problem
  141.     (browser.ns4 && browser.platform=='Win32')?tmpStr += 1:tmpStr += 4;
  142.   tmpStr += '" name="year" maxlength="4" onBlur="g_Calendar.inputChange();" value="' + this.year + '">';
  143.   } else {
  144.   tmpStr += '<table border="0" cellspacing="0" cellpadding="0"><tr><td class="cal"><a href="javascript: g_Calendar.changeYear(-1);"><img name="calendar" src="" width="8" height="12" border="0" alt=""></a></td><td class="cal" width="100%" align="center">' + this.year + '</td><td class="cal"><a href="javascript: g_Calendar.changeYear(+1);"><img name="calendar" src="" width="8" height="12" border="0" alt=""></a></td></tr></table>'
  145.   }
  146.   tmpStr += '</td>';
  147.   tmpStr += '</tr>';
  148.   tmpStr += '</table>';
  149.   var iCount = 1;
  150.   var iFirstDOM = (7+this.getFirstDOM()-g_startDay)%7; // to prevent calling it in a loop
  151.   var iDaysInMonth = this.getDaysInMonth(); // to prevent calling it in a loop
  152.   
  153.   tmpStr += '<table width="100%" border="0" cellspacing="0" cellpadding="1" class="calBgColor">';
  154.   tmpStr += '<tr>';
  155.     for (var i=0;i<7;i++){
  156.   tmpStr += '<td align="center" class="calDaysColor">' + this.daysOfWeek[(g_startDay+i)%7] + '</td>';
  157. }
  158.   tmpStr += '</tr>';
  159.   var tmpFrom = parseInt('' + this.dateFromYear + this.dateFromMonth + this.dateFromDay,10);
  160.   var tmpTo = parseInt('' + this.dateToYear + this.dateToMonth + this.dateToDay,10);
  161.   var tmpCompare;
  162.   for (var j=1;j<=6;j++){
  163.      tmpStr += '<tr>';
  164.      for (var i=1;i<=7;i++){
  165.    tmpStr += '<td width="16" align="center" '
  166.    if ( (7*(j-1) + i)>=iFirstDOM+1  && iCount <= iDaysInMonth){
  167.      if (iCount==this.day && this.year==this.oYear && this.month==this.oMonth) tmpStr += 'class="calHighlightColor"';
  168.  else {
  169.     if (i==7-g_startDay || i==((7-g_startDay)%7)+1) tmpStr += 'class="calWeekend"';
  170. else tmpStr += 'class="cal"';
  171.  }
  172.      tmpStr += '>';
  173.  /* could create a date object here and compare that but probably more efficient to convert to a number
  174.    and compare number as numbers are primitives */
  175.  tmpCompare = parseInt('' + this.year + padZero(this.month) + padZero(iCount),10);
  176.  if (tmpCompare >= tmpFrom && tmpCompare <= tmpTo) {
  177.    tmpStr += '<a class="cal" href="javascript: g_Calendar.clickDay(' + iCount + ');">' + iCount + '</a>';
  178.  } else {
  179.    tmpStr += '<span class="disabled">' + iCount + '</span>';
  180.  }
  181.  iCount++;
  182.    } else {
  183.      if  (i==7-g_startDay || i==((7-g_startDay)%7)+1) tmpStr += 'class="calWeekend"'; else tmpStr +='class="cal"';
  184.  tmpStr += '>&nbsp;';
  185.    }
  186.    tmpStr += '</td>'
  187.  }
  188.  tmpStr += '</tr>'
  189.   }
  190.   tmpStr += '</table></td></tr></table></form>'
  191.   return tmpStr;
  192. }
  193. Calendar.prototype.selectChange = function(){
  194.   this.month = browser.ns6?this.containerLayer.ownerDocument.forms[0].month.selectedIndex:this.containerLayer.document.forms[0].month.selectedIndex;
  195.   this.writeString(this.buildString());
  196. }
  197. Calendar.prototype.inputChange = function(){
  198.   var tmp = browser.ns6?this.containerLayer.ownerDocument.forms[0].year:this.containerLayer.document.forms[0].year;
  199.   if (tmp.value >=1900 || tmp.value <=2100){
  200.     this.year = tmp.value;
  201.     this.writeString(this.buildString());
  202.   } else {
  203.     tmp.value = this.year;
  204.   }
  205. }
  206. Calendar.prototype.changeYear = function(incr){
  207.    (incr==1)?this.year++:this.year--;
  208.    this.writeString(this.buildString());
  209. }
  210. Calendar.prototype.changeMonth = function(incr){
  211.     if (this.month==11 && incr==1){
  212.       this.month = 0;
  213.      this.year++;
  214.     } else {
  215.       if (this.month==0 && incr==-1){
  216.         this.month = 11;
  217.     this.year--;
  218.       } else {
  219.     (incr==1)?this.month++:this.month--;
  220.   }
  221. }
  222. this.writeString(this.buildString());
  223. }
  224. Calendar.prototype.clickDay = function(day){
  225.    var tmp = eval('document.' + this.target);
  226.    tmp.value = this.formatDateAsString(day,this.month,this.year);
  227.     if (browser.ns4) this.containerLayer.hidden=true;
  228.     if (browser.dom || browser.ie4){
  229.       this.containerLayer.style.visibility='hidden';
  230.     }
  231. }
  232. Calendar.prototype.formatDateAsString = function(day, month, year){
  233.   var delim = eval('/\' + this.dateDelim + '/g');
  234.    switch (this.dateFormat.replace(delim,"")){
  235.      case 'ddmmmyyyy': return padZero(day) + this.dateDelim + this.months[month].substr(0,3) + this.dateDelim + year;
  236.              case 'ddmmyyyy': return padZero(day) + this.dateDelim + padZero(month+1) + this.dateDelim + year;
  237.      case 'mmddyyyy': return padZero((month+1)) + this.dateDelim + padZero(day) + this.dateDelim + year;
  238.      case 'yyyymmdd': return year + this.dateDelim + padZero(month+1) + this.dateDelim + padZero(day);
  239.      case 'yyyymmdd': return year + this.dateDelim + padZero(month+1) + this.dateDelim + padZero(day);
  240.      case 'yyyy-mm-dd': return year + this.dateDelim + padZero(month+1) + this.dateDelim + padZero(day);
  241.      case 'yyyymmdd': return year  + padZero(month+1)  + padZero(day);
  242.  default: alert('unsupported date format');
  243.    }
  244. }
  245. Calendar.prototype.writeString = function(str){
  246.   if (browser.ns4){
  247.     this.containerLayer.document.open();
  248.     this.containerLayer.document.write(str);
  249.     this.containerLayer.document.close();
  250.   } 
  251.   if (browser.dom || browser.ie4){
  252.     this.containerLayer.innerHTML = str;
  253.   }
  254. }
  255. Calendar.prototype.show = function(event, target, bHasDropDown, dateFormat, dateFrom, dateTo){
  256. // calendar can restrict choices between 2 dates, if however no restrictions
  257. // are made, let them choose any date between 1900 and 3000
  258. this.dateFrom = dateFrom || new Date(1900,0,1);
  259. this.dateFromDay = padZero(this.dateFrom.getDate());
  260. this.dateFromMonth = padZero(this.dateFrom.getMonth());
  261. this.dateFromYear = this.dateFrom.getFullYear();
  262. this.dateTo = dateTo || new Date(3000,0,1);
  263. this.dateToDay = padZero(this.dateTo.getDate());
  264. this.dateToMonth = padZero(this.dateTo.getMonth());
  265. this.dateToYear = this.dateTo.getFullYear();
  266. this.hasDropDown = bHasDropDown;
  267. this.dateFormat = dateFormat || 'dd-mmm-yyyy';
  268. switch (this.dateFormat){
  269.   case 'dd-mmm-yyyy':
  270.   case 'dd-mm-yyyy':
  271.   case 'yyyy-mm-dd':
  272.         this.dateDelim = '-';
  273. break;
  274.   case 'dd/mm/yyyy':
  275.   case 'mm/dd/yyyy':
  276.   case 'dd/mmm/yyyy':
  277.     this.dateDelim = '/';
  278. break;
  279. }
  280.   if (browser.ns4) {
  281.     if (!this.containerLayer.hidden) {
  282.   this.containerLayer.hidden=true;
  283.   return;
  284. }
  285.    }
  286.   if (browser.dom || browser.ie4){
  287.     if (this.containerLayer.style.visibility=='visible') {
  288.   this.containerLayer.style.visibility='hidden';
  289.   return;
  290. }  
  291.   }
  292.   if (browser.ie5 || browser.ie4){
  293.     var event = window.event;
  294.   }
  295.   if (browser.ns4){
  296.     this.containerLayer.x = event.x+10;
  297.     this.containerLayer.y = event.y-5;
  298.   }
  299.   if (browser.ie5 || browser.ie4){
  300.     var obj = event.srcElement;
  301.       x = 0;
  302.    while (obj.offsetParent != null) {
  303.        x += obj.offsetLeft;
  304.        obj = obj.offsetParent;
  305.    }
  306.    x += obj.offsetLeft;
  307.     y = 0;
  308. var obj = event.srcElement;
  309.     while (obj.offsetParent != null) {
  310.        y += obj.offsetTop;
  311.        obj = obj.offsetParent;
  312.    }
  313.    y += obj.offsetTop;
  314.         this.containerLayer.style.left = x;
  315. if (event.y>0)this.containerLayer.style.top = y+20;
  316.   }
  317.   if (browser.ns6){
  318.     this.containerLayer.style.left = event.pageX+10;
  319. this.containerLayer.style.top = event.pageY-5;
  320.   }
  321.   this.target = target;
  322.   var tmp = eval('document.' + this.target);
  323.   if (tmp && tmp.value && tmp.value.split(this.dateDelim).length==3 && tmp.value.indexOf('d')==-1){
  324.     var atmp = tmp.value.split(this.dateDelim)
  325. switch (this.dateFormat){
  326.  case 'dd-mmm-yyyy':
  327.  case 'dd/mmm/yyyy':
  328.    for (var i=0;i<this.months.length;i++){
  329.      if (atmp[1].toLowerCase()==this.months[i].substr(0,3).toLowerCase()){
  330.        this.month = this.oMonth = i;
  331.    break;
  332.      }
  333.    }
  334.    this.day = parseInt(atmp[0],10);
  335.    this.year = this.oYear = parseInt(atmp[2],10);
  336.    break;
  337.  case 'dd/mm/yyyy':
  338.  case 'dd-mm-yyyy':
  339.    this.month = this.oMonth = parseInt(atmp[1]-1,10); 
  340.    this.day = parseInt(atmp[0],10);
  341.    this.year = this.oYear = parseInt(atmp[2],10);
  342.    break;
  343.  case 'mm/dd/yyyy':
  344.  case 'mm-dd-yyyy':
  345.    this.month = this.oMonth = parseInt(atmp[0]-1,10);
  346.    this.day = parseInt(atmp[1],10);
  347.    this.year = this.oYear = parseInt(atmp[2],10);
  348.    break;
  349.  case 'yyyy-mm-dd':
  350.    this.month = this.oMonth = parseInt(atmp[1]-1,10);
  351.    this.day = parseInt(atmp[2],10);
  352.    this.year = this.oYear = parseInt(atmp[0],10);
  353.    break;
  354. }
  355.   } else { // no date set, default to today
  356.     var theDate = new Date();
  357.     this.year = this.oYear = theDate.getFullYear();
  358.      this.month = this.oMonth = theDate.getMonth();
  359.      this.day = this.oDay = theDate.getDate();
  360.   }
  361.   this.writeString(this.buildString());
  362.   
  363.   // and then show it!
  364.    if (browser.ns4) {
  365.    this.containerLayer.hidden=false;
  366.    }
  367.   if (browser.dom || browser.ie4){
  368.       this.containerLayer.style.visibility='visible';
  369.   }
  370. }
  371. Calendar.prototype.hide = function(){
  372.   if (browser.ns4) this.containerLayer.hidden = true;
  373.   if (browser.dom || browser.ie4){
  374.     this.containerLayer.style.visibility='hidden';
  375.   }
  376. }
  377. function handleDocumentClick(e){
  378.   if (browser.ie4 || browser.ie5) e = window.event;
  379.   if (browser.ns6){
  380.     var bTest = (e.pageX > parseInt(g_Calendar.containerLayer.style.left,10) && e.pageX <  (parseInt(g_Calendar.containerLayer.style.left,10)+125) && e.pageY < (parseInt(g_Calendar.containerLayer.style.top,10)+125) && e.pageY > parseInt(g_Calendar.containerLayer.style.top,10));
  381.     if (e.target.name!='imgCalendar' && e.target.name!='month'  && e.target.name!='year' && e.target.name!='calendar' && !bTest){
  382.   g_Calendar.hide(); 
  383. }
  384.   }
  385.   if (browser.ie4 || browser.ie5){
  386. // extra test to see if user clicked inside the calendar but not on a valid date, we don't want it to disappear in this case
  387.    var bTest = (e.x > parseInt(g_Calendar.containerLayer.style.left,10) && e.x <  (parseInt(g_Calendar.containerLayer.style.left,10)+125) && e.y < (parseInt(g_Calendar.containerLayer.style.top,10)+125) && e.y > parseInt(g_Calendar.containerLayer.style.top,10));
  388.     if (e.srcElement.name!='imgCalendar' && e.srcElement.name!='month' && e.srcElement.name!='year' && !bTest & typeof(e.srcElement)!='object'){
  389.   g_Calendar.hide(); 
  390. }
  391.   }
  392.   if (browser.ns4) g_Calendar.hide();
  393. }
  394. // utility function
  395. function padZero(num) {
  396.   return ((num <= 9) ? ("0" + num) : num);
  397. }
  398.   // Finally licked extending  native date object;
  399.   Date.isLeapYear = function(year){ if (year%4==0 && ((year%100!=0) || (year%400==0))) return true; else return false; }
  400.   Date.daysInYear = function(year){ if (Date.isLeapYear(year)) return 366; else return 365;}
  401.   var DAY = 1000*60*60*24;
  402.   Date.prototype.addDays = function(num){
  403. return new Date((num*DAY)+this.valueOf());
  404.   }
  405.   
  406.  // events capturing, careful you don't override this by setting something in the onload event of 
  407. // the body tag
  408. window.onload=function(){ 
  409.   new Calendar(new Date());
  410.   if (browser.ns4){
  411.     if (typeof document.NSfix == 'undefined'){
  412.   document.NSfix = new Object();
  413.       document.NSfix.initWidth=window.innerWidth;
  414.   document.NSfix.initHeight=window.innerHeight;
  415. }
  416.   }
  417. }
  418. if (browser.ns4) window.onresize = function(){
  419.   if (document.NSfix.initWidth!=window.innerWidth || document.NSfix.initHeight!=window.innerHeight) window.location.reload(false);
  420. } // ns4 resize bug workaround
  421. window.document.onclick=handleDocumentClick;
  422.     window.onerror = function(msg,url,line){
  423.   alert('******* an error has occurred ********' +
  424.   'nnPlease check that' + 
  425.   'nn1)You have not added any code to the body onload event,'
  426.   +  'nif you want to run something as well as the calendar initialisation'
  427.   + 'ncode, add it to the onload event in the calendar library.'
  428.   + 'nn2)You have set the parameters correctly in the g_Calendar.show() method '
  429.   + 'nnSee www.totallysmartit.com\examples\calendar\simple.asp for examples'
  430.   + 'nn------------------------------------------------------'
  431.   + 'nError details'
  432.   + 'nText:' + msg + 'nurl:' + url + 'nline:' + line);
  433. }