/* * Bic Calendar - v3.2.2 * A simple twitter bootstrap calendar / agenda to mark events and select range of dates. * http://bichotll.github.io/bic_calendar * * Made by bichotll * Under Apache License */ $.fn.bic_calendar = function(options) { var opts = $.extend({}, $.fn.bic_calendar.defaults, options); this.each(function() { /*** vars ***/ //element called var elem = $(this); var calendar; var daysMonthLayer; var textMonthCurrentLayer = $('
'); var textYearCurrentLayer = $('
'); var calendarId = "bic_calendar"; var events = opts.events; var callback = opts.callback; //Date obj to calc the day var objFecha; if (opts.date) { if (typeof opts.date == 'string') { var arrayDate = opts.date.split('/'); objFecha = new Date(parseInt(arrayDate[2]), parseInt(arrayDate[1]) - 1, parseInt(arrayDate[0])); } else { objFecha = opts.date; } } else { objFecha = new Date(); } var dayNames; if (typeof opts.dayNames != "undefined") dayNames = opts.dayNames; else dayNames = ["l", "m", "x", "j", "v", "s", "d"]; var monthNames; if (typeof opts.monthNames != "undefined") monthNames = opts.monthNames; else monthNames = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]; var showDays; if (typeof opts.showDays != "undefined") showDays = opts.showDays; else showDays = true; var popoverOptions; if (typeof opts.popoverOptions != "undefined") popoverOptions = opts.popoverOptions; else popoverOptions = {placement: 'bottom', html: true, trigger: 'hover'}; var tooltipOptions; if (typeof opts.tooltipOptions != "undefined") tooltipOptions = opts.tooltipOptions; else tooltipOptions = {placement: 'bottom', trigger: 'hover'}; var reqAjax; if (typeof opts.reqAjax != "undefined") reqAjax = opts.reqAjax; else reqAjax = false; var enableSelect = false; if (typeof opts.enableSelect != 'undefined') enableSelect = opts.enableSelect; var multiSelect = false; if (typeof opts.multiSelect != 'undefined') multiSelect = opts.multiSelect; var displayMonthController = true; if (typeof opts.displayMonthController != 'undefined') displayMonthController = opts.displayMonthController; var displayYearController = true; if (typeof opts.displayYearController != 'undefined') displayYearController = opts.displayYearController; var startWeekDay = 0; if (typeof opts.startWeekDay != 'undefined') startWeekDay = opts.startWeekDay; var firstDaySelected = ''; var lastDaySelected = ''; var daySelected = ''; /*** --vars-- ***/ /*** functions ***/ /** * init n print calendar */ function showCalendar() { //layer with the days of the month (literals) daysMonthLayer = $(''); listListeralsWeek(); //current year n current month var month = objFecha.getMonth(); var year = objFecha.getFullYear(); //show the days of the month n year configured showMonthDays(month, year); //next-previous month controllers var nextMonthButton = $(''); //event nextMonthButton.click(function(e) { e.preventDefault(); month = (month + 1) % 12; if (month == 0) year++; changeDate(month, year); }) var previousMonthButton = $(''); //event previousMonthButton.click(function(e) { e.preventDefault(); month = (month - 1); if (month == -1) { year--; month = 11; } changeDate(month, year); }) //next-previous year controllers var nextYearButton = $(''); //event nextYearButton.click(function(e) { e.preventDefault(); year++; changeDate(month, year); }) var previousYearButton = $(''); //event previousYearButton.click(function(e) { e.preventDefault(); year--; changeDate(month, year); }) //show the current year n current month text layer var headerLayer = $('
'); if (displayYearController === true) { var yearTextLayer = $(''); var yearControlTextLayer = $(''); yearTextLayer.append(previousYearButton); yearTextLayer.append(yearControlTextLayer); yearTextLayer.append(nextYearButton); yearControlTextLayer.append(textYearCurrentLayer); headerLayer.append(yearTextLayer); } if (displayMonthController === true) { var monthTextLayer = $(''); var monthControlTextLayer = $(''); monthTextLayer.append(previousMonthButton); monthTextLayer.append(monthControlTextLayer); monthTextLayer.append(nextMonthButton); monthControlTextLayer.append(textMonthCurrentLayer); headerLayer.append(monthTextLayer); } //calendar n border calendar = $('
'); calendar.prepend(headerLayer); //calendar.append(capaDiasSemana); //daysMonthLayer.prepend(capaDiasSemana); calendar.append(daysMonthLayer); //insert calendar in the document elem.append(calendar); //check and add events checkEvents(month, year); //if enable select checkIfEnableMark(); } /** * indeed, change month or year */ function changeDate(month, year) { daysMonthLayer.empty(); listListeralsWeek(); showMonthDays(month, year); checkEvents(month, year); markSelectedDays(); } /** * show literals of the week */ function listListeralsWeek() { if (showDays != false) { var capaDiasSemana = $(''); var codigoInsertar = ''; $(dayNames).each(function(indice, valor) { codigoInsertar += ''; }); codigoInsertar += ''; capaDiasSemana.append(codigoInsertar); daysMonthLayer.append(capaDiasSemana); } } /** * show the days of the month */ function showMonthDays(month, year) { //print year n month in layers textMonthCurrentLayer.text(monthNames[month]); textYearCurrentLayer.text(year); //show days of the month var daysCounter = 1; //calc the date of the first day of this month var firstDay = calcNumberDayWeek(1, month, year); //calc the last day of this month var lastDayMonth = lastDay(month, year); var nMonth = month + 1; var daysMonthLayerString = ""; //print the first row of the week for (var i = 0; i < 7; i++) { if (i < firstDay) { var dayCode = ""; if (i == 0) dayCode += ""; //add weekDay dayCode += ''; if (i == 6) dayCode += ''; daysCounter++; } daysMonthLayerString += dayCode } //check all the other days until end of the month var currentWeekDay = 1; while (daysCounter <= lastDayMonth) { var dayCode = ""; if (currentWeekDay % 7 == 1) dayCode += ""; dayCode += ''; if (currentWeekDay % 7 == 0) dayCode += ""; daysCounter++; currentWeekDay++; daysMonthLayerString += dayCode } //check if the empty cells it have yet to write of the last week of the month currentWeekDay--; if (currentWeekDay % 7 != 0) { dayCode = ""; for (var i = (currentWeekDay % 7) + 1; i <= 7; i++) { var dayCode = ""; dayCode += ' 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate(); } /** * return last day of a date (month n year) */ function lastDay(month, year) { var lastDayValue = 28; while (checkDate(month + 1, lastDayValue + 1, year)) { lastDayValue++; } return lastDayValue; } function validateWritedDate(fecha) { var arrayFecha = fecha.split("/"); if (arrayFecha.length != 3) return false; return checkDate(arrayFecha[1], arrayFecha[0], arrayFecha[2]); } /** * check if there are ajax events */ function checkEvents(month, year) { if (reqAjax != false) { $('#calendari_lateral_container .calendar_loading').show(); //peticio ajax $.ajax({ type: reqAjax.type, url: reqAjax.url, data: {mes: month + 1, ano: year}, dataType: 'json' }).done(function(data) { if (typeof events == 'undefined') events = []; $.each(data, function(k, v) { events.push(data[k]); }); markEvents(month, year); if (typeof callback == 'function') { // make sure the callback is a function callback.call(this); // brings the scope to the callback } }); } else { this.markEvents(month, year); } } /** * mark all the events n create logic for them */ function markEvents(month, year) { var temporalMonth = month + 1; for (var i = 0; i < events.length; i++) { if (events[i].date.split('/')[1] == temporalMonth && events[i].date.split('/')[2] == year) { var loopDayTd = $('#' + calendarId + '_' + events[i].date.replace(/\//g, "_")); var loopDayA = $('#' + calendarId + '_' + events[i].date.replace(/\//g, "_") + ' a'); loopDayTd.addClass('event'); loopDayA.attr('data-original-title', events[i].title); //bg color if (events[i].color) loopDayTd.css('background', events[i].color); //link if (typeof events[i].link != 'undefined' && events[i].link != '') { loopDayA.attr('href', events[i].link); } if (typeof events[i].linkTarget != 'undefined' && events[i].linkTarget != '') { loopDayA.attr('target', events[i].linkTarget); } //class if (events[i].class) loopDayTd.addClass(events[i].class); //tooltip vs popover if (events[i].content) { loopDayTd.addClass('event_popover'); loopDayA.attr('rel', 'popover'); loopDayA.attr('data-content', events[i].content); } else { loopDayTd.addClass('event_tooltip'); loopDayA.attr('rel', 'tooltip'); } } } $('#' + calendarId + ' ' + '.event_tooltip a').tooltip(tooltipOptions); $('#' + calendarId + ' ' + '.event_popover a').popover(popoverOptions); $('.manual_popover').click(function() { $(this).popover('toggle'); }); } /** * check if the user can mark days */ function checkIfEnableMark() { if (enableSelect == true) { var eventBicCalendarSelect; elem.on('click', '#' + calendarId + ' td.day', function() { //if multiSelect if (multiSelect == true) { if (daySelected == '') { daySelected = $(this).data('date'); this.markSelectedDays(); } else { if (lastDaySelected == '') { //set firstDaySelected firstDaySelected = daySelected; lastDaySelected = $(this).data('date'); this.markSelectedDays(); //create n fire event //to change var eventBicCalendarSelect = new CustomEvent("bicCalendarSelect", { detail: { dateFirst: firstDaySelected, dateLast: lastDaySelected } }); document.dispatchEvent(eventBicCalendarSelect); } else { firstDaySelected = ''; lastDaySelected = ''; daySelected = ''; elem.find('.selection').removeClass('middle-selection selection first-selection last-selection'); } } } else { //remove the class selection of the others a elem.find('td div').removeClass('selection'); //add class selection $(this).find('div').addClass('selection'); //create n fire event var eventBicCalendarSelect = new CustomEvent("bicCalendarSelect", { detail: { date: $(this).data('date') } }); document.dispatchEvent(eventBicCalendarSelect); } }) } } /** * to mark selected dates */ function markSelectedDays() { if (daySelected != '' && firstDaySelected == '') { var arrayDate = daySelected.split('/'); $('#' + calendarId + '_' + arrayDate[1] + '_' + arrayDate[0] + '_' + arrayDate[2] + ' div').addClass('selection'); } else if (firstDaySelected != '') { //create array from dates var arrayFirstDay = firstDaySelected.split('/'); var arrayLastDay = lastDaySelected.split('/'); //remove all selected classes elem.find('td.selection').removeClass('selection'); //create date object from dates var oldSelectedDate = new Date(firstDaySelected); var newSelectedDate = new Date(lastDaySelected); //create a loop adding day per loop to set days //turn dates if > if (oldSelectedDate > newSelectedDate) { //turn vars date var tempSelectedDate = oldSelectedDate; oldSelectedDate = newSelectedDate; newSelectedDate = tempSelectedDate; } //set first selection $('#' + calendarId + '_' + oldSelectedDate.getDate() + '_' + (parseInt(oldSelectedDate.getMonth()) + 1) + '_' + oldSelectedDate.getFullYear() + ' div').addClass('selection first-selection'); while (oldSelectedDate < newSelectedDate) { oldSelectedDate.setDate(oldSelectedDate.getDate() + 1); //set middle-selection $('#' + calendarId + '_' + oldSelectedDate.getDate() + '_' + (parseInt(oldSelectedDate.getMonth()) + 1) + '_' + oldSelectedDate.getFullYear() + ' div').addClass('selection middle-selection'); } //set last selection $('#' + calendarId + '_' + oldSelectedDate.getDate() + '_' + (parseInt(oldSelectedDate.getMonth()) + 1) + '_' + oldSelectedDate.getFullYear() + ' div').removeClass('middle-selection').addClass('selection last-selection'); } } /*** --functions-- ***/ //fire calendar! showCalendar(); }); return this; };