pfsense/usr/local/www/javascript/datepicker/js/datepicker.js
2007-01-29 22:07:52 +00:00

1112 lines
51 KiB
JavaScript

/*
DatePicker v2.5 by frequency-decoder.com (2006/12/01)
Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)
Please credit frequency-decoder in any derivative work - thanks.
You are free:
* to copy, distribute, display, and perform the work
* to make derivative works
* to make commercial use of the work
Under the following conditions:
by Attribution.
--------------
You must attribute the work in the manner specified by the author or licensor.
sa
--
Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
* For any reuse or distribution, you must make clear to others the license terms of this work.
* Any of these conditions can be waived if you get permission from the copyright holder.
*/
var datePickerController;
(function() {
datePicker.isSupported = typeof document.createElement != "undefined" &&
typeof document.documentElement != "undefined" &&
typeof document.documentElement.offsetWidth == "number";
// Detect the users language
datePicker.languageinfo = navigator.language ? navigator.language : navigator.userLanguage;
datePicker.languageinfo = datePicker.languageinfo ? datePicker.languageinfo.toLowerCase().replace(/-[a-z]+$/, "") : 'en';
if(datePicker.languageinfo != 'en') {
// Load the appropriate language file
var scriptFiles = document.getElementsByTagName('head')[0].getElementsByTagName('script');
var loc = "";
for(var i = 0, scriptFile; scriptFile = scriptFiles[i]; i++) {
if(scriptFile.src && scriptFile.src.match(/datepicker/)) {
loc = scriptFile.src.replace("datepicker", "lang/" + datePicker.languageinfo);
break;
};
};
if(loc != "") {
var script = document.createElement('script');
script.type = "text/javascript";
script.src = loc;
// Hopefully this allows a UTF-8 js file to be imported into a non-UTF HTML document
script.setAttribute("charset", "utf-8");
document.getElementsByTagName('head')[0].appendChild(script);
};
};
// Defaults for the language should the locale file not load
datePicker.months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"];
datePicker.fullDay = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"];
datePicker.titles = [
"Previous month",
"Next month",
"Previous year",
"Next year"];
datePicker.daysPerMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
datePicker.getDaysPerMonth = function (nMonth, nYear) {
nMonth = (nMonth + 12) % 12;
var res = datePicker.daysPerMonth[nMonth];
if(((0 == (nYear%4)) && ((0 != (nYear%100)) || (0 == (nYear%400)))) && nMonth == 1) {
res = 29;
};
return res;
};
function datePicker(options) {
this.defaults = {};
for(opt in options) {
this[opt] = this.defaults[opt] = options[opt];
};
this.date = new Date();
this.yearinc = 1;
this.timer = null;
this.pause = 1000;
this.timerSet = false;
this.opacity = 0;
this.opacityTo = 0;
this.fadeTimer = null;
this.interval = new Date();
this.firstDayOfWeek = this.defaults.firstDayOfWeek = 0;
this.dateSet = null;
this.visible = false;
this.div;
this.table;
var o = this;
o.reset = function() {
for(def in o.defaults) {
o[def] = o.defaults[def];
};
};
o.setOpacity = function(op) {
o.div.style.opacity = + op/100;
o.div.style.filter = 'alpha(opacity=' + op + ')';
o.opacity = op;
};
o.fade = function() {
window.clearTimeout(o.fadeTimer);
var diff = Math.round(o.opacity + ((o.opacityTo - o.opacity) / 4));
o.setOpacity(diff);
if(Math.abs(o.opacityTo - diff) > 3) {
o.fadeTimer = window.setTimeout(function () { o.fade(); }, 50);
} else {
o.setOpacity(o.opacityTo);
if(o.opacityTo == 0) o.div.style.display = "none";
};
};
o.killEvent = function(e) {
if (e == null) e = document.parentWindow.event;
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
/*@cc_on@*/
/*@if(@_win32)
e.cancelBubble = true;
e.returnValue = false;
/*@end@*/
return false;
};
o.startTimer = function () {
if (o.timerSet) o.stopTimer();
o.timer = window.setTimeout(function () { o.onTimer(); }, o.timerInc);
o.timerSet = true;
};
o.stopTimer = function () {
if (o.timer != null) window.clearTimeout(o.timer);
o.timerSet = false;
};
o.events = {
onkeydown: function (e) {
if(!o.visible) return false;
if (e == null) e = document.parentWindow.event;
var kc = e.keyCode ? e.keyCode : e.charCode;
if ( kc == 13 ) {
// close with update
o.returnFormattedDate();
o.hide();
return o.killEvent(e);
} else if ( kc == 27 ) {
// close
o.hide();
return o.killEvent(e);
} else if ( kc == 32 || kc == 0 ) {
// close
o.date = new Date( );
o.updateTable();
return o.killEvent(e);
};
// Internet Explorer fires the keydown event faster than the JavaScript engine can
// update the interface. The following attempts to fix this.
/*@cc_on@*/
/*@if(@_win32)
if(new Date().getTime() - o.interval.getTime() < 100) return o.killEvent(e);
o.interval = new Date();
/*@end@*/
if ((kc > 49 && kc < 56) || (kc > 97 && kc < 104)) {
if (kc > 96) kc -= (96-48);
kc -= 49;
o.firstDayOfWeek = (o.firstDayOfWeek + kc) % 7;
o.updateTable();
return o.killEvent(e);
};
if ( kc < 37 || kc > 40 ) return true;
var d = new Date( o.date ).valueOf();
if ( kc == 37 ) {
// ctrl + left = previous month
if( e.ctrlKey ) {
d = new Date( o.date );
d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth() - 1,d.getFullYear())) ); // no need to catch dec -> jan for the year
d.setMonth( d.getMonth() - 1 );
} else {
d -= 24 * 60 * 60 * 1000;
};
} else if ( kc == 39 ) {
// ctrl + right = next month
if( e.ctrlKey ) {
d = new Date( o.date );
d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth() + 1,d.getFullYear())) ); // no need to catch dec -> jan for the year
d.setMonth( d.getMonth() + 1 );
} else {
d += 24 * 60 * 60 * 1000;
};
} else if ( kc == 38 ) {
// ctrl + up = next year
if( e.ctrlKey ) {
d = new Date( o.date );
d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth(),d.getFullYear() + 1)) ); // no need to catch dec -> jan for the year
d.setFullYear( d.getFullYear() + 1 );
} else {
d -= 7 * 24 * 60 * 60 * 1000;
};
} else if ( kc == 40 ) {
// ctrl + down = prev year
if( e.ctrlKey ) {
d = new Date( o.date );
d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth(),d.getFullYear() - 1)) ); // no need to catch dec -> jan for the year
d.setFullYear( d.getFullYear() - 1 );
} else {
d += 7 * 24 * 60 * 60 * 1000;
};
};
var tmpDate = new Date( d );
if(!o.outOfRange(tmpDate)) {
o.date = tmpDate;
};
o.updateTable();
return o.killEvent(e);
},
onmousedown: function(e) {
if ( e == null ) e = document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
var found = false;
while(el.parentNode) {
if(el.id && (el.id == "fd-"+o.id || el.id == "fd-but-"+o.id)) {
found = true;
break;
}
try {
el = el.parentNode;
} catch(err) {
break;
}
}
if(found) return true;
datePickerController.hideAll();
},
onmouseover: function(e) {
if(document.getElementById("date-picker-hover")) {
document.getElementById("date-picker-hover").id = "";
};
this.id = "date-picker-hover";
o.date.setDate(this.firstChild.nodeValue);
},
onclick: function (e) {
if(o.opacity != o.opacityTo) return false;
if ( e == null ) e = document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
while ( el.nodeType != 1 ) el = el.parentNode;
var d = new Date( o.date );
var n = Number( el.firstChild.data );
if(isNaN(n)) { return true; };
d.setDate( n );
o.date = d;
o.returnFormattedDate();
o.hide();
return o.killEvent(e);
},
incDec:function(e) {
if(o.timerSet) {
o.stopTimer();
};
datePickerController.addEvent(document, "mouseup", o.events.clearTimer);
o.timerInc = 1000;
o.dayInc = arguments[1];
o.yearInc = arguments[2];
o.monthInc = arguments[3];
o.onTimer();
return o.killEvent(e);
},
clearTimer:function() {
o.stopped = true;
o.timerInc = 1000;
o.yearInc = 0;
o.monthInc = 0;
o.dayInc = 0;
try {
datePickerController.removeEvent(document, "mouseup", o.events.clearTimer);
} catch(e) { };
o.stopTimer();
}
};
o.onTimer = function() {
var d = new Date( o.date );
d.setDate( Math.min(d.getDate()+o.dayInc, datePicker.getDaysPerMonth(d.getMonth()+o.monthInc,d.getFullYear()+o.yearInc)) ); // no need to catch dec -> jan for the year
d.setMonth( d.getMonth() + o.monthInc );
d.setFullYear( d.getFullYear() + o.yearInc );
o.date = d;
if(o.timerInc > 50) {
o.timerInc = 50 + Math.round(((o.timerInc - 50) / 1.8));
};
o.startTimer();
o.updateTable();
};
o.getElem = function() {
return document.getElementById(o.id.replace(/^fd-/, '')) || false;
};
o.setRangeLow = function(range) {
if(String(range).search(/^(\d\d?\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) range = '';
o.low = o.defaults.low = range;
};
o.setRangeHigh = function(range) {
if(String(range).search(/^(\d\d?\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) range = '';
o.high = o.defaults.high = range;
};
o.setDisabledDays = function(dayArray) {
o.disableDays = o.defaults.disableDays = dayArray;
};
o.setFirstDayOfWeek = function(e) {
if ( e == null ) e = document.parentWindow.event;
var elem = e.target != null ? e.target : e.srcElement;
if(elem.tagName.toLowerCase() != "th") {
while(elem.tagName.toLowerCase() != "th") elem = elem.parentNode;
}
var cnt = 0;
while(elem.previousSibling) {
elem = elem.previousSibling;
if(elem.tagName.toLowerCase() == "th") cnt++;
}
o.firstDayOfWeek = (o.firstDayOfWeek + cnt) % 7;
o.updateTable();
return o.killEvent(e);
};
o.trueBody = function() {
return
};
o.resize = function() {
if(!o.created || !o.getElem()) return;
o.div.style.visibility = "hidden";
o.div.style.display = "block";
var osh = o.div.offsetHeight;
var osw = o.div.offsetWidth;
o.div.style.visibility = "visible";
o.div.style.display = "none";
var elem = document.getElementById('fd-but-' + o.id);
var pos = datePickerController.findPosition(elem);
var trueBody = (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
if ( parseInt(trueBody.clientWidth+trueBody.scrollLeft) < parseInt(osw+pos[0])) {
o.div.style.left = Math.abs(parseInt((trueBody.clientWidth+trueBody.scrollLeft) - osw)) + "px";
} else {
o.div.style.left = pos[0] + "px";
};
if ( parseInt(trueBody.clientHeight+trueBody.scrollTop) < parseInt(osh+pos[1]+elem.offsetHeight+2)) {
o.div.style.top = Math.abs(parseInt(pos[1] - (osh + 2))) + "px";
} else {
o.div.style.top = Math.abs(parseInt(pos[1] + elem.offsetHeight + 2)) + "px";
};
};
o.equaliseDates = function() {
var clearDayFound = false;
var tmpDate;
for(var i = o.low; i <= o.high; i++) {
tmpDate = String(i);
if(!o.disableDays[new Date(tmpDate.substr(4,2) + '/' + tmpDate.substr(6,2) + '/' + tmpDate.substr(0,4)).getDay() - 1]) {
clearDayFound = true;
break;
};
};
if(!clearDayFound) o.disableDays = o.defaults.disableDays = [0,0,0,0,0,0,0];
};
o.outOfRange = function(tmpDate) {
if(!o.low && !o.high) return false;
var level = false;
if(!tmpDate) {
level = true;
tmpDate = o.date;
};
var d = (tmpDate.getDate() < 10) ? "0" + tmpDate.getDate() : tmpDate.getDate();
var m = ((tmpDate.getMonth() + 1) < 10) ? "0" + (tmpDate.getMonth() + 1) : tmpDate.getMonth() + 1;
var y = tmpDate.getFullYear();
var dt = (y+' '+m+' '+d).replace(/ /g,'');
if(o.low) {
if(parseInt(dt) < parseInt(o.low)) {
if(!level) return true;
o.date = new Date( o.low.substr(4,2) + '/' + o.low.substr(6,2) + '/' + o.low.substr(0,4) );
return false;
};
};
if(o.high) {
if(parseInt(dt) > parseInt(o.high)) {
if(!level) return true;
o.date = new Date( o.high.substr(4,2) + '/' + o.high.substr(6,2) + '/' + o.high.substr(0,4) );
};
};
return false;
};
o.create = function() {
/*@cc_on@*/
/*@if(@_jscript_version <= 5.6)
if(!document.getElementById("iePopUpHack")) {
var loc = "./blank.html";
var scriptFiles = document.getElementsByTagName('head')[0].getElementsByTagName('script');
for(var i = 0, scriptFile; scriptFile = scriptFiles[i]; i++) {
if(scriptFile.src && scriptFile.src.match(/datepicker.js$/)) {
loc = scriptFile.src.replace("datepicker.js", "blank.html");
break;
};
};
o.iePopUp = document.createElement('iframe');
o.iePopUp.src = loc;
o.iePopUp.setAttribute('className','iehack');
o.iePopUp.scrolling="no";
o.iePopUp.frameBorder="0";
o.iePopUp.name = o.iePopUp.id = "iePopUpHack";
document.body.appendChild(o.iePopUp);
} else {
o.iePopUp = document.getElementById("iePopUpHack");
};
/*@end@*/
if(typeof(fdLocale) == "object" && o.locale) {
datePicker.titles = fdLocale.titles;
datePicker.months = fdLocale.months;
datePicker.fullDay = fdLocale.fullDay;
// Optional parameters
if(fdLocale.dayAbbr) datePicker.dayAbbr = fdLocale.dayAbbr;
if(fdLocale.firstDayOfWeek) o.firstDayOfWeek = o.defaults.firstDayOfWeek = fdLocale.firstDayOfWeek;
};
o.div = document.createElement('div');
o.div.style.zIndex = 9999;
o.div.id = "fd-"+o.id;
var tableBody = document.createElement('tbody');
var tableHead = document.createElement('thead');
var nbsp = String.fromCharCode( 160 );
o.table = document.createElement('table');
o.div.className = "datePicker";
var tr = document.createElement('tr');
var th = document.createElement('th');
// previous year
var tmpelem = document.createElement('button');
tmpelem.setAttribute("type", "button");
tmpelem.className = "prev-but";
tmpelem.appendChild(document.createTextNode('\u00AB'));
tmpelem.title = datePicker.titles[2];
tmpelem.onmousedown = function(e) { this.blur(); o.events.incDec(e,0,-1,0); };
tmpelem.onmouseup = o.events.clearTimer;
th.appendChild( tmpelem );
// previous month
var tmpelem = document.createElement('button');
tmpelem.setAttribute("type", "button");
tmpelem.className = "prev-but";
tmpelem.appendChild(document.createTextNode("\u2039"));
tmpelem.title = datePicker.titles[0];
tmpelem.onmousedown = function(e) { this.blur(); o.events.incDec(e,0,0,-1); };
tmpelem.onmouseup = o.events.clearTimer;
th.appendChild( tmpelem );
tr.appendChild( th );
// title bar
o.titleBar = document.createElement('th');
/*@cc_on
/*@if (@_win32)
o.titleBar.setAttribute('colSpan','5');
@else @*/
o.titleBar.setAttribute('colspan','5');
/*@end
@*/
o.titleBar.setAttribute('text-align','center');
tr.appendChild( o.titleBar );
th = document.createElement('th');
// next month
var tmpelem = document.createElement('button');
tmpelem.setAttribute("type", "button");
tmpelem.className = "next-but";
tmpelem.appendChild(document.createTextNode('\u203A'));
tmpelem.title = datePicker.titles[1];
tmpelem.onmousedown = function(e) { this.blur(); o.events.incDec(e,0,0,1); };
tmpelem.onmouseup = o.events.clearTimer;
th.appendChild( tmpelem );
// next year
var tmpelem = document.createElement('button');
tmpelem.setAttribute("type", "button");
tmpelem.className = "next-but";
tmpelem.appendChild(document.createTextNode('\u00BB'));
tmpelem.title = datePicker.titles[3];
tmpelem.onmousedown = function(e) { this.blur(); o.events.incDec(e,0,1,0); };
tmpelem.onmouseup = o.events.clearTimer;
th.appendChild( tmpelem );
tr.appendChild( th );
tableHead.appendChild(tr);
var row, col;
for(var rows = 0; rows < 7; rows++) {
row = document.createElement('tr');
for(var cols = 0; cols < 7; cols++) {
col = (rows == 0) ? document.createElement('th') : document.createElement('td');
if(rows != 0) {
col.appendChild(document.createTextNode(nbsp));
} else {
col.className = "date-picker-day-header";
col.scope = "col";
};
row.appendChild(col);
}
if(rows != 0) tableBody.appendChild(row);
else tableHead.appendChild(row);
};
o.table.appendChild( tableHead );
o.table.appendChild( tableBody );
o.div.appendChild( o.table );
o.created = true;
document.getElementsByTagName('body')[0].appendChild( o.div );
};
o.setDateFromInput = function() {
o.dateSet = null;
var elem = o.getElem();
if(!elem) return;
var date = elem.value;
var d,m,y,dt,dates;
d = o.format.replace(/-/g,'').indexOf('d');
m = o.format.replace(/-/g,'').indexOf('m');
y = o.format.replace(/-/g,'').indexOf('y');
if(o.splitDate) {
dates = [];
dates[m] = document.getElementById(o.id+'-mm').value;
if(dates[m] < 1 || dates[m] > 12) dates[m] = "";
dates[d] = document.getElementById(o.id+'-dd').value;
if(dates[d] < 1 || dates[d] > datePicker.daysPerMonth[dates[m]-1]) dates[d] = "";
dates[y] = date;
} else {
if(date.match(/^[0-9]{4}$/)) {
if(date > 1600 && date < 2030) {
o.date.setFullYear(date);
return;
};
};
dates = date.split(o.divider);
if(dates.length != 3) {
o.date = new Date();
return;
};
};
var check = new Date( dates[y] + "/" + dates[m] + "/" + dates[d] );
if(check == 'Invalid Date' /*@cc_on@*/ /*@if(@_win32) || check == 'NaN' /*@end@*/) {
o.date = new Date();
return;
};
o.date.setMonth(dates[m]-1);
o.date.setFullYear(dates[y]);
o.date.setDate(dates[d]);
o.dateSet = new Date(o.date);
};
o.returnFormattedDate = function() {
var elem = o.getElem();
if(!elem) return;
var d = (o.date.getDate() < 10) ? "0" + o.date.getDate() : o.date.getDate();
var m = ((o.date.getMonth() + 1) < 10) ? "0" + (o.date.getMonth() + 1) : o.date.getMonth() + 1;
var yyyy = o.date.getFullYear();
var weekDay = ( o.date.getDay() + 6 ) % 7;
if(!(o.disableDays[weekDay])) {
if(o.splitDate) {
document.getElementById(o.id+"-dd").value = d;
document.getElementById(o.id+"-mm").value = m;
elem.value = yyyy;
document.getElementById(o.id+"-dd").focus();
if(document.getElementById(o.id+"-dd").onchange) document.getElementById(o.id+"-dd").onchange();
if(document.getElementById(o.id+"-mm").onchange) document.getElementById(o.id+"-mm").onchange();
} else {
elem.value = o.format.replace('y',yyyy).replace('m',m).replace('d',d).replace(/-/g,o.divider);
elem.focus();
};
if(elem.onchange) elem.onchange();
};
};
// Credit where credit's due:
// Most of the logic for this method from the webfx date-picker
// http://webfx.eae.net/
o.updateTable = function() {
if(document.getElementById("date-picker-hover")) {
document.getElementById("date-picker-hover").id = "";
};
var i;
var str = "";
var rows = 6;
var cols = 7;
var currentWeek = 0;
var nbsp = String.fromCharCode( 160 );
var cells = new Array( rows );
for ( i = 0; i < rows; i++ ) {
cells[i] = new Array( cols );
};
o.outOfRange();
// Set the tmpDate to this month
var tmpDate = new Date( o.date.getFullYear(), o.date.getMonth(), 1 );
var today = new Date();
// titleBar
var titleText = datePicker.months[o.date.getMonth()] + nbsp + o.date.getFullYear();
while(o.titleBar.firstChild) o.titleBar.removeChild(o.titleBar.firstChild);
o.titleBar.appendChild(document.createTextNode(titleText));
for ( i = 1; i < 32; i++ ) {
tmpDate.setDate( i );
var weekDay = ( tmpDate.getDay() + 6 ) % 7;
var colIndex = ( (weekDay - o.firstDayOfWeek) + 7 ) % 7;
var cell = { text:"", className:"", id:"" };
if ( tmpDate.getMonth() == o.date.getMonth() ) {
cells[currentWeek][colIndex] = { text:"", className:"", id:"" };
var isToday = tmpDate.getDate() == today.getDate() &&
tmpDate.getMonth() == today.getMonth() &&
tmpDate.getFullYear() == today.getFullYear();
if ( o.dateSet != null && o.dateSet.getDate() == tmpDate.getDate() && o.dateSet.getMonth() == tmpDate.getMonth() && o.dateSet.getFullYear() == tmpDate.getFullYear()) {
cells[currentWeek][colIndex].className = "date-picker-selected-date";
};
if ( o.date.getDate() == tmpDate.getDate() && o.date.getFullYear() == tmpDate.getFullYear()) {
cells[currentWeek][colIndex].id = "date-picker-hover";
};
if(o.highlightDays[weekDay]) {
cells[currentWeek][colIndex].className += " date-picker-highlight";
};
if ( isToday ) {
cells[currentWeek][colIndex].className = "date-picker-today";
};
if(o.outOfRange(tmpDate)) {
cells[currentWeek][colIndex].className = "out-of-range";
} else if(o.disableDays[weekDay]) {
cells[currentWeek][colIndex].className = "day-disabled";
};
cells[currentWeek][colIndex].text = tmpDate.getDate();
if ( colIndex == 6 ) currentWeek++;
};
};
// Table headers
var lnk, d;
var ths = o.table.getElementsByTagName('thead')[0].getElementsByTagName('tr')[1].getElementsByTagName('th');
for ( var y = 0; y < 7; y++ ) {
d = (o.firstDayOfWeek + y) % 7;
while(ths[y].firstChild) ths[y].removeChild(ths[y].firstChild);
ths[y].title = datePicker.fullDay[d];
// Don't create a button for the first day header
if(y > 0) {
but = document.createElement("BUTTON");
but.className = "fd-day-header";
but.onclick = but.onkeypress = ths[y].onclick = o.setFirstDayOfWeek;
but.appendChild(document.createTextNode(datePicker.dayAbbr ? datePicker.dayAbbr[d] : datePicker.fullDay[d].charAt(0)));
ths[y].appendChild(but);
but.title = datePicker.fullDay[d];
} else {
ths[y].appendChild(document.createTextNode(datePicker.dayAbbr ? datePicker.dayAbbr[d] : datePicker.fullDay[d].charAt(0)));
ths[y].onclick = null;
};
};
var trs = o.table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
var tmpCell;
for ( var y = 0; y < rows; y++ ) {
var tds = trs[y].getElementsByTagName('td');
for (var x = 0; x < cols; x++) {
tmpCell = tds[x];
while(tmpCell.firstChild) tmpCell.removeChild(tmpCell.firstChild);
if ( typeof cells[y][x] != "undefined" ) {
tmpCell.className = cells[y][x].className;
tmpCell.id = cells[y][x].id;
tmpCell.appendChild(document.createTextNode(cells[y][x].text));
if(cells[y][x].className != "out-of-range") {
tmpCell.onmouseover = o.events.onmouseover;
tmpCell.onclick = cells[y][x].className == "day-disabled" ? o.killEvent : o.events.onclick;
tmpCell.title = datePicker.months[o.date.getMonth()] + nbsp + cells[y][x].text + "," + nbsp + o.date.getFullYear();
} else {
tmpCell.onmouseover = null;
tmpCell.onclick = o.killEvent;
tmpCell.title = "";
};
} else {
tmpCell.className = "";
tmpCell.id = "";
tmpCell.onmouseover = null;
tmpCell.onclick = function(e) { return o.killEvent(e); };
tmpCell.appendChild(document.createTextNode(nbsp));
tmpCell.title = "";
};
};
};
};
o.init = function() {
if(o.low && o.high && (o.high - o.low < 7)) {
o.equaliseDates();
};
o.resize();
o.setDateFromInput();
o.fade();
o.ieHack(true);
};
o.ieHack = function(cleanup) {
// IE hack
if(o.iePopUp) {
o.iePopUp.style.display = "block";
o.iePopUp.style.top = (o.div.offsetTop + 2) + "px";
o.iePopUp.style.left = o.div.offsetLeft + "px";
o.iePopUp.style.width = o.div.clientWidth + "px";
o.iePopUp.style.height = (o.div.clientHeight - 2) + "px";
if(cleanup) o.iePopUp.style.display = "none";
}
};
o.show = function() {
var elem = o.getElem();
if(!elem || o.visible || elem.disabled) return;
o.reset();
o.setDateFromInput();
o.updateTable();
o.resize();
o.ieHack(false);
datePickerController.addEvent(document, "mousedown", o.events.onmousedown);
datePickerController.addEvent(document, "keypress", o.events.onkeydown);
// Internet Explorer requires the keydown event in order to catch arrow keys
/*@cc_on@*/
/*@if(@_win32)
datePickerController.removeEvent(document, "keypress", o.events.onkeydown);
datePickerController.addEvent(document, "keydown", o.events.onkeydown);
/*@end@*/
o.opacityTo = 90;
o.div.style.display = "block";
o.ieHack(false);
o.fade();
o.visible = true;
};
o.hide = function() {
try {
datePickerController.removeEvent(document, "mousedown", o.events.onmousedown);
datePickerController.removeEvent(document, "keypress", o.events.onkeydown);
datePickerController.removeEvent(document, "keydown", o.events.onkeydown);
} catch(e) {
};
if(o.iePopUp) {
o.iePopUp.style.display = "none";
};
o.opacityTo = 0;
o.fade();
o.visible = false;
};
o.create();
o.init();
};
datePickerController = {
datePickers: {},
addEvent: function(obj, type, fn, tmp) {
tmp || (tmp = true);
if( obj.attachEvent ) {
obj["e"+type+fn] = fn;
obj[type+fn] = function(){obj["e"+type+fn]( window.event );};
obj.attachEvent( "on"+type, obj[type+fn] );
} else {
obj.addEventListener( type, fn, true );
};
},
removeEvent: function(obj, type, fn, tmp) {
tmp || (tmp = true);
if( obj.detachEvent ) {
obj.detachEvent( "on"+type, obj[type+fn] );
obj[type+fn] = null;
} else {
obj.removeEventListener( type, fn, true );
};
},
findPosition: function(obj) {
var curleft = 0;
var curtop = 0;
var orig = obj;
if(obj.offsetParent) {
while(obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
obj = obj.offsetParent;
};
} else if (obj.x) {
curleft += obj.x;
curtop += obj.y;
};
return [ curleft, curtop ];
},
hideAll: function(exception) {
for(dp in datePickerController.datePickers) {
if(exception && exception == datePickerController.datePickers[dp].id) continue;
datePickerController.datePickers[dp].hide();
};
},
cleanUp: function() {
var dp;
for(dp in datePickerController.datePickers) {
if(!document.getElementById(datePickerController.datePickers[dp].id)) {
dpElem = document.getElementById("fd-"+datePickerController.datePickers[dp].id);
if(dpElem) {
dpElem.parentNode.removeChild(dpElem);
};
datePickerController.datePickers[dp] = null;
delete datePickerController.datePickers[dp];
};
};
},
dateFormat: function(dateIn, favourMDY) {
var dateTest = [
{ regExp:/^(0[1-9]|[12][0-9]|3[01])([- \/.])(0[1-9]|1[012])([- \/.])(\d\d?\d\d)$/, d:1, m:3, y:5 }, // dmy
{ regExp:/^(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])([- \/.])(\d\d?\d\d)$/, d:3, m:1, y:5 }, // mdy
{ regExp:/^(\d\d?\d\d)([- \/.])(0[1-9]|1[012])([- \/.])(0[1-9]|[12][0-9]|3[01])$/, d:5, m:3, y:1 } // ymd
];
var start;
var cnt = 0;
while(cnt < 3) {
start = (cnt + (favourMDY ? 4 : 3)) % 3;
if(dateIn.match(dateTest[start].regExp)) {
res = dateIn.match(dateTest[start].regExp);
y = res[dateTest[start].y];
m = res[dateTest[start].m];
d = res[dateTest[start].d];
if(m.length == 1) m = "0" + m;
if(d.length == 1) d = "0" + d;
if(y.length != 4) y = (parseInt(y) < 50) ? '20' + y : '19' + y;
return y+m+d;
};
cnt++;
};
return 0;
},
create: function() {
if(!datePicker.isSupported) return;
datePickerController.cleanUp();
var inputs = document.getElementsByTagName('input');
var regExp1 = /disable-days-([1-7]){1,6}/g; // the days to disable
var regExp3 = /highlight-days-([1-7]){1,7}/g; // the days to highlight in red
var regExp4 = /range-low-([0-9\-]){10}/g; // the lowest selectable date
var regExp5 = /range-high-([0-9\-]){10}/g; // the highest selectable date
var regExp6 = /format-([dmy\-]{5})/g; // the input/output date format
var regExp7 = /divider-(dot|slash|space|dash)/g; // the character used to divide the date
var regExp8 = /no-locale/g; // do not attempt to detect the browser language
for(var i=0, inp; inp = inputs[i]; i++) {
if(inp.className && (inp.className.search(regExp6) != -1 || inp.className.search(/split-date/) != -1) && inp.type == "text" && inp.name) {
if(!inp.id) {
// Internet explorer requires you to give each input a unique ID attribute.
if(document.getElementById(inp.name)) continue;
inp.id = inp.name;
};
var options = {
id:inp.id,
low:"",
high:"",
divider:"/",
format:"d-m-y",
highlightDays:[0,0,0,0,0,1,1],
disableDays:[0,0,0,0,0,0,0],
locale:inp.className.search(regExp8) == -1,
splitDate:0
};
// Split the date into three parts ?
if(inp.className.search(/split-date/) != -1) {
if(document.getElementById(inp.id+'-dd') && document.getElementById(inp.id+'-mm') && document.getElementById(inp.id+'-dd').tagName.toLowerCase() == "input" && document.getElementById(inp.id+'-mm').tagName.toLowerCase() == "input") {
options.splitDate = 1;
};
};
// Date format(variations of d-m-y)
if(inp.className.search(regExp6) != -1) {
options.format = inp.className.match(regExp6)[0].replace('format-','');
};
// What divider to use, a "/", "-", "." or " "
if(inp.className.search(regExp7) != -1) {
var divider = inp.className.match(regExp7)[0].replace('divider-','');
switch(divider.toLowerCase()) {
case "dot":
options.divider = ".";
break;
case "space":
options.divider = " ";
break;
case "dash":
options.divider = "-";
break;
default:
options.divider = "/";
};
};
// The days to highlight
if(inp.className.search(regExp3) != -1) {
var tmp = inp.className.match(regExp3)[0].replace(/highlight-days-/, '');
options.highlightDays = [0,0,0,0,0,0,0];
for(var j = 0; j < tmp.length; j++) {
options.highlightDays[tmp.charAt(j) - 1] = 1;
};
};
// The days to disable
if(inp.className.search(regExp1) != -1) {
var tmp = inp.className.match(regExp1)[0].replace(/disable-days-/, '');
options.disableDays = [0,0,0,0,0,0,0];
for(var j = 0; j < tmp.length; j++) {
options.disableDays[tmp.charAt(j) - 1] = 1;
};
};
// The lower limit
if(inp.className.search(regExp4) != -1) {
options.low = datePickerController.dateFormat(inp.className.match(regExp4)[0].replace(/range-low-/, ''), options.format.charAt(0) == "m");
if(options.low == 0) {
options.low = '';
};
};
// The higher limit
if(inp.className.search(regExp5) != -1) {
options.high = datePickerController.dateFormat(inp.className.match(regExp5)[0].replace(/range-high-/, ''), options.format.charAt(0) == "m");
if(options.high == 0) {
options.high = '';
};
};
// Datepicker is already created so reset it's defaults
if(document.getElementById('fd-'+inp.id)) {
for(var opt in options) {
datePickerController.datePickers[inp.id].defaults[opt] = options[opt];
};
};
// Create the button (if needs be)
if(!document.getElementById("fd-but-" + inp.id)) {
var but = document.createElement('button');
but.setAttribute("type", "button");
but.className = "date-picker-control";
but.id = "fd-but-" + inp.id;
but.appendChild(document.createTextNode(String.fromCharCode( 160 )));
if(inp.nextSibling) {
inp.parentNode.insertBefore(but, inp.nextSibling);
} else {
inp.parentNode.appendChild(but);
};
} else {
var but = document.getElementById("fd-but-" + inp.id);
};
// Add button events
but.onclick = but.onpress = function() {
var inpId = this.id.replace('fd-but-','');
datePickerController.hideAll(inpId);
if(inpId in datePickerController.datePickers && !datePickerController.datePickers[inpId].visible) {
datePickerController.datePickers[inpId].show();
};
return false;
};
// Create the datePicker (if needs be)
if(!document.getElementById('fd-'+inp.id)) {
datePickerController.datePickers[inp.id] = new datePicker(options);
};
};
};
}
};
})();
datePickerController.addEvent(window, 'load', datePickerController.create);