MxxCalendar 日期时间选择控件

<!-- MxxCalendar.htm -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>梅雪香日期时间控件</title>
<style type="text/css">
 .mxxCalendar{  behavior: url(MxxCalendar.htc);}
 td{font-size:12px}
</style>
</head>

<body>
<table width="800" border="1" cellspacing="0" cellpadding="8" align="center">
  <tr>
    <td colspan="2" align="center"><h2>梅雪香日期时间控件</h2></td>
  </tr>
  <tr>
    <td width="20%"><div align="right">控件名称:</div></td>
    <td width="80%">梅雪香日期时间控件</td>
  </tr>
  <tr>
    <td><div align="right">相关技术:</div></td>
    <td>htc,popup</td>
  </tr>
  <tr>
    <td><div align="right">版本:</div></td>
    <td style="color:red">V1.01 修正了当页面有滚动条或者页面在frame中不能正常定位的问题</td>
  </tr>
  <tr>
    <td><div align="right">功能说明:</div></td>
    <td>选择日期和时间,支持动态显示,支持快捷键操作.</td>
  </tr>
  <tr>
    <td><div align="right">修改须知:</div></td>
    <td>该控件没有详细的帮助文档,需要自己摸索,参看不详尽的注释.</td>
  </tr>
  <tr>
    <td><div align="right">调用方法:</div></td>
    <td>参见htc文件头部说明,需要显示时间在控件源对象上添加代码: showtime="true"</td>
  </tr>
  <tr>
    <td><div align="right">问题反馈:</div></td>
    <td>如发现bug或者有改进意见请mail给我:wy_hd@163.com,想骂我mail同上</td>
  </tr>
  <tr>
    <td><div align="right">示例:</div></td>
    <td>
  <input name="text" type="text" class="mxxCalendar" showtime="true" id="txtMxxCalendar" value="" size="20">
  <input type="button" value="※" οnclick="document.getElementById('txtMxxCalendar').focus();">
 </td>
  </tr>
</table>
</body>
</html>

<!--
MxxCalendar.htc
作者 : 梅雪香(meixx)
时间 : 2005-11-11
描述 : mxxCalendar(htc) v1.0
调用方法:在<head></head>中添加
 <style type="text/css">
  .mxxCalendar{  behavior: url(MxxCalendar.htc);}
 </style>
   为需要菜单的对象添加  class="mxxCalendar"
   e.g : <input type="text" id="txtMxxCalendar" size="15" class="mxxCalendar">
-->
<!--
接口定义
-->
<public:component>
   <public:property name="description"    value="mxxCalendar" />
   <public:property name="version"     value="1.0.0.0" />

   <public:attach  event="oncontentready"   onevent="init()"   />
   <public:attach  event="onfocus"   onevent="showMxxCalendar()" />
   <public:attach  event="onclick"   onevent="showMxxCalendar()" />

</public:component>
<!--
组件实现
-->
<script language="javascript">
var oPopup = null; //popup对象,作为载体
var step = 1 ; //动态显示时的记步器

