jQuery.fn.calendar = function(date, options) {
var dayNames = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
var template = "
";
return this.each(function () {
var table = createTable(jQuery(this), date, options);
populateHeader(table);
populateBody(table);
populateCaption(table)
decorate(table);
});
function getFirstDateInMonth(date, firstDayOfWeek) {
var firstDate = new Date(date.getTime());
firstDate.setDate(1);
return getFirstDateInWeek(firstDate, firstDayOfWeek);
}
function getFirstDateInWeek(date, firstDayOfWeek) {
var dayOfWeek = date.getUTCDay();
if (dayOfWeek != firstDayOfWeek) {
date.setUTCDate(date.getUTCDate() - 1);
date = getFirstDateInWeek(date, firstDayOfWeek);
}
return date;
}
function createTable(predecessor, date, options) {
predecessor.after(template);
var table = predecessor.next();
table.data("date", new Date(date.getTime()));
if (options && options.className)
table.addClass(options.className);
table.data("firstDay", (options && options.firstDayOfWeek) ? options.firstDayOfWeek : 0);
table.data("days", (options && options.days) ? options.days : dayNames);
table.data("alwaysShowLast", (options && options.alwaysShowLastRow == true) ? true : false);
return table;
}
function populateHeader(table) {
var days = table.data("days");
var firstDay = table.data("firstDay");
var headerIndex = firstDay;
jQuery("th", table).each(function() {
var cell = jQuery(this);
cell.text(days[headerIndex++]);
if (headerIndex > 6)
headerIndex = 0;
});
}
function populateCaption(table) {
jQuery("caption", table).text(table.data("date").toUTCString());
}
function populateBody(table) {
var date = table.data("date");
var firstDay = table.data("firstDay");
var currentDate = getFirstDateInMonth(date, firstDay)
jQuery("td", table).each(function() {
jQuery(this)
.removeClass()
.data("date", new Date(currentDate.getTime()))
.text(currentDate.getUTCDate())
.addClass("dw" + currentDate.getUTCDay())
.addClass("d" + currentDate.getUTCDate())
.addClass("m" + currentDate.getUTCMonth())
.addClass("y" + currentDate.getUTCFullYear());
currentDate.setUTCDate(currentDate.getUTCDate() + 1);
});
}
function decorate(table) {
var date = table.data("date");
var currentDayStyle = ".d" + date.getUTCDate();
var currentMonthStyle = ".m" + date.getUTCMonth();
var currentYearStyle = ".y" + date.getUTCFullYear();
// Mark all months which are not part of the current month.
jQuery("td:not(" + currentMonthStyle + ")", table)
.addClass("other");
// Mark the current date.
jQuery("td" + currentDayStyle, table)
.filter(currentMonthStyle)
.filter(currentYearStyle)
.addClass("selected");
// If the last row is not being used, hide it unless instructed otherwise.
// The last row is unused if its first cell is empty.
var lastRow = jQuery("tr:last", table);
if (table.data("alwaysShowLast") || !jQuery("td:first", lastRow).is(".other"))
lastRow.show();
else
lastRow.hide();
}
};