var g_dayNumOfMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var g_cn_weekDays = ['日', '一', '二', '三', '四', '五', '六'];
var g_cn_months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
var g_en_weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var g_en_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var g_cal_div = '#_calendar_div';
var g_cn_format = function(year, month, day) {
month++;
return day ? (year + '-' + month + '-' + day) : (year + '-' + month);
};
var g_cn_parse = function(dtStr) {
var ss = dtStr.split('-');
var d = new Date();
d.setYear(parseInt(ss[0]));
d.setMonth(parseInt(ss[1]));
if(ss[2]) {
d.setDate(parseInt(ss[2]));
} else {
d.setDate(1);
}
return d;
};
var g_ok = function(checked) {
var htm = [];
for(var i in checked) {
htm.push(checked[i].year + '-' + (checked[i].month+1) + '-' + checked[i].day);
}
console.info(htm.join(''));
return true;
};
var cur = new Date();
var default_settings = {
lang:'cn',
weekDays: g_cn_weekDays,
months: g_cn_months,
target: '',
endTarget: '',
mode: 'single', /*range|single|multi*/
format: g_cn_format,
parse: g_cn_parse,
ok:g_ok,
year: cur.getFullYear(),
month: cur.getMonth(),
day: 0,
num:1
};
function isLeapYear(year) {
return ((year % 4 == 0 && year % 100 != 0) || (year % 400) == 0);
}
function isChecked(year, month, day, context) {
var one;
for(var i = 0, num = context.checked.length; i < num; i++) {
one = context.checked[i];
if(one.year == year && one.month == month && one.day == day) {
return true;
}
}
return false;
}
function getMonthName(context, month) {
return context.months[month%12];
}
function getWeekDayName(context, day) {
return context.weekDays[day % 7];
}
var g_contexts = {};
$.fn.calendar = function(settings) {
var context = {checked:[]};
$.extend(context, default_settings);
$.extend(context, settings);
if(context.lang == 'cn') {
context.weekDays = g_cn_weekDays;
context.months = g_cn_months;
} else {
context.weekDays = g_en_weekDays;
context.months = g_en_months;
}
if($(g_cal_div).size() <= 0) {
$('body').append('<div id="' + g_cal_div.substr(1) + '" class="calendar_body"/>');
}
g_contexts[context.target] = context; //record context into global
$(context.target).click({target:context.target}, function(event) {
var context = g_contexts[event.data.target];
if(context) {
genHtm(context)
}
});
function addCSS(css) {
$("<link>").attr({rel: "stylesheet", type: "text/css", href: css}).appendTo("head");
}
function genHtm(context) {
// get first day of month
var startDay = new Date(context.year, context.month, 1).getDay();
var target = context.target;
// find number of days in month
// compensate for leap year
var monthDayNum = g_dayNumOfMonth[context.month];
if (context.month == 1) { // February only!
if(isLeapYear(context.year)){
monthDayNum = 29;
}
}
// do the header
var htm = [];
if(context.mode != 'single') {
htm.push('<div style="height:16px;"><span class="calendar_close"></span></div>');
}
htm.push('<div style="margin:5px;">');
htm.push('<table class="calendar"><tr>'
,'<td style="text-align:left;"><span class="calendar_btn foreYear"></span>'
,' <span class="calendar_btn foreMonth"></span></td>'
,'<td align="center">', context.format(context.year, context.month)
,'</td><td style="text-align:right;"><span class="calendar_btn nextMonth"></span>'
,' <span class="calendar_btn nextYear"></span></td>'
,'</tr></table>');
htm.push('<table class="calendar"><tr>');
for(var i = 0; i < 7; i++ ){
htm.push('<th>', context.weekDays[i], '</th>');
}
htm.push('</tr>');
// fill in the days
var day = 0;
// this loop is for is weeks (rows)
for (var i = 0; i < 6 && day < monthDayNum; i++) {
htm.push('<tr>');
for (var j = 0; j < 7; j++) {
htm.push('<td>');
if (day < monthDayNum && (i > 0 || j >= startDay)) {
if (isChecked(context.year, context.month, day, context)) {
htm.push('<span class="calendar_day selectedDay">', day + 1, '</span>');
} else {
htm.push('<span class="calendar_day day" day="',day,'">', day + 1, '</span>');
}
day++;
}
htm.push('</td>');
}
htm.push('</tr>');
}
htm.push('</table>');
htm.push('</div>');
var calDiv = $(g_cal_div);
calDiv.html(htm.join(''));
calDiv.fadeIn();
$('span.calendar_btn.foreYear').click({target:target}, function(event) {
console.info(event.data.target);
var context = g_contexts[event.data.target];
if(context.year > 1900) {
context.year--;
genHtm(context);
}
});
$('span.calendar_btn.foreMonth').click({target:target}, function(event) {
var context = g_contexts[event.data.target];
if(context.month > 0) {
context.month--;
genHtm(context);
} else if(context.year > 1900){
context.month = 11;
context.year--;
genHtm(context);
}
});
$('span.calendar_btn.nextYear').click({target:target}, function(event) {
var context = g_contexts[event.data.target];
if(context.year < 2200) {
context.year++;
genHtm(context);
}
});
$('span.calendar_btn.nextMonth').click({target:target}, function(event) {
var context = g_contexts[event.data.target];
if(context.month < 11) {
context.month++;
genHtm(context);
} else if(context.year < 2200){
context.year++;
context.month = 0;
genHtm(context);
}
});
$('span.calendar_day.day').click({target:target}, function(event) {
var day = $(this).attr('day');
if(!day) {
return;
}
day = parseInt(day);
var context = g_contexts[event.data.target];
var one = {year:context.year, month:context.month, day:(day+1)};
if(context.mode == 'single') {
if(context.ok([one])) {
$(g_cal_div).fadeOut();
}
} else if(context.mode == 'multi') {
context.checked.push(one);
} else /*range*/{
context.checked.push(one);
if(context.checked.length > 1) {
context.ok(context.checked);
$(g_cal_div).fadeOut();
}
}
});
$('span.calendar_close').click({target:target}, function(event) {
var context = g_contexts[event.data.target];
if(context.ok(context.checked)) {
$(g_cal_div).fadeOut();
}
});
}
}
})(jQuery);
span.calendar_btn {line-height:0; margin:0; width:20px; height:20px; display: inline-block; vertical-align:middle;
border:0 none; cursor: pointer;outline:none;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
background-image:url("./tinycal.gif");
}
span.calendar_btn.foreMonth {background-position:0 0;}
span.calendar_btn.foreMonth:hover {background-position:-20px 0;}
span.calendar_btn.nextMonth {background-position:-40px 0;}
span.calendar_btn.nextMonth:hover {background-position:-60px 0;}
span.calendar_btn.foreYear {background-position:-80px 0;}
span.calendar_btn.foreYear:hover {background-position:-100px 0;}
span.calendar_btn.nextYear {background-position:-120px 0;}
span.calendar_btn.nextYear:hover {background-position:-140px 0;}
table.calendar {
border-collapse: separate;
border-spacing: 0;
padding:0;
width:100%;
}
table.calendar td,th {
text-align:center;
font-size:14px;
vertical-align:middle;
height:27px;
}
span.calendar_day {line-height:0; margin:0; width:24px; height:25px; vertical-align:middle;
border:0 none; cursor: pointer;display: table-cell;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
background-image:url("./tinycal.gif");
}
span.calendar_day.selectedDay {background-position:0 -20px;}
span.calendar_day.day {background-position:-24px -20px;}
span.calendar_day.day:hover {background-position:-48px -20px;}
span.calendar_day.curDay {background-position:-72px -20px;}
span.calendar_close {line-height:0; margin:0; width:33px; height:13px; vertical-align:middle;
border:0 none; cursor: pointer;display: table-cell;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
background-image:url("./tinycal.gif");
background-position:-96px -20px;
float:right;
}
span.calendar_close:hover {
background-position:-96px -33px;
}
.calendar_body {
display:none;
position:absolute;
width:250px;
height:260px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
border:1px solid ddd;
-webkit-box-shadow:0 0 5px black;
-moz-box-shadow:0 0 5px black;
border-style:outset;
}