/*
bootstrap_calendar by bic.cat (http://bic.cat) & xero (http://xero.nu)
https://github.com/xero/bootstrap_calendar
released open source under the Apache License
*/
$.fn.calendar = function(options) {
var args = $.extend({}, $.fn.calendar.defaults, options);
this.each(function(){
var calendar;
var lblDaysMonth;
var lblTextMonth = $('
');
var calendar_id = "cal_" + Math.floor(Math.random()*99999).toString(36);
var events = args.events;
var days;
if ( typeof args.days != "undefined" )
days = args.days;
else
days = ["S", "M", "T", "W", "T", "F", "S"];
var months;
if ( typeof args.months != "undefined" )
months = args.months;
else
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var show_days;
if ( typeof args.show_days != "undefined" )
show_days = args.show_days;
else
show_days = true;
var popover_options;
if ( args.popover_options != "undefined" )
popover_options = args.popover_options;
else
popover_options = {placement: 'top'};
var tooltip_options;
if ( typeof args.tooltip_options != "undefined" )
tooltip_options = args.tooltip_options;
else
tooltip_options = {placement: 'top'};
var req_ajax;
if ( typeof args.req_ajax != "undefined" )
req_ajax = args.req_ajax;
else
req_ajax = false;
var elem = $(this);
showCalendar();
/*** functions ***/
//display
function showCalendar(){
//days of month label
lblDaysMonth = $('');
list_week();
//date calculation object
var dateObj = new Date();
//check for date input
var dateText = elem.val();
if (dateText!= ""){
if (validateDate(dateText)){
var dateTextArray = dateText.split("/");
//two digit years
if(dateTextArray[2].length == 2){
if (dateTextArray[2].charAt(0)=="0"){
dateTextArray[2] = dateTextArray[2].substring(1);
}
dateTextArray[2] = parseInt(dateTextArray[2]);
if (dateTextArray[2] < 50)
dateTextArray[2] += 2000;
}
dateObj = new Date(dateTextArray[2], dateTextArray[1]-1, dateTextArray[0])
}
}
//current month & year
var month = dateObj.getMonth();
var year = dateObj.getFullYear();
showDaysOfMonth(month, year);
//next/previous month controls
var btnNextMonth = $(' | ');
btnNextMonth.click(function(e){
e.stopPropagation();
e.preventDefault();
month = (month + 1) % 12;
if (month==0)
year++;
change_month(month, year);
});
var btnPrevMonth = $(' | ');
btnPrevMonth.click(function(e){
e.stopPropagation();
e.preventDefault();
month = (month - 1);
if (month==-1){
year--;
month = 11;
}
change_month(month, year);
});
$('.icon-arrow-left').css('cursor', 'pointer');
$('.icon-arrow-right').css('cursor', 'pointer');
//current year & month label
var lblDate = $('');
var lblDateControl = $(' | ');
lblDate.append(btnPrevMonth);
lblDate.append(lblDateControl);
lblDate.append(btnNextMonth);
lblDateControl.append(lblTextMonth);
calendar = $('');
calendar.prepend(lblDate);
//calendar.append(lblWeek);
//lblDaysMonth.prepend(lblWeek);
calendar.append(lblDaysMonth);
//render calendar
elem.append(calendar);
check_events(month, year);
}
function change_month(month, year){
lblDaysMonth.empty();
list_week();
showDaysOfMonth(month, year);
check_events(month, year);
}
//week
function list_week(){
if ( show_days != false ){
var lblWeek = $('');
var insertCode = '';
$(days).each(function(key, value){
insertCode += '" + value + ' | ';
});
insertCode += '
';
lblWeek.append(insertCode);
lblDaysMonth.append(lblWeek);
}
}
function showDaysOfMonth(month, year){
//console.log("show (month, year): ", month, " ", year)
lblTextMonth.text(months[month] + " " + year);
//days of month
var day_counter = 1;
var firstDay = calculateWeekday(1, month, year);
var lastDaymonth = lastDay(month,year);
var next_month = month + 1;
var lblDaysMonth_string = "";
//render first row of week
for (var i=0; i<7; i++){
if (i < firstDay){
var dayCode = "";
if (i == 0)
dayCode += "";
//if the day of the week is less than the number of the first day of the week do not put anything in the cell
dayCode += ' | ';
} else {
var dayCode = "";
if (i == 0)
dayCode += '
';
dayCode += '' + day_counter + '';
if (i == 6)
dayCode += ' |
';
day_counter++;
}
lblDaysMonth_string += dayCode
}
//rest of month
var currentWeekDay = 1;
while (day_counter <= lastDaymonth){
var dayCode = "";
if (currentWeekDay % 7 == 1)
dayCode += "";
dayCode += '' + day_counter + ' | ';
if (currentWeekDay % 7 == 0)
dayCode += "
";
day_counter++;
currentWeekDay++;
lblDaysMonth_string += dayCode
}
//fill empty days
currentWeekDay--;
if (currentWeekDay%7!=0){
dayCode = "";
for (var i=(currentWeekDay%7)+1; i<=7; i++){
var dayCode = "";
dayCode += ' | ';
if (i==7)
dayCode += ''
lblDaysMonth_string += dayCode
}
}
lblDaysMonth.append( lblDaysMonth_string );
}
//calcuation number of days in week
function calculateWeekday(day,month,year){
var dateObj = new Date(year, month, day);
var numDay = dateObj.getDay();
return numDay;
}
//date validation
function checkdate (m, d, y) {
// function by http://kevin.vanzonneveld.net
// extracted from the manual phpjs.org libraries at http://www.desarrolloweb.com/manuales/manual-librerias-phpjs.html
return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
}
//calculate last day of month for a given year
function lastDay(month,year){
var last_day=28;
while (checkdate(month+1,last_day + 1,year)){
last_day++;
}
return last_day;
}
function validateDate(date){
var dateArray = date.split("/");
if (dateArray.length!=3)
return false;
return checkdate(dateArray[1], dateArray[0], dateArray[2]);
}
function check_events(month, year){
if (req_ajax != false){
$.ajax({
type: req_ajax.type,
url: req_ajax.url,
data: { month: month + 1, year: year },
dataType: 'json'
}).done(function( data ) {
events = [];
$.each(data, function(k,v){
events.push(data[k]);
});
markEvents(month, year);
});
} else {
markEvents(month, year);
}
}
function markEvents(month, year){
var t_month = month + 1;
for(var i=0; i< events.length; i++) {
if ( events[i][0].split('/')[1] == t_month && events[i][0].split('/')[2] == year ){
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event');
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-original-title', events[i][1]);
//bg
if ( events[i][3] ){
var e = $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") );
e.append('').find('span').css('background', events[i][3]);
}
//link
if ( events[i][2] == '' || events[i][2] == '#' ){
if ( events[i][4] != '' ){
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-trigger', 'manual');
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).addClass('manual_popover');
} else {
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('href', 'javascript:false;');
}
} else {
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('href', events[i][2]);
}
//tooltip vs popover
if ( events[i][4] ){
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event_popover');
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('rel', 'popover');
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-content', events[i][4]);
} else {
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event_tooltip');
$('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('rel', 'tooltip');
}
}
}
$('#' + calendar_id + ' ' + '.event_tooltip a').tooltip(tooltip_options);
$('#' + calendar_id + ' ' + '.event_popover a').popover(popover_options);
$('.manual_popover').click( function(){
$(this).popover('toggle');
} );
}
/*** --functions-- ***/
});
return this;
};