<style type="text/css"> .calender_tb{ border:1px solid black; border-collapse:collapse; background-color:lightblue; font-family:'宋体'; font-size:90%; width:180px; height:180px; } .calender_tb tr td{ margin:0px; padding:1px; cursor:pointer; border:none; text-align:center; white-space: nowrap; } .calender_tb caption{ background-color:#CCCC99; border-top:1px solid black; border-left:1px solid black; border-right:1px solid black; font-size:120%; } .calender_tb tr.calender_nav{ height:25px; border:1px solid black; white-space: nowrap; background-color:#ccc; } .calender_tb tr.calender_nav td{ border:none; } .calender_tb th{ border-top:1px solid black; border-left:1px solid black; border-right:1px solid black; border:none; } .calender_tb tr.calendar_time td.disabled_td { overflow:hidden; color:#666; } .calender_tb .disabled_td{ color:#666; } .calender_tb .invalid_td{ color:#666; } .today{ background-color:blue; color:#fff; } .calender_tb tbody tr td.td_mouse_over{ color:blue; background-color:yellow; } .calendar_time{ border-top:1px solid black; } </style>
var shawn = {}; /** * @param cfg 配置项 * @author shawn * @version 1.0 * */ shawn.Calendar = function(cfg){ this.renderTo = null; this.now = new Date(); this.id = "shawn_table_" + this.genId++; this.multi = false; this.lang = 'zh'; this.autoFix = true; this.dateOnly = true; if(Object.prototype.toString.call(cfg) == '[object Date]'){ this.value = cfg; }else if(Object.prototype.toString.call(cfg) == '[object Object]'){ this.value = cfg.value || new Date(); this.multi = cfg.multi || false; this.lang = cfg.lang || 'zh'; this.minValue = cfg.minValue || null; this.maxValue = cfg.maxValue || null; this.id = cfg.id || this.id; this.renderTo = typeof cfg.renderTo == 'string' ?document.getElementById(cfg.renderTo):cfg.renderTo ; this.autoFix = cfg.autoFix === false ? false : true; this.dateOnly = cfg.dateOnly === false ? false : true; this.callbackFn = cfg.callbackFn; } this.init(); } shawn.Calendar.prototype = { genId: 0, format:'YYYY-MM-DD hh:mm:ss', dateTimeReg: /^([12]\d{3})-(0[1-9]|1[0-2])-([0-2]\d|3[0-1])\s([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/, dateReg: /^([12]\d{3})-(0[1-9]|1[0-2])-([0-2]\d|3[0-1])$/, timeReg:/^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/, language:{ zh:{ ths:['日','一','二','三','四','五','六'], year:'年', month:'月', now:'今天'}, en:{ ths:['Sun','Mon','Tue','Wen','Ths','Fri','Sat'], year:'/', month:'/', now:'Today'} }, baseJudge:function(){ if(navigator.appName.indexOf('Microsoft')>-1){ this.isIE = true; }else{ this.isIE = false; } }, initValue:function(){ if(typeof this.value == 'string'){ var result = this.value.match(this.dateTimeReg); if(result != null){ this.value = new Date(result[1],result[2]-1,result[3],result[4],result[5],result[6]); }else{ result = this.value.match(this.dateReg); if(result != null){ this.value = new Date(); this.value.setFullYear(result[1]); this.value.setMonth(result[2]-1); this.value.setDate(result[3]); }else{ this.value = new Date(); } } }else if(Object.prototype.toString.call(this.value) == '[object Date]'){ }else{ this.value = new Date(); } this.day = this.value.getDay(); this.fullYear = this.value.getFullYear(); this.month = this.value.getMonth() + 1; this.date = this.value.getDate(); this.hour = this.value.getHours(); this.min = this.value.getMinutes(); this.sec = this.value.getSeconds(); }, init: function(){ this.baseJudge(); this.initValue(); this.createTable(); }, createThs:function(){ var ths = "<tr>"; var ths_zh = this.language[this.lang].ths; for(var i=0;i<7;i++){ ths+="<th>" + ths_zh[i] + "</th>"; } ths += "</tr>"; return ths; }, createTbody:function(){ var maxDay = this.getMaxDay(this.fullYear,this.month); var startDay = new Date(this.fullYear,this.month-1,1).getDay(); var min = new Date(1970,0,1); var max = new Date(2999,11,31); var tmp = null; if(this.minValue){ tmp = this.minValue.split('-'); min = new Date(tmp[0],tmp[1]-1,tmp[2]); if(Object.prototype.valueOf.call(min) == 'Invalid Date' || Object.prototype.valueOf.call(min) == 'NaN' ){ min = new Date(1970,0,1); } } if(this.maxValue){ tmp = this.maxValue.split('-'); max = new Date(tmp[0],tmp[1]-1,tmp[2]); if(Object.prototype.valueOf.call(max) == 'Invalid Date' || Object.prototype.valueOf.call(max) == 'NaN' ){ max = new Date(2999,11,31); } } var tds = "",trs=""; if(this.multi){ var preMaxDay = this.getMaxDay(this.fullYear,this.month-1); for(var j=0;j<startDay;j++){ tds = tds + '<td class="disabled_td">' +(preMaxDay-startDay+j+1) + '</td>'; } }else{ for(var j=0;j<startDay;j++){ tds += '<td class="disabled_td"> </td>'; } } var j=1; for(var i=1 ;(i + startDay)<= 42; i++){ if((i+startDay-1)%7 == 0){ trs = trs + '<tr>' + tds + '</tr>'; tds = ""; } if(i == this.date){ tmp = new Date(this.value.getFullYear(),this.value.getMonth(),i); if(tmp < min || tmp > max){ tds = tds + '<td class="today invalid_td">'+ i + '</td>'; }else{ tds = tds + '<td class="today">'+ i + '</td>'; } }else if(i<=maxDay){ tmp = new Date(this.value.getFullYear(),this.value.getMonth(),i); if(tmp < min || tmp > max){ tds = tds + '<td class="invalid_td">'+ i + '</td>'; }else{ tds = tds + '<td>'+ i + '</td>'; } }else{ if(this.multi){ tds = tds + '<td class="disabled_td">' +(j++) +'</td>'; }else{ tds = tds + '<td class="disabled_td"> </td>'; } } } trs = trs + "<tr>" + tds + "</tr>"; return trs; }, getMaxDay:function(year,month){ var maxDay = 0; var leap = (year%400 == 0 || (year%4 == 0 && year%100 !=0)); if(leap && month == 2){ maxDay = 29; }else if(month == 2){ maxDay = 28; }else if("1,3,5,7,8,10,12,".indexOf(month + ",") == -1){ maxDay = 30; }else{ maxDay = 31; } return maxDay; }, createNav:function(){ return '<tr class="calender_nav">' + '<td><<</td>' + '<td><</td>' + '<td colspan="3" class="disabled_td_">' //+this.language[this.lang].now + this.fullYear + this.language[this.lang].year + this.month + this.language[this.lang].month +'</td>' + '<td>></td>' + '<td>>></td></tr>' }, createHours:function(){ var str = ''; for(var i=0;i<=23;i++){ if(i == this.hour){ str +='<option value="'+ i +'" selected="selected">' + i + '</option>'; }else{ str +='<option value="'+ i +'">' + i + '</option>'; } } return '<select name="hour">' + str + '</select>'; }, createMinutes:function(){ var str = ''; for(var i=0;i<=59;i++){ if(i == this.min){ str +='<option value="'+ i +'" selected="selected">' + i + '</option>'; }else{ str +='<option value="'+ i +'">' + i + '</option>'; } } return '<select name="min">' + str + '</select>'; }, createSeconds:function(){ var str = ''; for(var i=0;i<=59;i++){ if(i == this.sec){ str +='<option value="'+ i +'" selected="selected">' + i + '</option>'; }else{ str +='<option value="'+ i +'">' + i + '</option>'; } } return '<select name="sec">' + str + '</select>'; }, fixSelect:function(){ var tb = document.getElementById(this.id); var inputs = tb.getElementsByTagName('select'); if(this.isIE){ var computedStyle = tb.currentStyle; }else{ var computedStyle = document.defaultView.getComputedStyle(tb, null); } var i = 0; var width = parseInt(computedStyle.width); // var height = parseInt(computedStyle.height); while(inputs[i]){ inputs[i].style.width = Math.floor(2*width/9) + 'px'; // inputs[i].style.height = Math.floor(height/7) + 'px'; i++; } }, createTime:function(){ return '<tr class="calendar_time">' + '<td class="disabled_td" colspan="7"> ' + this.createHours() + ":" + this.createMinutes() + ":" + this.createSeconds() + '</td></tr>' }, createTable:function(){ var table = ['<table id="'+ this.id + '" class="calender_tb">',"</table>"]; var thead = ["<thead>","</thead>"]; var tbody = ['<tbody>',"</tbody>"]; var timeField = this.dateOnly == true?'':this.createTime(); this.output = table[0] + thead[0] + this.createNav() + this.createThs() + thead[1] + tbody[0] + this.createTbody() + timeField + tbody[1] + table[1]; }, show: function(){ if(this.renderTo == null){ this.renderTo = document.createElement("DIV"); this.renderTo.id = "calendar" + this.id; document.body.appendChild(this.renderTo); document.getElementById(this.renderTo.id).innerHTML = this.output; } else{ document.getElementById(this.renderTo.id).innerHTML = this.output; } this.output = '' this.addListeners(); if(this.autoFix && this.dateOnly ==false){ this.fixSelect(); } }, render: function(target){ this.renderTo = target; }, getValue:function(){ var tb = document.getElementById(this.id); var selects = tb.getElementsByTagName('select'); var i = 0,hour=0,min=0,sec=0; while(selects[i]){ if(selects[i].name == 'hour'){ hour = selects[i].value; }else if(selects[i].name == 'min'){ min = selects[i].value; }else if(selects[i].name == 'sec'){ sec = selects[i].value; } i++; } return new Date(this.fullYear,this.month,this.date,hour,min,sec); }, nextMonth: function(){ this.value = new Date(this.fullYear,this.month,this.date); this._update(); }, previousMonth: function(){ this.value = new Date(this.fullYear,this.month-2,this.date); this._update(); }, _update:function(){ this.removeListeners(); document.getElementById(this.renderTo.id).innerHTML = ''; this.initValue(); this.createTable(); this.show(); }, nextYear: function(){ this.value = new Date(this.fullYear+1,this.month-1,this.date); this._update(); }, previousYear: function(){ this.value = new Date(this.fullYear-1,this.month-1,this.date); this._update(); }, restore:function(){ this.value = new Date(); this._update(); }, addListeners:function(){ var that = this; if(!this.eventObj){ this.eventObj = {}; } function clickFn(e){ e = e || window.event; var target = e.srcElement || e.target; if(target.tagName && target.tagName.toLowerCase() == 'td'){ if(target.className.indexOf("disabled_td") == -1 && target.className.indexOf("invalid_td") == -1 ){ switch(target.innerHTML){ case "<":that.previousMonth();break; case "<<" :that.previousYear();break; case ">":that.nextMonth();break; case ">>":that.nextYear();break; case that.language[that.lang].now:that.restore();break; default:{ that.selectedDay = parseInt(target.innerHTML); if(!isNaN(that.selectedDay)){ that.callbackFn.call(window,that.getValue()) } } } } } } function mouseoverFn(e){ e = e || window.event; var target = e.srcElement || e.target; if(target.tagName.toLowerCase() == 'td'){ if(target.className.indexOf("disabled_td") == -1 && target.className.indexOf("invalid_td") == -1 ){ target.className = target.className + ' td_mouse_over '; } } } function mouseoutFn(e){ e = e || window.event; var target = e.srcElement || e.target; if(target.tagName.toLowerCase() == 'td'){ if(target.className.indexOf("disabled_td") == -1 && target.className.indexOf("invalid_td") == -1 ){ target.className = target.className.replace(/\s*td_mouse_over\s*/,''); } } } this.eventObj.click = clickFn; this.eventObj.mouseover = mouseoverFn; this.eventObj.mouseout = mouseoutFn; if(this.isIE){ this.renderTo.attachEvent('onclick',clickFn); this.renderTo.attachEvent('onmouseover',mouseoverFn); this.renderTo.attachEvent('onmouseout',mouseoutFn); }else{ this.renderTo.addEventListener('click',clickFn,false); this.renderTo.addEventListener('mouseover',mouseoverFn,false); this.renderTo.addEventListener('mouseout',mouseoutFn,false); } }, removeListeners:function(){ if(this.eventObj){ for(name in this.eventObj){ if(this.isIE){ this.renderTo.detachEvent('on' + name,this.eventObj[name]); }else { this.renderTo.removeEventListener(name,this.eventObj[name],false); } } } } } //示例: function go(){ var cal = new shawn.Calendar({ renderTo:'str2', dateOnly:false, value: '2010-09-09 12:12:12', // minValue:'2010-12-15', // maxValue: '2011-2-1', multi:true, //lang:'en', callbackFn:function(val){ alert('Value is ' + val.toLocaleString()); } }).show(); }