<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();
}
[img]http://dl.iteye.com/upload/attachment/366944/de8fa58f-0271-3f57-b9cc-d4402c2390eb.bmp[/img]