var calendar = {
items: new Array(),
init: function(config){
var c = {
title: 'Calendar',
fieldId: "myDate",
showButton: false,
buttonId: "myDateButton",
buttonIcon: "",
onlyFutureEnabled: false,
currentDateEnabled: true,
activateOnFocus: true,
validateOnBlur: false,
errorClass: "red",
layerClass: "ac-layer",
transImage: "",
daysNames: { EU: new Array('Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'), US: new Array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa')},
monthsNames: { EU: new Array('Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli','August', 'September', 'Oktober', 'November', 'Dezember'), US: new Array('Januar', 'Februar', 'March', 'April', 'May', 'June', 'July','August', 'September', 'Oktober', 'November', 'December')},
form: 'EU', // 'US'
position: 'topRight', //bottomLeft
calendarLayer: null,
isDateValid: false,
positionDeltaTop: 3,
positionDeltaLeft: 20,
range: {
from: null,
upto: null
},
defaultDate: null
},
c = jQuery.extend(c, config);
//Ob das Element schon mal initialisiert wurde
var itemIndex = null;
for (var i in this.items) {
if (this.items[i].fieldId == c.fieldId) itemIndex = i;
}
if (itemIndex == null) this.items.push(c);
else this.items[i] = c;
//Button container
var buttonObj = jQuery('#'+c.buttonId).get(0);
if (jQuery('#'+c.fieldId).get(0)!=null) {
//Show button
if ( (c.showButton) && ( buttonObj!= null) ) {
buttonObj.innerHTML = '
';
}
//Events
var calender = this;
//Field
jQuery('#'+c.fieldId).unbind('focus').bind('focus', function(){ calender.onFocus(c); });
jQuery('#'+c.fieldId).unbind('blur').bind('blur', function(){ calender.onBlur(c); });
//Button
jQuery('#'+c.buttonId).unbind('click').bind('click', function(){ calender.onClick(c); });
}
},
onFocus: function(c){
if (c.activateOnFocus) this.showLayer(c);
},
onBlur: function(c){
if (c.validateOnBlur){
this.refreshDateField(c);
};
},
onClick: function(c){
this.hideAllLayers();
this.showLayer(c);
},
refreshDateField: function(c){
//Datum des Feldes normalisieren
var strDate = this.normalizeDateString(jQuery('#'+c.fieldId).get(0).value);
//Validieren
c.isDateValid = this.validateDate(c, strDate);
//Wenn das Datum korrekt ist
if (c.isDateValid) {
jQuery('#'+c.fieldId).get(0).value = strDate;
jQuery('#'+c.fieldId).removeClass(c.errorClass);
this.hideLayer(c);
return true;
} else {
jQuery('#'+c.fieldId).addClass(c.errorClass);
return false;
}
},
setDateFieldValue: function(c, strValue){
jQuery('#'+c.fieldId).get(0).value = strValue;
jQuery('#'+c.fieldId).change();
this.refreshDateField(c);
},
validateDate: function(c, strDate){
var isDateValid = false;
//Datumformat validieren
isDateValid = this.validateDateString(strDate);
//Datumzeitraum validieren
if (isDateValid) isDateValid = this.validateDateRange(c, strDate);
c.isDateValid = isDateValid;
return isDateValid;
},
showLayer: function(c){
this.buildLayer(c);
},
hideLayer: function(c){
if (c.calendarLayer != null) {
jQuery('body').get(0).removeChild(c.calendarLayer);
c.calendarLayer = null;
}
},
hideAllLayers: function(){
for(var i in this.items) {
this.hideLayer(this.items[i]);
}
},
buildLayer: function(c){
if (jQuery('#'+c.fieldId+'_layer').get(0) == null) {
var currentDate = new Date();
var fromDate = currentDate;
if (c.range.from != null) {
var arrDate = c.range.from.split('.');
fromDate = new Date(parseInt(arrDate[2]),(parseInt(arrDate[1])-1),parseInt(arrDate[0]));
}
var strCurrentDate = currentDate.getDate()+'.'+(currentDate.getMonth()+1)+'.'+currentDate.getFullYear();
//Datum des Feldes normalisieren
if (jQuery('#'+c.fieldId).get(0).value != '') {
var strInputDate = this.normalizeDateString(jQuery('#'+c.fieldId).get(0).value);
} else if (c.defaultDate != null) {
var strInputDate = this.normalizeDateString(c.defaultDate);
} else {
var strInputDate = '';
}
//Validieren
var isDateValid = this.validateDate(c, strInputDate);
//Wenn das Datum im Eingabefeld korrekt ist
if (isDateValid) {
var arrayInputDate = strInputDate.split(strInputDate.substring(2,3));
var month = arrayInputDate[1];
var year = arrayInputDate[2];
var strMonth = c.monthsNames[c.form][arrayInputDate[1]-1];
var strYear = arrayInputDate[2];
} else {
var startDate = (c.range.from == null) ? currentDate : fromDate;
var month = parseInt(startDate.getMonth()+1);
var year = parseInt(startDate.getFullYear());
var strMonth = c.monthsNames[c.form][startDate.getMonth()];
var strYear = startDate.getFullYear();
}
var layer = document.createElement('div');
layer.setAttribute('id', c.fieldId+'_layer');
layer.className = c.layerClass;
layer.style.position = 'absolute';
if (c.position == 'bottomLeft') {
layer.style.top = this.getElementTopPos(jQuery('#'+c.fieldId).get(0)) + jQuery('#'+c.fieldId).get(0).offsetHeight + c.positionDeltaTop + 'px';
layer.style.left = this.getElementLeftPos(jQuery('#'+c.fieldId).get(0)) + 'px';
} else {
layer.style.top = this.getElementTopPos(jQuery('#'+c.fieldId).get(0)) + 'px';
layer.style.left = this.getElementLeftPos(jQuery('#'+c.fieldId).get(0)) + jQuery('#'+c.fieldId).get(0).offsetWidth + c.positionDeltaLeft + 'px';
}
jQuery('body').get(0).appendChild(layer);
layer.innerHTML = ''+
'
'+
'
'+c.title+'
'+
'
'+
'
'+this.getDaysTable(c, month, year)+'
'+
''
'
';
c.calendarLayer = layer;
//Events*************************
var calendar = this;
jQuery('#'+c.fieldId+'_layer .btnClose a').bind('click', function(){ calendar.hideLayer(c); });
//Days anchors
jQuery('#'+c.fieldId+'_layer .content a').each( function(i){
jQuery(this).bind('click', function(){
var strDate = jQuery(this).attr('rel');
calendar.setDateFieldValue(c,strDate);
});
});
//Current day anchor
jQuery('#'+c.fieldId+'_layer .footer a').each( function(i){
jQuery(this).bind('click', function(){
var strDate = jQuery(this).attr('rel');
calendar.setDateFieldValue(c,strDate);
});
});
//Next/Prev month
jQuery('#'+c.fieldId+'_layer .btnNext').bind('click', function(){
calendar.getNextMonth(c, month, year);
});
jQuery('#'+c.fieldId+'_layer .btnPrev').bind('click', function(){
calendar.getPrevMonth(c, month, year);
});
} else jQuery('#'+c.fieldId+'_layer').show();
},
getDaysTable: function(c, month, year){
//Header
var html = '';
for (var i=0; i<7; i++){
html += '| '+c.daysNames[c.form][i]+' | ';
}
html +='
';
var firstDate = new Date(year, month-1, 1, 0, 0, 0);
var intDay = firstDate.getDay();
if (c.form == 'EU') {
intDay--;
intDay = (intDay == -1) ? intDay = 6 : intDay;
}
//Days cells
var intDayCount = 1;
var strValue = null;
var tdClass = null;
var strDate = null;
var isDateRangeValid = true;
for (var cw=0; cw<6; cw++){
html += '';
for (var cd=0; cd<7; cd++){
tdClass = '';
strValue = '';
strDate = '';
isDateRangeValid = true;
if (c.form=='US' && (cd==0 || cd==6)) tdClass += 'weekend ';
if (c.form=='EU' && (cd==5 || cd==6)) tdClass += 'weekend ';
if ( cw==0 && cd>=intDay ){ //Erste Woche des Monats
strDate = this.normalizeDateString(intDayCount+'.'+month+'.'+year);
isDateRangeValid = this.validateDateRange(c, strDate);
if (!isDateRangeValid) tdClass += 'disabled ';
if ((this.isInputDate(c, strDate)) && (isDateRangeValid)) tdClass += 'selected ';
strValue = intDayCount;
if (isDateRangeValid) html += '| '+strValue+' | ';
else html += ''+strValue+' | ';
intDayCount++;
} else if ( cw==0 && cd'+strValue+'';
} else { //Folgewochen
if (!this.isNextMonth(intDayCount,month, year)) {
strDate = this.normalizeDateString(intDayCount+'.'+month+'.'+year);
isDateRangeValid = this.validateDateRange(c, strDate);
if (!isDateRangeValid) tdClass += 'disabled ';
if ((this.isInputDate(c, strDate)) && (isDateRangeValid)) tdClass += 'selected ';
strValue = intDayCount;
if (isDateRangeValid) html += ''+strValue+' | ';
else html += ''+strValue+' | ';
intDayCount++;
} else {
tdClass += 'blank ';
strValue = ' ';
html += ''+strValue+' | ';
}
}
}
html += '
';
}
html += '
';
return html;
},
isNextMonth: function(day, month, year){
var objDate = new Date(year, month-1, day, 0, 0, 0);
var calcMonth = objDate.getMonth();
if (calcMonth!=(month-1)) return true;
else return false;
},
isInputDate: function(c, strDate){
//Datum des Feldes normalisieren
var strInputDate = this.normalizeDateString(jQuery('#'+c.fieldId).get(0).value);
//Validieren
var isDateValid = this.validateDate(c, strInputDate);
//Wenn das Datum im Eingabefeld korrekt ist
if (isDateValid) {
if (this.isDatesEq(strInputDate, strDate)) return true;
} else return false;
},
getElementTopPos: function(obj) {
var returnValue = obj.offsetTop;
while((obj = obj.offsetParent) != null){
if (obj.tagName!='HTML') returnValue += obj.offsetTop;
}
return returnValue;
},
getElementLeftPos: function(obj) {
var returnValue = obj.offsetLeft;
while((obj = obj.offsetParent) != null){
if (obj.tagName!='HTML') returnValue += obj.offsetLeft;
}
return returnValue;
},
getNextMonth: function(c, month, year){
var nextMonth = 1;
var nextYear = 1970;
if (typeof(month) == 'string') month = (month.substr(0,1) == '0') ? month.substr(1,1) : month;
month = parseInt(month);
year = parseInt(year);
nextMonth = ((month+1)>12) ? 1 : (month+1);
nextYear = ((month+1)>12) ?(year+1) : year;
jQuery('#'+c.fieldId+'_layer .content').html(this.getDaysTable(c, nextMonth, nextYear));
//Title mit Datum
jQuery('#'+c.fieldId+'_layer .info').html(c.monthsNames[c.form][nextMonth-1] + ' ' + nextYear);
//Buttons events
var calendar = this;
//Next
jQuery('#'+c.fieldId+'_layer .btnNext').unbind('click');
jQuery('#'+c.fieldId+'_layer .btnNext').bind('click', function(){
calendar.getNextMonth(c, nextMonth, nextYear);
});
//Prev
jQuery('#'+c.fieldId+'_layer .btnPrev').unbind('click');
jQuery('#'+c.fieldId+'_layer .btnPrev').bind('click', function(){
calendar.getPrevMonth(c, nextMonth, nextYear);
});
//Days anchors events
jQuery('#'+c.fieldId+'_layer .content a').each( function(i){
jQuery(this).bind('click', function(){
var strDate = jQuery(this).attr('rel');
calendar.setDateFieldValue(c,strDate);
});
});
},
getPrevMonth: function(c, month, year){
var prevMonth = 1;
var prevYear = 1970;
month = parseInt(month);
year = parseInt(year);
var prevMonth = ((month-1)<=0) ? 12 : (month-1) ;
var prevYear = ((month-1)<=0) ? (year-1) : year;
jQuery('#'+c.fieldId+'_layer .content').html(this.getDaysTable(c, prevMonth, prevYear));
//Title mit Datum
jQuery('#'+c.fieldId+'_layer .info').html(c.monthsNames[c.form][prevMonth-1] + ' ' + prevYear);
//Buttons events
var calendar = this;
//Next
jQuery('#'+c.fieldId+'_layer .btnNext').unbind('click');
jQuery('#'+c.fieldId+'_layer .btnNext').bind('click', function(){
calendar.getNextMonth(c, prevMonth, prevYear);
});
//Prev
jQuery('#'+c.fieldId+'_layer .btnPrev').unbind('click');
jQuery('#'+c.fieldId+'_layer .btnPrev').bind('click', function(){
calendar.getPrevMonth(c, prevMonth, prevYear);
});
//Days anchors events
jQuery('#'+c.fieldId+'_layer .content a').each( function(i){
jQuery(this).bind('click', function(){
var strDate = jQuery(this).attr('rel');
calendar.setDateFieldValue(c,strDate);
});
});
},
normalizeDateString: function(strDate){
if (strDate == null) return null;
//Zum Format fuehren: dd.mm.yyyy | dd-mm-yyyy | dd/mm/yyyy
//Fehlende '0' und '20' einfuegen, wenn es notwendig ist
//- Separator ermitteln. Moegliche Variante: . - /
var separator = null;
separator = ((strDate.indexOf('.') != -1) && (separator == null)) ? '.' : separator;
separator = ((strDate.indexOf('-') != -1) && (separator == null)) ? '-' : separator;
separator = ((strDate.indexOf('/') != -1) && (separator == null)) ? '/' : separator;
if (separator!=null) {
//- '0' einfuegen, zusammenfueren
var arrayDate = strDate.split(separator);
strDate = '';
for (var i=0; i"Max. Anzahl von Tagen" erstellen, nicht fuer Februar relevant
var arrayLookup = { '01': 31, '03': 31,
'04': 30, '05': 31, '06': 30,
'07': 31, '08': 31, '09': 30,
'10': 31, '11': 30, '12': 31 };
var intDay = parseInt(arrayDate[0],10);
//Tagwert und Monatwert pruefen
if (arrayLookup[arrayDate[1]] != null) {
if ((intDay <= arrayLookup[arrayDate[1]]) && (intDay != 0))
return true; //richtig, in der Zuordnungstabelle gefunden wurde
}
//Pruefung fuer Februar
var intMonth = parseInt(arrayDate[1],10);
if (intMonth == 2) {
var intYear = parseInt(arrayDate[2]);
if ((intDay > 0) && (intDay < 29)) {
return true;
} else if (intDay == 29) {
if ((intYear % 4 == 0) && (intYear % 100 != 0) || (intYear % 400 == 0)) {
// year div by 4 and ((not div by 100) or div by 400) ->ok
return true;
}
}
}
}
return false; //Alles anderes ist falsch
},
validateDateRange: function(c, strDate){
var currentDateFull = new Date();
var strCurrentDate = currentDateFull.getDate()+'.'+ parseInt(currentDateFull.getMonth()+1)+'.'+currentDateFull.getFullYear();
strCurrentDate = this.normalizeDateString(strCurrentDate);
strDate = this.normalizeDateString(strDate);
c.range = (typeof(c.range) == 'undefined') ? { from: null, upto: null} : c.range;
//From
var rangeFrom = this.normalizeDateString(c.range.from);
if (c.onlyFutureEnabled) {
if ((rangeFrom != null) && (this.isDatesLt(c.range.from, strCurrentDate))) rangeFrom = strCurrentDate;
else if (rangeFrom == null) rangeFrom = strCurrentDate;
}
//To
var rangeUpto = this.normalizeDateString(c.range.upto);
if ((c.onlyFutureEnabled) && (rangeUpto != null) && (this.isDatesLt(rangeUpto, strCurrentDate))) rangeUpto = null;
//
if (c.onlyFutureEnabled) {
if ((c.currentDateEnabled) && (this.isDatesLt(strDate, rangeFrom))) return false;
if ((!c.currentDateEnabled) && (this.isDatesLtEq(strDate, rangeFrom))) return false;
}
if ((rangeFrom != null) && (this.isDatesLt(strDate, rangeFrom))) return false;
if ((rangeUpto != null) && (this.isDatesLt(rangeUpto, strDate))) return false;
return true;
},
isDatesEq: function(strDate1, strDate2){
var strSeparator1 = strDate1.substring(2,3)
var arrayDate1 = strDate1.split(strSeparator1);
var strSeparator2 = strDate2.substring(2,3)
var arrayDate2 = strDate2.split(strSeparator2);
if ( arrayDate1[0] == arrayDate2[0] &&
arrayDate1[1] == arrayDate2[1] &&
arrayDate1[2] == arrayDate2[2] ) return true;
else return false;
},
isDatesLt: function(strDate1, strDate2){
var strSeparator1 = strDate1.substring(2,3)
var arrayDate1 = strDate1.split(strSeparator1);
var strSeparator2 = strDate2.substring(2,3)
var arrayDate2 = strDate2.split(strSeparator2);
var day1 = parseInt(arrayDate1[0],10);
var month1 = parseInt(arrayDate1[1],10);
var year1 = parseInt(arrayDate1[2],10);
var day2 = parseInt(arrayDate2[0],10);
var month2 = parseInt(arrayDate2[1],10);
var year2 = parseInt(arrayDate2[2],10);
//alert(strDate1 +'#'+ strDate2 + ' | ' +day1+'.'+month1+'#'+day2+'.'+month2);
if (year1 < year2) return true;
else if (year1 > year2) return false;
else{
if (month1 < month2) return true;
else if (month1 > month2) return false;
else {
if (day1 < day2) return true;
else if (day1 > day2) return false;
else return false;
}
}
return false;
},
isDatesLtEq: function(strDate1, strDate2){
if (this.isDatesEq(strDate1, strDate2)) return true;
if (this.isDatesLt(strDate1, strDate2)) return true;
return false;
}
};