function mxxCalendar(){
 this.showTime = eval(element.showtime); //是否显示时间选择项,默认为不显示
 this.style = "yy-mm-dd"; //显示时间的样式
 this.year = 0; //当前年
 this.month = 0; //当前月
 this.day = 0; //当前月
 this.left = 0; //控件位置x坐标
 this.top = 0; //控件位置y坐标
 this.width = 150; //控件宽度
 this.height = 160; //控件高度
 this.curClassName=""; //记录onmouseover时,日期td的className
 this.minYear = 1970; //年区间最小值
 this.maxYear = 2030; //年区间最大值
 this.isDynamicShow = false; //是否动态显示控件
 this.dynamicShow = "v";  //动态显示方向 h:水平 v:竖直
 this.speed = 2; //动态显示时的速度
}
var mc = new mxxCalendar();
function init(){
 element.readOnly = true;
 element.style.cursor = "default";
 oPopup= window.createPopup();
 var oPopDoc = oPopup.document;
 var oPopBody = oPopDoc.body;
 oPopDoc.oncontextmenu = function (){ return false; };
 oPopBody.onselectstart = function (){ return false; };
 var strHTML=""
 strHTML+='<table id="tbMxxCalendar" cellpadding="0">'
     + '<tr>'
     + '<td><input type="button" HIDEFOCUS="true" οnfοcus="this.blur()" value="&lt;&lt;" title="向前一年(Up or W)" class="button"></td>'
     + '<td><input type="button" HIDEFOCUS="true" οnfοcus="this.blur()" value="&lt;" title="向前一月(Left or A)" class="button"></td>'
     + '<td colspan="2"></td><td colspan="2"></td>'
     + '<td><input type="button" HIDEFOCUS="true" οnfοcus="this.blur()" value="&gt;" title="向后一月(Right or D)" class="button"></td>'
     + '<td><input type="button" HIDEFOCUS="true" οnfοcus="this.blur()" value="&gt;&gt;" title="向后一年(Down or S)" class="button"></td>'
     + '</tr><tr>';
 for(i=0;i<8;i++)
  strHTML += '<td width="10%">'+'周日一二三四五六'.charAt(i)+'</td>';
 strHTML+='</tr>';
 for(var i=0;i<5;i++){
  strHTML+="<tr>";
  for(var j=0;j<8;j++)
     strHTML+="<td>&nbsp;</td>";
  strHTML+="</tr>";
 }
 strHTML+='<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';
 if(mc.showTime){
  for(var i=0;i<3;i++)
   strHTML += '<td title="'+"时分秒".charAt(i)+'" class="tdTime"></td>';
 }
 else strHTML += '<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>';
 strHTML += '<td><input type="button" hidefocus="true" οnfοcus="this.blur()" value="清" title="清楚文本框内容(Del)"/ class="button"></td>'
      +  '</table>';
 oPopBody.innerHTML=strHTML;
 SetMxxCalendarStyle();
 attachEventForTb();
}
function SetMxxCalendarStyle(){
 var oPopDoc = oPopup.document;
 var oStyleSheet=oPopDoc.createStyleSheet();
 with(oStyleSheet){
  addRule("td", "vertical-align:middle; text-align: center; border:1px solid; border-color:  #D4D0C8 #FFFFFF  #FFFFFF #D4D0C8");
  addRule("#tbMxxCalendar", "border:solid 1px #6BBFD9; font-size:12px; width:100%; height:100%; cursor:default");
  addRule(".button", "width:100%; height:100%;border: 0px solid #D4D0C8; padding-top: 1px; height: 18;color:#000080; background-color:#FFFFF1");
  addRule(".firstrow", "color:#000080; background-color:#FFFFF1");
  addRule(".secondrow", "color:blue; background-color:#FFFFF1");
  addRule(".curMonth", "color:#000080; background-color:#DEEAF6");
  addRule(".notCurMonth", "color:#DCDCDC; background-color:#DEEAF6");
  addRule(".curDay", "color:red; background-color:#DEEAF6");
  addRule(".tdTime", "color:#FF00FF; background-color:#FFFFF1");
  addRule(".tdOver", "color:#FFFFF1; background-color:#6BBFD9");
  addRule(".tdWeek", "color:#3399FF; background-color:#FFFFF1");
 }
 var tbRows = oPopup.document.getElementById("tbMxxCalendar").rows;
 tbRows[0].className = "firstrow";
 tbRows[1].className = "secondrow";
 for(var i=2;i<8;i++){
  tbRows[i].cells[0].className = "tdWeek";
 }
}
//为表格设定事件
function attachEventForTb(){
 var pDoc = oPopup.document;
 var tbRows = pDoc.getElementById("tbMxxCalendar").rows;
 var head= pDoc.getElementsByTagName("head").item(0);
 with(tbRows[0]){
  cells[0].childNodes[0].attachEvent("onclick",function(){chgDate("y",-1);});
  cells[1].childNodes[0].attachEvent("onclick",function(){chgDate("m",-1);});
  cells[4].childNodes[0].attachEvent("onclick",function(){chgDate("m",1);});
  cells[5].childNodes[0].attachEvent("onclick",function(){chgDate("y",1);});
  cells[2].attachEvent("onclick",function(){selectVal(tbRows[0].cells[2],0);});
  cells[3].attachEvent("onclick",function(){selectVal(tbRows[0].cells[3],12);});
 }
 var script = pDoc.createElement('SCRIPT');
 script.language = "javascript";
 var strScript = '';
 strScript += 'document.onkeydown = function(){'
           +  ' var code = window.event.keyCode;'
           +  ' var firstRow = document.getElementById("tbMxxCalendar").rows[0];'
           +  ' if(event.ctrlKey){'
           +  '  var td=null;'
           +  '  switch(code){'
           +  '   case 37: td = firstRow.cells[1].childNodes[0];td.click();td.click();td.click(); break;'
           +  '   case 38: td = firstRow.cells[0].childNodes[0];td.click();td.click();td.click();td.click();td.click(); break;'
           +  '   case 39: td = firstRow.cells[4].childNodes[0];td.click();td.click();td.click(); break;'
           +  '   case 40: td = firstRow.cells[5].childNodes[0];td.click();td.click();td.click();td.click();td.click(); break;'
           +  '   default: return;'
           +  '  }'
           +  ' }'
           +  ' else{'
           +  '  switch(code){'
           +  '   case 32: case 13: var td = document.getElementById("curDay"); if(td) td.click(); break;'
           +  '   case 65: case 37: firstRow.cells[1].childNodes[0].click(); break;'
           +  '   case 87: case 38: firstRow.cells[0].childNodes[0].click(); break;'
           +  '   case 68: case 39: firstRow.cells[4].childNodes[0].click(); break;'
           +  '   case 83: case 40: firstRow.cells[5].childNodes[0].click(); break;'
           +  '   case 46: document.getElementById("tbMxxCalendar").rows[7].cells[7].childNodes[0].click(); break;'
           +  '   default: return;'
           +  '  }'
           +  ' }'
           +  '}';
 script.text = strScript;
 head.appendChild(script);

 for(var i=2;i<8;i++)
  for(var j=1,k=(i==7?(mc.showTime?4:7):8);j<k;j++)
   addEvent(tbRows[i].cells[j]);
 with(tbRows[7]){
  if(mc.showTime){
   cells[4].attachEvent("onclick",function(){selectVal(cells[4],23);});
   cells[5].attachEvent("onclick",function(){selectVal(cells[5],59);});
   cells[6].attachEvent("onclick",function(){selectVal(cells[6],59);});
  }
  cells[7].childNodes[0].attachEvent("onclick",function(){element.value=""; oPopup.hide();});
 }
}

//显示日期控件
function showMxxCalendar(){
 var parObj = element;
 mc.top =  0;
 mc.left = 0;
 while(parObj){
  mc.left += parObj.offsetLeft;
  mc.top += parObj.offsetTop;
  if (!parObj.offsetParent)
  {
   mc.top -=  parObj.ownerDocument.body.scrollTop;
   mc.left -= parObj.ownerDocument.body.scrollLeft;
  }
  if(!parObj.offsetParent && parObj.ownerDocument.parentWindow.frameElement)
   parObj = parObj.ownerDocument.parentWindow.frameElement;
  else
   parObj = parObj.offsetParent;

 }
 //没有考虑框架中也有滚动条的情况
 mc.top +=  element.clientHeight+6;
 mc.left += 4;

 var date = element.value.createDate();
 mc.year = date.getFullYear();
 mc.month = date.getMonth();
 mc.day = date.getDate();
 writeCalendar(date);
 if(mc.isDynamicShow) timer = setTimeout(dynamicShow,mc.speed);
 else oPopup.show(mc.left, mc.top, mc.width,mc.height, document.body);

}
//动态显示控件
var timer = null;
function dynamicShow(){
 if(step > 15) { step = 1; clearTimeout(timer); return ;}
 else{
  if(mc.dynamicShow == "v")
   oPopup.show(mc.left, mc.top, mc.width,Math.floor(Math.sin(Math.PI*step/30)*mc.height), document.body);
  else
   oPopup.show(mc.left, mc.top, Math.floor(Math.sin(Math.PI*step/30)*mc.width),mc.height, document.body);
  step ++;
  timer = setTimeout(dynamicShow,mc.speed);
 }
}
//根据日期来改变控件的显示
function writeCalendar(date){
 //获得传入日期属性
 var tbRows = oPopup.document.getElementById("tbMxxCalendar").rows;
 var tdYear = tbRows[0].cells[2];
 var tdMonth = tbRows[0].cells[3];
 var year = date.getFullYear();
 var month = date.getMonth();
 if(mc.showTime){
  tbRows[7].cells[4].innerText = date.getHours().toString().replace(/^(/d)$/,"0$1");
  tbRows[7].cells[5].innerText = date.getMinutes().toString().replace(/^(/d)$/,"0$1");
  tbRows[7].cells[6].innerText = date.getSeconds().toString().replace(/^(/d)$/,"0$1");
 }
 //判断是否合法的年份
 //if(year > mc.maxYear || year <mc.minYear){ alert("超出设定的显示年份!"); return false;}
 //写入年月
 tdYear.innerText = year;
 tdMonth.innerText = eval(month+1).toString().replace(/^(/d)$/,"0$1");
 tdYear.title = "西元" +year + "年";
 tdMonth.title = eval(month+1) + "月";

 //返回当月1号日期
 date = new Date(year,month,1);
 //计算当前月1号的周数
 var week = date.getWeekNum();
 //计算该周第一天(周日)的日期
 date = new Date(year,month,date.getDate()-date.getDay());
 for(var i=2;i<8;i++){
  tbRows[i].cells[0].innerText = week;
  tbRows[i].cells[0].title = year + "年的第" + week++ + "周";
  for(var j=1,k=(i==7?(mc.showTime?4:7):8);j<k;j++){
   var tdTemp = tbRows[i].cells[j];
   tdTemp.innerText = date.getDate();
   tdTemp.id = "";
   tdTemp.title =date.getFullYear() + "/" + eval(date.getMonth()+1)+"/" + tdTemp.innerText;
   if(month != date.getMonth()) tdTemp.className = "notCurMonth";
   else if(mc.year == date.getFullYear() && mc.month == date.getMonth() && mc.day == date.getDate()) {
    tdTemp.id = "curDay";
    tdTemp.title += "(Enter or Space)";
    tdTemp.className = "curDay";
   }
   else tdTemp.className = "curMonth";
   date = date.dateAfter();
  }
 }
}
//年月改变事件
function chgDate(flag,num){
 var tbRows = oPopup.document.getElementById("tbMxxCalendar").rows;
 var year = parseInt(tbRows[0].cells[2].innerText,10);
 var month = parseInt(tbRows[0].cells[3].innerText,10)-1;
 var hour =parseInt(tbRows[7].cells[4].innerText,10);
 var minute =parseInt(tbRows[7].cells[5].innerText,10);
 var second =parseInt(tbRows[7].cells[6].innerText,10);
 var date =null;
 if(flag == "y") date = new Date(year+num,month,1);
 else if (flag == "m") date = new Date(year,month+num,1);
 else date = new Date();
 date.setHours(hour , minute, second);
 writeCalendar(date);
}

function addEvent(td){
   td.attachEvent("onmouseover",function(){ mc.curClassName = td.className; td.className = "tdOver"; });
   td.attachEvent("onmouseout",function(){td.className = mc.curClassName;});
   td.attachEvent("onclick",function(){
  var tbRows = oPopup.document.getElementById("tbMxxCalendar").rows;
  var style = mc.style;
  var date = new Date(td.title);
  if(mc.showTime){
   var hour =parseInt(tbRows[7].cells[4].innerText,10);
   var minute =parseInt(tbRows[7].cells[5].innerText,10);
   var second =parseInt(tbRows[7].cells[6].innerText,10);
   date.setHours(hour , minute, second)
   style += " hh:mi:ss";
  }
  element.value = date.parseString(style);
  oPopup.hide();
 });
}

var pp=null;
function initpp(){
 pp=oPopup.document.parentWindow.createPopup();
 var ppDoc = pp.document;
 var ppBody = pp.document.body;
 ppDoc.oncontextmenu = function (){ return false; };
 ppDoc.onselectstart = function (){ return false; };
 ppBody.style.overflow = "auto";
 var oStyleSheet=ppDoc.createStyleSheet();
 oStyleSheet.addRule("body", "background-color:#DEEAF6; border:solid #6BBFD9 1px; scrollbar-arrow-color:#000080; scrollbar-shadow-color:#DEEAF6; scrollbar-base-color:#DEEAF6; scrollbar-highlight-color:#DEEAF6;");
 oStyleSheet.addRule(".divNormal", "color:#000080; vertical-align:middle; font-size:12px; text-align: center; border:1px solid; border-color:  #FFFFFF  #D4D0C8 #D4D0C8 #FFFFFF ; width:100%; height:16; cursor:default;");
 oStyleSheet.addRule(".divOver", "color:#FFFFF1; background-color:#6BBFD9; vertical-align:middle; font-size:12px; text-align: center; border:1px solid; border-color:  #FFFFFF  #D4D0C8 #D4D0C8 #FFFFFF ; width:100%; height:16; cursor:default;");
 oStyleSheet.addRule(".divCurent", "color:#FF0000; background-color:#6BBFD9; vertical-align:middle; font-size:12px; text-align: center; border:1px solid; border-color:  #FFFFFF  #D4D0C8 #D4D0C8 #FFFFFF ; width:100%; height:16; cursor:default;");
}

function selectVal(obj,val){
 var start =0;
 var end = val;
 if(val ==0){ start =mc.minYear; end = mc.maxYear;}
 else if(val ==12){ start =1; end = 12;}
 var txt = obj.innerText;

 if(pp == null)  initpp();
 var ppDoc = pp.document;
 var ppBody = pp.document.body;
 ppBody.innerHTML="";
 for(var i=start;i<=end;i++){
  var newDiv = ppDoc.createElement('div');
  newDiv.id = "div"+i;
  newDiv.innerText = i;
  newDiv.className = "divNormal";
  divAttach(newDiv,obj,val);
  ppBody.appendChild(newDiv);
 }
 pp.show(mc.width+1, 0, 50, mc.height, oPopup.document.body);
 var divNow = ppDoc.getElementById("div"+parseInt(obj.innerText,10));
 if(divNow){
  divNow.scrollIntoView();
  divNow.className = "divCurent";
 }
}
function divAttach(newDiv,obj,val){
 newDiv.attachEvent("onmouseover",function(){
  newDiv.className = "divOver";
  });
 newDiv.attachEvent("onmouseout",function(){
  newDiv.className = "divNormal";
  });
 newDiv.attachEvent("onclick",function(){
  pp.hide();
  obj.innerText = newDiv.innerText.trim().replace(/^(/d)$/,"0$1");
  var data = parseInt(obj.innerText,10);
  var date = null;
  var tbRows = oPopup.document.getElementById("tbMxxCalendar").rows;
  var hour =parseInt(tbRows[7].cells[4].innerText,10);
  var minute =parseInt(tbRows[7].cells[5].innerText,10);
  var second =parseInt(tbRows[7].cells[6].innerText,10);
  if(val == 0){
   var month = parseInt(tbRows[0].cells[3].innerText,10)-1;
   date = new Date(data,month,1);
  }
  else if(val ==12){
   var year = parseInt(tbRows[0].cells[2].innerText,10);
   date = new Date(year,data-1,1);
  }
  else return false;
  date.setHours(hour , minute, second, 0);
  writeCalendar(date);
 });
}

String.prototype.trim = function(){return this.replace(/(^/s*)|(/s*$)/g,"");}
/*用相对不规则的字符串来创建日期对象,不规则的含义为:顺序包含年月日三个或者年月日时分秒六个数值串,有间隔
 *如果element.value非法,返回当前日期
 */
String.prototype.createDate = function(){
 if(this == "") return new Date();
 var regThree = /^/D*(/d{2,4})/D+(/d{1,2})/D+(/d{1,2})/D*$/;
 var regSix = /^/D*(/d{2,4})/D+(/d{1,2})/D+(/d{1,2})/D+(/d{1,2})/D+(/d{1,2})/D+(/d{1,2})/D*$/;
 var str = "";
 var date = null;
 if(regThree.test(this)){
  str = this.replace(//s/g,"").replace(regThree,"$1/$2/$3");
  date = new Date(str);
 }
 else if(regSix.test(this)){
  str = this.match(regSix);
  date = new Date(str[1],str[2]-1,str[3],str[4],str[5],str[6]);
 }
 else return new Date();
 return date;
}
//根据日期返回该日期所在年的周数
Date.prototype.getWeekNum = function (){
 var dat = new Date(this.getFullYear(),0,1);
 var week = dat.getDay();
 week = (week==0?7:week);
 var days = this.calDateDistance(dat)+1;
 return ((days + 6 - this.getDay() - 7 + week)/7);
}
/*功能:返回两日期之差
 *参数:date Date对象
 */
Date.prototype.calDateDistance = function (date){
 if(typeof(date) != "object" || !(/Date/.test(date.constructor)))
   throw new Error(-1,"calDateDistance参数为Date类型.");
 return num = (( this.valueOf()- date.valueOf())/86400000).fmtRtnVal(0);
}
//返回整数或者两位小数的浮点数
Number.prototype.fmtRtnVal = function (intOrFloat){
 return (intOrFloat == 0 ? Math.floor(this) : parseInt(this*100)/100);
}
/* 功能 : 返回下一天的日期
 * 返回 : 新的Date
 */
Date.prototype.dateAfter=function(){
 return new Date(this.valueOf() + 86400000);
}
/*
 * 功能:根据输入表达式返回日期字符串
 * 参数:dateFmt:字符串,由以下结构组成   
 *      yy:长写年,mm:数字月,dd:日,hh:时,mi:分,ss秒
*/
Date.prototype.parseString = function(dateFmt){
 dateFmt = (dateFmt == null?"yy-mm-dd" : dateFmt);
 if(typeof(dateFmt) != "string" )
  throw (new Error(-1, 'parseString()方法需要字符串类型参数!'));
 var str=dateFmt;
 str = str.replace(/yy/g,this.getFullYear());
 str = str.replace(/mm/g,(this.getMonth()+1));
 str = str.replace(/dd/g,this.getDate());
 str = str.replace(/hh/g,this.getHours());
 str = str.replace(/mi/g,this.getMinutes());
 str = str.replace(/ss/g,this.getSeconds());
 str = str.replace(/(/D)(/d)(?=/D|$)/g, "$10$2");
 return str;
}
</script>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值