function calchange(cal)
{
var date = datePickerController.printFormattedDate(cal.date, "d-m-Y", false);
window.location = "http://www.themolokobar.co.uk/events/#"+date;
}
/*
DatePicker v4b2 rc1 by frequency-decoder.com
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 datePickerController() {
var languageInfo = navigator.language ? navigator.language.toLowerCase().replace(/-[a-z]+$/, "") : navigator.userLanguage ? navigator.userLanguage.toLowerCase().replace(/-[a-z]+$/, "") : "en",
datePickers = {},
uniqueId = 0,
weeksInYearCache = {},
localeImport = false,
nbsp = String.fromCharCode(160),
nodrag = false,
splitAppend = ["-dd","-mm"],
cellFormat = "d-sp-F-sp-Y",
formatMasks = ["Y-sl-m-sl-d","m-sl-d-sl-Y","d-sl-m-sl-Y","Y-ds-m-ds-d","m-ds-d-ds-Y","d-ds-m-ds-Y"];
void function() {
var scriptFiles = document.getElementsByTagName('head')[0].getElementsByTagName('script'),
scriptInner = scriptFiles[scriptFiles.length - 1].innerHTML.replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, ""),
json = parseJSON(scriptInner);
if(typeof json === "object" && !("err" in json)) {
affectJSON(json);
};
if(typeof(fdLocale) != "object" && languageInfo != "en") {
var loc = scriptFiles[scriptFiles.length - 1].src.substr(0, scriptFiles[scriptFiles.length - 1].src.lastIndexOf("/")) + "/lang/" + languageInfo + ".js",
script = document.createElement('script');
script.type = "text/javascript";
script.src = loc;
script.setAttribute("charset", "utf-8");
/*@cc_on
/*@if(@_win32)
var bases = document.getElementsByTagName('base');
if (bases.length && bases[0].childNodes.length) {
bases[0].appendChild(script);
} else {
document.getElementsByTagName('head')[0].appendChild(script);
};
bases = null;
@else @*/
document.getElementsByTagName('head')[0].appendChild(script);
/*@end
@*/
script = null;
};
}();
function affectJSON(json) {
if(typeof json !== "object") { return; };
for(key in json) {
value = json[key];
switch(key.toLower()) {
case "lang":
if(value.search(/^[a-z]{2}$/i) != -1) {
languageInfo = value;
};
break;
case "split":
if(typeof value === 'object') {
if(value.length && value.length == 2) {
splitAppend = value;
};
};
case "formats":
if(typeof value === 'object') {
if(value.length) {
var tmpMasks = [];
for(var m = 0, msk; msk = value[m]; msk++) {
if(msk.match(/((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p]))(-((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p])))+/)) {
tmpMasks.push(msk);
};
};
if(tmpMasks.length) { formatMasks = tmpMasks; };
};
};
break;
case "nodrag":
nodrag = !!value;
break;
case "cellformat":
if(typeof value == "string" && value.match(/((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p]))(-((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p])))+/)) {
cellFormat = cellformat;
};
};
};
};
function pad(value, length) {
length = length || 2;
return "0000".substr(0,length - Math.min(String(value).length, length)) + value;
};
function addEvent(obj, type, fn) {
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 );
};
};
function removeEvent(obj, type, fn) {
try {
if( obj.detachEvent ) {
obj.detachEvent( "on"+type, obj[type+fn] );
obj[type+fn] = null;
} else {
obj.removeEventListener( type, fn, true );
};
} catch(err) {};
};
function stopEvent(e) {
e = e || document.parentWindow.event;
if(e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
};
/*@cc_on
@if(@_win32)
e.cancelBubble = true;
e.returnValue = false;
@end
@*/
return false;
};
function parseJSON(str) {
// Check we have a String
if(typeof str !== 'string' || str == "") { return {}; };
try {
// Does the Douglas Crockford JSON parser exist in the global scope?
if("JSON" in window && "parse" in window.JSON && typeof window.JSON.parse == "function") {
return window.JSON.parse(str);
// Genious code taken from: http://kentbrewster.com/badges/
} else if(/lang|split|formats|nodrag/.test(str.toLower())) {
var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,',
'Array,String,Math,RegExp,Image,ActiveXObject;',
'return (' , str.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function') , ');'].join(''));
return f();
};
} catch (e) {
return {"err":"Trouble parsing JSON object"};
};
return {};
};
function setARIARole(element, role) {
if(element && element.tagName) {
element.setAttribute("role", role);
};
};
function setARIAProperty(element, property, value) {
if(element && element.tagName) {
element.setAttribute("aria-" + property, value);
};
};
// The datePicker object itself
function datePicker(options) {
this.dateSet = null;
this.timerSet = false;
this.visible = false;
this.fadeTimer = null;
this.timer = null;
this.yearInc = 0;
this.monthInc = 0;
this.dayInc = 0;
this.mx = 0;
this.my = 0;
this.x = 0;
this.y = 0;
this.date = new Date();
this.defaults = {};
this.created = false;
this.id = options.id;
this.opacity = 0;
this.firstDayOfWeek = 0;
this.buttonWrapper = "buttonWrapper" in options ? options.buttonWrapper : false;
this.staticPos = "staticPos" in options ? !!options.staticPos : false;
this.disabledDays = "disabledDays" in options && options.disabledDays.length ? options.disabledDays : [0,0,0,0,0,0,0];
this.disabledDates = "disabledDates" in options ? options.disabledDates : {};
this.enabledDates = "enabledDates" in options ? options.enabledDates : {};
this.showWeeks = "showWeeks" in options ? !!options.showWeeks : false;
this.low = options.low || "";
this.high = options.high || "";
this.dragDisabled = nodrag ? true : ("dragDisabled" in options ? !!options.dragDisabled : false);
this.positioned = "positioned" in options ? options.positioned : false;
this.hideInput = this.staticPos ? false : "hideInput" in options ? !!options.hideInput : false;
this.splitDate = "splitDate" in options ? !!options.splitDate : false;
this.format = options.format || "d-sl-m-sl-Y";
this.statusFormat = options.statusFormat || "";
this.cellFormat = options.cellFormat || options.format;
this.highlightDays = options.highlightDays && options.highlightDays.length ? options.highlightDays : [0,0,0,0,0,1,1];
this.noFadeEffect = "noFadeEffect" in options ? !!options.noFadeEffect : false;
this.opacityTo = this.noFadeEffect || this.staticPos ? 99 : 90;
this.callbacks = {};
this.fillGrid = !!options.fillGrid;
this.noToday = !!options.noToday;
this.labelledBy = "labelledBy" in options ? options.labelledBy : "";
this.constrainSelection = this.fillGrid && !!options.constrainSelection;
this.finalOpacity = !this.staticPos && "finalOpacity" in options ? +options.finalOpacity : 90;
this.dynDisabledDates = {};
this.inUpdate = false;
this.noFocus = true;
this.kbEventsAdded = false;
this.fullCreate = false;
this.selectedTD = null;
/*@cc_on
@if(@_win32)
this.interval = new Date();
this.iePopUp = null;
this.isIE7 = false;
@end
@*/
/*@cc_on
@if(@_jscript_version <= 5.7)
this.isIE7 = document.documentElement && typeof document.documentElement.style.maxHeight != "undefined";
@end
@*/
for(var thing in options.callbacks) {
this.callbacks[thing] = options.callbacks[thing];
};
// Adjust time to stop daylight savings madness on windows
this.date.setHours(12);
// Create the format parts for the screen reader
var formatParts = this.cellFormat.split("-");
fullParts = [],
tmpParts = [];
for(var pt = 0; pt < formatParts.length; pt++) {
part = formatParts[pt];
if(part == "j" || part == "d") {
if(tmpParts.length) {
fullParts.push(tmpParts.join("-"));
tmpParts = [];
};
fullParts.push("placeholder");
} else {
tmpParts.push(part);
};
};
if(tmpParts.length) {
fullParts.push(tmpParts.join("-"));
};
if(!fullParts.length || fullParts.length > 3) {
fullParts = ["placeholder", "sp-F-sp-Y"];
};
// Don't use hidden text for opera due to focus outline problems
this.formatParts = window.opera ? ["placeholder"] : fullParts;
this.startDrag = function(e) {
e = e || document.parentWindow.event;
o.mx = e.pageX?e.pageX:e.clientX?e.clientX:e.x;
o.my = e.pageY?e.pageY:e.clientY?e.clientY:e.Y;
o.x = parseInt(o.div.style.left);
o.y = parseInt(o.div.style.top);
addEvent(document,'mousemove',o.trackDrag, false);
addEvent(document,'mouseup',o.stopDrag, false);
o.div.style.zIndex = 10000;
return stopEvent(e);
};
this.trackDrag = function(e) {
e = e || window.event;
var diffx = (e.pageX?e.pageX:e.clientX?e.clientX:e.x) - o.mx;
var diffy = (e.pageY?e.pageY:e.clientY?e.clientY:e.Y) - o.my;
o.div.style.left = Math.round(o.x + diffx) > 0 ? Math.round(o.x + diffx) + 'px' : "0px";
o.div.style.top = Math.round(o.y + diffy) > 0 ? Math.round(o.y + diffy) + 'px' : "0px";
/*@cc_on
@if(@_jscript_version <= 5.7)
if(o.staticPos || o.isIE7) return;
o.iePopUp.style.top = o.div.style.top;
o.iePopUp.style.left = o.div.style.left;
@end
@*/
};
this.stopDrag = function(e) {
removeEvent(document,'mousemove',o.trackDrag, false);
removeEvent(document,'mouseup',o.stopDrag, false);
o.div.style.zIndex = 9999;
};
this.changeHandler = function() {
o.setDateFromInput();
if(o.created) o.updateTable();
};
this.getScrollOffsets = function() {
if(typeof(window.pageYOffset) == 'number' ) {
//Netscape compliant
return [window.pageXOffset, window.pageYOffset];
} else if(document.body && ( document.body.scrollLeft || document.body.scrollTop )) {
//DOM compliant
return [document.body.scrollLeft, document.body.scrollTop];
} else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
//IE6 standards compliant mode
return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
};
return [0,0];
}
this.reposition = function() {
if(!o.created || !o.getElem() || o.staticPos) { return; };
o.div.style.visibility = "hidden";
o.div.style.left = o.div.style.top = "0px";
o.div.style.display = "block";
var osh = o.div.offsetHeight,
osw = o.div.offsetWidth,
elem = document.getElementById('fd-but-' + o.id),
pos = o.truePosition(elem),
trueBody = (document.compatMode && document.compatMode!="BackCompat") ? document.documentElement : document.body,
sOffsets = o.getScrollOffsets(),
scrollTop = sOffsets[1],
scrollLeft = sOffsets[0];
o.div.style.visibility = "visible";
o.div.style.left = Number(parseInt(trueBody.clientWidth+scrollLeft) < parseInt(osw+pos[0]) ? Math.abs(parseInt((trueBody.clientWidth+scrollLeft) - osw)) : pos[0]) + "px";
o.div.style.top = Number(parseInt(trueBody.clientHeight+scrollTop) < parseInt(osh+pos[1]+elem.offsetHeight+2) ? Math.abs(parseInt(pos[1] - (osh + 2))) : Math.abs(parseInt(pos[1] + elem.offsetHeight + 2))) + "px";
/*@cc_on
@if(@_jscript_version <= 5.7)
if(o.isIE7) return;
o.iePopUp.style.top = o.div.style.top;
o.iePopUp.style.left = o.div.style.left;
o.iePopUp.style.width = osw + "px";
o.iePopUp.style.height = (osh - 2) + "px";
@end
@*/
};
this.removeOldFocus = function() {
var td = document.getElementById(o.id + "-date-picker-hover");
if(td) {
try {
td.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", "-1");
td.tabIndex = -1;
td.className = td.className.replace(/date-picker-hover/, "");
td.id = "";
} catch(err) {};
};
};
this.setNewFocus = function() {
var td = document.getElementById(o.id + "-date-picker-hover");
if(td) {
try {
td.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", "0");
td.tabIndex = 0;
td.className = td.className.replace(/date-picker-hover/, "") + " date-picker-hover";
if(!this.noFocus) {
setTimeout(function() { try { td.focus(); } catch(err) {}; }, 0);
};
} catch(err) {};
};
};
this.updateTable = function(noCallback) {
if(o.inUpdate) return;
o.inUpdate = true;
o.removeOldFocus();
if(o.timerSet) {
o.date.setDate(Math.min(o.date.getDate()+o.dayInc, daysInMonth(o.date.getMonth()+o.monthInc,o.date.getFullYear()+o.yearInc)) );
o.date.setMonth(o.date.getMonth() + o.monthInc);
o.date.setFullYear(o.date.getFullYear() + o.yearInc);
};
o.outOfRange();
if(!o.noToday) { o.disableTodayButton(); };
o.showHideButtons(o.date);
var cd = o.date.getDate(),
cm = o.date.getMonth(),
cy = o.date.getFullYear(),
cursorDate = (String(cy) + pad(cm+1) + pad(cd)),
tmpDate = new Date(cy, cm, 1);
tmpDate.setHours(5);
var dt, cName, td, i, currentDate, cellAdded, col, currentStub, abbr, bespokeRenderClass, spnC,
weekDayC = ( tmpDate.getDay() + 6 ) % 7,
firstColIndex = (((weekDayC - o.firstDayOfWeek) + 7 ) % 7) - 1,
dpm = daysInMonth(cm, cy),
today = new Date(),
dateSetD = (o.dateSet != null) ? o.dateSet.getFullYear() + pad(o.dateSet.getMonth()+1) + pad(o.dateSet.getDate()) : false,
stub = String(tmpDate.getFullYear()) + pad(tmpDate.getMonth()+1),
cellAdded = [4,4,4,4,4,4],
lm = new Date(cy, cm-1, 1),
nm = new Date(cy, cm+1, 1),
daySub = daysInMonth(lm.getMonth(), lm.getFullYear()),
stubN = String(nm.getFullYear()) + pad(nm.getMonth()+1),
stubP = String(lm.getFullYear()) + pad(lm.getMonth()+1),
weekDayN = (nm.getDay() + 6) % 7,
weekDayP = (lm.getDay() + 6) % 7,
today = today.getFullYear() + pad(today.getMonth()+1) + pad(today.getDate()),
spn = document.createElement('span'),
titleFormat = o.statusFormat ? o.statusFormat : (o.dateFormat ? o.dateFormat : (o.cellFormat ? o.cellFormat : ""));
o.firstDateShown = !o.constrainSelection && o.fillGrid && (0 - firstColIndex < 1) ? String(stubP) + (daySub + (0 - firstColIndex)) : stub + "01";
o.lastDateShown = !o.constrainSelection && o.fillGrid ? stubN + pad(41 - firstColIndex - dpm) : stub + String(dpm);
o.currentYYYYMM = stub;
bespokeRenderClass = o.callback("redraw", {id:o.id, dd:pad(cd), mm:pad(cm+1), yyyy:cy, firstDateDisplayed:o.firstDateShown, lastDateDisplayed:o.lastDateShown}) || {};
o.dynDisabledDates = o.getDisabledDates(cy, cm + 1);
spn.className = "fd-screen-reader";
if(this.selectedTD != null) {
setARIAProperty(this.selectedTD, "selected", false);
this.selectedTD = null;
};
for(var curr = 0; curr < 42; curr++) {
row = Math.floor(curr / 7);
td = o.tds[curr];
spnC = spn.cloneNode(false);
while(td.firstChild) td.removeChild(td.firstChild);
if((curr > firstColIndex && curr <= (firstColIndex + dpm)) || o.fillGrid) {
currentStub = stub;
weekDay = weekDayC;
dt = curr - firstColIndex;
cName = [];
selectable = true;
if(dt < 1) {
dt = daySub + dt;
currentStub = stubP;
weekDay = weekDayP;
selectable = !o.constrainSelection;
cName.push("month-out");
} else if(dt > dpm) {
dt -= dpm;
currentStub = stubN;
weekDay = weekDayN;
selectable = !o.constrainSelection;
cName.push("month-out");
};
weekDay = ( weekDay + dt + 6 ) % 7;
cName.push("day-" + localeDefaults.dayAbbrs[weekDay].toLowerCase());
//td.appendChild(document.createTextNode(dt));
currentDate = currentStub + String(dt < 10 ? "0" : "") + dt;
if(o.low && +currentDate < +o.low || o.high && +currentDate > +o.high) {
td.className = "out-of-range";
td.title = "";
td.appendChild(document.createTextNode(dt));
if(o.showWeeks) { cellAdded[row] = Math.min(cellAdded[row], 2); };
} else {
if(selectable) {
td.title = titleFormat ? printFormattedDate(new Date(+String(currentStub).substr(0,4), +String(currentStub).substr(4, 2) - 1, +dt), titleFormat, true) : "";
cName.push("cd-" + currentDate + " yyyymm-" + currentStub + " mmdd-" + currentStub.substr(4,2) + pad(dt));
} else {
td.title = titleFormat ? getTitleTranslation(13) + " " + printFormattedDate(new Date(+String(currentStub).substr(0,4), +String(currentStub).substr(4, 2) - 1, +dt), titleFormat, true) : "";
cName.push("yyyymm-" + currentStub + " mmdd-" + currentStub.substr(4,2) + pad(dt) + " not-selectable");
};
if(currentDate == today) { cName.push("date-picker-today"); };
if(dateSetD == currentDate) {
cName.push("date-picker-selected-date");
setARIAProperty(td, "selected", "true");
this.selectedTD = td;
};
if(o.disabledDays[weekDay] || currentDate in o.dynDisabledDates) { cName.push("day-disabled"); if(titleFormat && selectable) { td.title = getTitleTranslation(13) + " " + td.title; }; }
if(currentDate in bespokeRenderClass) { cName.push(bespokeRenderClass[currentDate]); }
if(o.highlightDays[weekDay]) { cName.push("date-picker-highlight"); };
if(cursorDate == currentDate) {
td.id = o.id + "-date-picker-hover";
};
td.className = cName.join(" ");
for(var pt = 0, part; part = o.formatParts[pt]; pt++) {
if(part == "placeholder") {
td.appendChild(document.createTextNode(dt));
} else {
spnC = spn.cloneNode(spn);
spnC.appendChild(document.createTextNode(printFormattedDate(new Date(+String(currentStub).substr(0,4), +String(currentStub).substr(4, 2) - 1, +dt), part, true)));
td.appendChild(spnC);
};
};
if(o.showWeeks) {
cellAdded[row] = Math.min(cName[0] == "month-out" ? 3 : 1, cellAdded[row]);
};
};
} else {
td.className = "date-picker-unused";
td.appendChild(document.createTextNode(nbsp));
td.title = "";
};
if(o.showWeeks && curr - (row * 7) == 6) {
while(o.wkThs[row].firstChild) o.wkThs[row].removeChild(o.wkThs[row].firstChild);
o.wkThs[row].appendChild(document.createTextNode(cellAdded[row] == 4 && !o.fillGrid ? nbsp : getWeekNumber(cy, cm, curr - firstColIndex - 6)));
o.wkThs[row].className = "date-picker-week-header" + (["",""," out-of-range"," month-out",""][cellAdded[row]]);
};
};
// Title Bar
var span = o.titleBar.getElementsByTagName("span");
while(span[0].firstChild) span[0].removeChild(span[0].firstChild);
while(span[1].firstChild) span[1].removeChild(span[1].firstChild);
span[0].appendChild(document.createTextNode(getMonthTranslation(cm, false) + nbsp));
span[1].appendChild(document.createTextNode(cy));
if(o.timerSet) {
o.timerInc = 50 + Math.round(((o.timerInc - 50) / 1.8));
o.timer = window.setTimeout(o.updateTable, o.timerInc);
};
o.inUpdate = false;
o.setNewFocus();
};
this.show = function(autoFocus) {
if(this.staticPos) { return; };
var elem = this.getElem();
if(!elem || (elem && elem.disabled)) { return; };
autoFocus = !!autoFocus;
if(!document.getElementById('fd-' + this.id)) {
this.created = false;
this.fullCreate = false;
this.noFocus = true;
this.create();
this.fullCreate = true;
} else {
this.noFocus = autoFocus;
this.setDateFromInput();
this.updateTable();
};
if(!this.staticPos) this.reposition();
addEvent(document, "mousedown", this.events.onmousedown);
this.opacityTo = this.finalOpacity;
this.div.style.display = "block";
/*@cc_on
@if(@_jscript_version <= 5.7)
if(!o.isIE7) {
this.iePopUp.style.width = this.div.offsetWidth + "px";
this.iePopUp.style.height = this.div.offsetHeight + "px";
this.iePopUp.style.display = "block";
};
@end
@*/
this.noFocus = !autoFocus;
this.addKeyboardEvents();
this.setNewFocus();
this.fade();
var butt = document.getElementById('fd-but-' + this.id);
if(butt) butt.className = butt.className.replace("dp-button-active", "") + " dp-button-active";
};
this.hide = function() {
if(!this.visible || !this.created || !document.getElementById('fd-' + this.id)) return;
this.stopTimer();
this.removeKeyboardEvents();
if(this.staticPos) { return; };
var butt = document.getElementById('fd-but-' + this.id);
if(butt) butt.className = butt.className.replace("dp-button-active", "");
removeEvent(document, "mousedown", this.events.onmousedown);
removeEvent(document, "mouseup", this.events.clearTimer);
/*@cc_on
@if(@_jscript_version <= 5.7)
if(!this.isIE7) { this.iePopUp.style.display = "none"; };
@end
@*/
this.opacityTo = 0;
this.fade();
// Programmatically remove the focus style on the calendar
this.div.className = this.div.className.replace("datepicker-focus", "");
// Update status bar
if(this.statusBar) { this.updateStatus(getTitleTranslation(9)); };
};
this.destroy = function() {
// Cleanup for Internet Explorer
removeEvent(this.staticPos ? this.table : document, "mousedown", o.events.onmousedown);
removeEvent(document, "mouseup", o.events.clearTimer);
o.removeKeyboardEvents();
clearTimeout(o.fadeTimer);
clearTimeout(o.timer);
/*@cc_on
@if(@_jscript_version <= 5.7)
if(!o.staticPos && !o.isIE7) {
o.iePopUp.parentNode.removeChild(o.iePopUp);
o.iePopUp = null;
};
@end
@*/
if(!this.staticPos && document.getElementById(this.id.replace(/^fd-/, 'fd-but-'))) {
var butt = document.getElementById(this.id.replace(/^fd-/, 'fd-but-'));
butt.onclick = butt.onpress = null;
};
if(this.div && this.div.parentNode) {
this.div.parentNode.removeChild(this.div);
};
o = null;
};
this.resizeInlineDiv = function() {
o.div.style.width = o.table.offsetWidth + "px";
o.div.style.height = o.table.offsetHeight + "px";
};
this.create = function() {
if(this.created) { return; };
this.noFocus = true;
function createTH(details) {
var th = document.createElement('th');
if(details.thClassName) th.className = details.thClassName;
if(details.colspan) {
/*@cc_on
/*@if (@_win32)
th.setAttribute('colSpan',details.colspan);
@else @*/
th.setAttribute('colspan',details.colspan);
/*@end
@*/
};
/*@cc_on
/*@if (@_win32)
th.unselectable = "on";
/*@end@*/
return th;
};
function createThAndButton(tr, obj) {
for(var i = 0, details; details = obj[i]; i++) {
var th = createTH(details);
tr.appendChild(th);
var but = document.createElement('span');
but.className = details.className;
but.id = o.id + details.id;
but.appendChild(document.createTextNode(details.text || o.nbsp));
but.title = details.title || "";
if(details.onmousedown) but.onmousedown = details.onmousedown;
if(details.onclick) but.onclick = details.onclick;
if(details.onmouseout) but.onmouseout = details.onmouseout;
/*@cc_on
/*@if(@_win32)
th.unselectable = but.unselectable = "on";
/*@end@*/
th.appendChild(but);
};
};
this.div = document.createElement('div');
this.div.id = "fd-" + this.id;
this.div.className = "datePicker";
// Attempt to hide the div from screen readers during content creation
this.div.style.visibility = "hidden";
this.div.style.display = "none";
// Set the ARIA describedby property if the required block available
if(document.getElementById("fd-datepicker-aria-describedby")) {
setARIAProperty(this.div, "describedby", "fd-datepicker-aria-describedby");
};
// Set the ARIA labelled property if the required label available
if(this.labelledBy) {
setARIAProperty(this.div, "labelledby", this.labelledBy);
};
var tr, row, col, tableHead, tableBody, tableFoot;
this.table = document.createElement('table');
this.table.className = "datePickerTable";
this.table.onmouseover = this.events.ontablemouseover;
this.table.onmouseout = this.events.ontablemouseout;
this.div.appendChild(this.table);
if(!this.staticPos) {
this.div.style.visibility = "hidden";
if(!this.dragDisabled) { this.div.className += " drag-enabled"; };
document.getElementsByTagName('body')[0].appendChild(this.div);
/*@cc_on
@if(@_jscript_version <= 5.7)
if(!this.isIE7) {
this.iePopUp = document.createElement('iframe');
this.iePopUp.src = "javascript:'';";
this.iePopUp.setAttribute('className','iehack');
// Remove iFrame from tabIndex
this.iePopUp.setAttribute("tabIndex", -1);
// Hide it from ARIA aware technologies
setARIARole(this.iePopUp, "presentation");
setARIAProperty(this.iePopUp, "hidden", "true");
this.iePopUp.scrolling = "no";
this.iePopUp.frameBorder = "0";
this.iePopUp.name = this.iePopUp.id = this.id + "-iePopUpHack";
document.body.appendChild(this.iePopUp);
};
@end
@*/
// Aria "hidden" property for non active popup datepickers
setARIAProperty(this.div, "hidden", "true");
} else {
elem = this.positioned ? document.getElementById(this.positioned) : this.getElem();
if(!elem) {
this.div = null;
throw this.positioned ? "Could not locate a datePickers associated parent element with an id:" + this.positioned : "Could not locate a datePickers associated input with an id:" + this.id;
};
this.div.className += " static-datepicker";
if(this.positioned) {
elem.appendChild(this.div);
} else {
elem.parentNode.insertBefore(this.div, elem.nextSibling);
};
if(this.hideInput) {
var elemList = [elem];
if(this.splitDate) {
elemList[elemList.length] = document.getElementById(this.id + splitAppend[1]);
elemList[elemList.length] = document.getElementById(this.id + splitAppend[0]);
};
for(var i = 0; i < elemList.length; i++) {
if(elemList[i].tagName) elemList[i].className += " fd-hidden-input";
};
};
setTimeout(this.resizeInlineDiv, 300);
};
// ARIA Grid role
setARIARole(this.div, "grid");
if(this.statusFormat) {
tableFoot = document.createElement('tfoot');
this.table.appendChild(tableFoot);
tr = document.createElement('tr');
tr.className = "date-picker-tfoot";
tableFoot.appendChild(tr);
this.statusBar = createTH({thClassName:"date-picker-statusbar", colspan:this.showWeeks ? 8 : 7});
tr.appendChild(this.statusBar);
this.updateStatus();
if(!this.dragDisabled) {
this.statusBar.className += " drag-enabled";
addEvent(this.statusBar,'mousedown',this.startDrag,false);
};
};
tableHead = document.createElement('thead');
this.table.appendChild(tableHead);
tr = document.createElement('tr');
setARIARole(tr, "presentation");
tableHead.appendChild(tr);
// Title Bar
this.titleBar = createTH({thClassName:!this.dragDisabled ? "date-picker-title drag-enabled" : "date-picker-title", colspan:this.showWeeks ? 8 : 7});
if(!this.dragDisabled) {
addEvent(this.titleBar,'mousedown',o.startDrag,false);
};
tr.appendChild(this.titleBar);
tr = null;
var span = document.createElement('span');
span.appendChild(document.createTextNode(nbsp));
span.className = !this.dragDisabled ? "month-display drag-enabled" : "month-display";
this.titleBar.appendChild(span);
span = document.createElement('span');
span.appendChild(document.createTextNode(nbsp));
span.className = !this.dragDisabled ? "year-display drag-enabled" : "year-display";
this.titleBar.appendChild(span);
span = null;
tr = document.createElement('tr');
setARIARole(tr, "presentation");
tableHead.appendChild(tr);
createThAndButton(tr, [
{className:"prev-but prev-year", id:"-prev-year-but", text:"\u00AB", title:getTitleTranslation(2), onmousedown:function(e) { addEvent(document, "mouseup", o.events.clearTimer); o.events.incDec(e,0,-1,0); }, onmouseout:this.events.clearTimer },
{className:"prev-but prev-month", id:"-prev-month-but", text:"\u2039", title:getTitleTranslation(0), onmousedown:function(e) { addEvent(document, "mouseup", o.events.clearTimer); if(o.currentYYYYMM > Number(o.date.getFullYear() + pad(o.date.getMonth()+1))) { o.stopTimer(); o.updateTable(); o.timer = window.setTimeout(function() { o.events.incDec(e,0,0,-1); }, 800); return; }; o.events.incDec(e,0,0,-1); }, onmouseout:this.events.clearTimer },
{colspan:this.showWeeks ? 4 : 3, className:"today-but", id:"-today-but", text:getTitleTranslation(4), onmousedown:function(e) { return true; }, onclick:function(e) { o.date = new Date(); o.updateTable(); }},
{className:"next-but next-month", id:"-next-month-but", text:"\u203A", title:getTitleTranslation(1), onmousedown:function(e) { addEvent(document, "mouseup", o.events.clearTimer); if(o.currentYYYYMM < Number(o.date.getFullYear() + pad(o.date.getMonth()+1))) { o.stopTimer(); o.updateTable(); o.timer = window.setTimeout(function() { o.events.incDec(e,0,0,1); }, 800); return; }; o.events.incDec(e,0,0,1); }, onmouseout:this.events.clearTimer },
{className:"next-but next-year", id:"-next-year-but", text:"\u00BB", title:getTitleTranslation(3), onmousedown:function(e) { addEvent(document, "mouseup", o.events.clearTimer); o.events.incDec(e,0,1,0); }, onmouseout:this.events.clearTimer }]);
tableBody = document.createElement('tbody');
this.table.appendChild(tableBody);
var colspanTotal = this.showWeeks ? 8 : 7,
colOffset = this.showWeeks ? 0 : -1,
but, abbr;
for(var rows = 0; rows < 7; rows++) {
row = document.createElement('tr');
if(rows != 0) {
// ARIA Grid role
setARIARole(row, "row");
tableBody.appendChild(row);
} else {
tableHead.appendChild(row);
};
for(var cols = 0; cols < colspanTotal; cols++) {
if(rows === 0 || (this.showWeeks && cols === 0)) {
col = document.createElement('th');
} else {
col = document.createElement('td');
col.onblur = this.events.onCellBlur;
col.onfocus = this.events.onCellFocus;
setARIAProperty(col, "describedby", "col-" + cols + (this.showWeeks ? " row-" + rows : ""));
setARIAProperty(col, "selected", "false");
};
/*@cc_on@*/
/*@if(@_win32)
col.unselectable = "on";
/*@end@*/
row.appendChild(col);
if((this.showWeeks && cols > 0 && rows > 0) || (!this.showWeeks && rows > 0)) {
col.onclick = this.events.onclick;
setARIARole(col, "gridcell");
} else {
if(rows === 0 && cols > colOffset) {
col.className = "date-picker-day-header";
col.scope = "col";
setARIARole(col, "columnheader");
col.id = "col-" + cols;
} else {
col.className = "date-picker-week-header";
col.scope = "row";
setARIARole(col, "rowheader");
col.id = "row-" + row;
};
};
};
};
col = row = null;
this.ths = this.table.getElementsByTagName('thead')[0].getElementsByTagName('tr')[2].getElementsByTagName('th');
for (var y = 0; y < colspanTotal; y++) {
if(y == 0 && this.showWeeks) {
this.ths[y].appendChild(document.createTextNode(getTitleTranslation(6)));
this.ths[y].title = getTitleTranslation(8);
continue;
};
if(y > (this.showWeeks ? 0 : -1)) {
but = document.createElement("span");
but.className = "fd-day-header";
but.onclick = this.ths[y].onclick = this.setFirstDayOfWeek;
/*@cc_on@*/
/*@if(@_win32)
but.unselectable = "on";
/*@end@*/
this.ths[y].appendChild(but);
};
};
but = null;
this.trs = this.table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
this.tds = this.table.getElementsByTagName('tbody')[0].getElementsByTagName('td');
this.butPrevYear = document.getElementById(this.id + "-prev-year-but");
this.butPrevMonth = document.getElementById(this.id + "-prev-month-but");
this.butToday = document.getElementById(this.id + "-today-but");
this.butNextYear = document.getElementById(this.id + "-next-year-but");
this.butNextMonth = document.getElementById(this.id + "-next-month-but");
if(this.noToday) {
this.butToday.style.display = "none";
};
if(this.showWeeks) {
this.wkThs = this.table.getElementsByTagName('tbody')[0].getElementsByTagName('th');
this.div.className += " weeks-displayed";
};
tableBody = tableHead = tr = createThAndButton = createTH = null;
if(this.low && this.high && (this.high - this.low < 7)) { this.equaliseDates(); };
this.setDateFromInput();
this.updateTableHeaders();
this.created = true;
this.callback("create", {id:this.id});
this.updateTable();
if(this.staticPos) {
this.visible = true;
this.opacity = this.opacityTo;
this.div.style.visibility = "visible";
// Attempt to reshow the div
this.div.style.display = "block";
this.fade();
} else {
this.reposition();
this.div.style.visibility = "visible";
this.fade();
};
this.noFocus = false;
};
this.setFirstDayOfWeek = function(e) {
e = e || document.parentWindow.event;
var elem = e.target != null ? e.target : e.srcElement;
while(elem.tagName.toLowerCase() != "th") elem = elem.parentNode;
var cnt = o.showWeeks ? -1 : 0;
while(elem.previousSibling) {
elem = elem.previousSibling;
if(elem.tagName.toLowerCase() == "th") cnt++;
};
o.firstDayOfWeek = (o.firstDayOfWeek + cnt) % 7;
o.updateTableHeaders();
return stopEvent(e);
};
this.fade = function() {
window.clearTimeout(o.fadeTimer);
o.fadeTimer = null;
var diff = Math.round(o.opacity + ((o.opacityTo - o.opacity) / 4));
o.setOpacity(diff);
if(Math.abs(o.opacityTo - diff) > 3 && !o.noFadeEffect) {
o.fadeTimer = window.setTimeout(o.fade, 50);
} else {
o.setOpacity(o.opacityTo);
if(o.opacityTo == 0) {
o.div.style.display = "none";
o.div.style.visibility = "hidden";
setARIAProperty(o.div, "hidden", "true");
o.visible = false;
} else {
setARIAProperty(o.div, "hidden", "false");
o.visible = true;
};
};
};
this.events = {
onCellBlur:function(e) {
e = e || document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
while(el.parentNode) {
if(el.id && el.id == "fd-" + o.id) {
return true;
};
try { el = el.parentNode; } catch(err) { break; };
};
// If a popup datepicker then hide it
if(!o.staticPos) {
o.hide();
return;
};
// Remove the keyboard events from the document
o.removeKeyboardEvents();
// Programmatically remove the focus style on the calendar
o.div.className = o.div.className.replace("datepicker-focus", "");
// Update status bar
if(o.statusBar) { o.updateStatus(getTitleTranslation(9)); };
},
onCellFocus:function(e) {
// Add the keyboard events
//if(this.staticPos) this.noFocus = false;
o.addKeyboardEvents();
},
onkeydown: function (e) {
o.stopTimer();
if(!o.visible) return false;
if(e == null) e = document.parentWindow.event;
var kc = e.keyCode ? e.keyCode : e.charCode;
if( kc == 13 ) {
// RETURN/ENTER: close & select the date
var td = document.getElementById(o.id + "-date-picker-hover");
if(!td || td.className.search(/cd-([0-9]{8})/) == -1 || td.className.search(/no-selection|out-of-range|day-disabled/) != -1) {
return stopEvent(e);
};
o.dateSet = new Date(o.date);
o.returnFormattedDate();
o.hide();
return stopEvent(e);
} else if(kc == 27) {
// ESC: close, no date selection
o.hide();
return stopEvent(e);
} else if(kc == 32 || kc == 0) {
// SPACE: goto today's date
o.date = new Date();
o.updateTable();
return stopEvent(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() < 50) { return stopEvent(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.updateTableHeaders();
return stopEvent(e);
};
if ( kc < 33 || kc > 40 ) return true;
var d = new Date(o.date), tmp, cursorYYYYMM = o.date.getFullYear() + pad(o.date.getMonth()+1);
// HOME: Set date to first day of current month
if(kc == 36) {
d.setDate(1);
// END: Set date to last day of current month
} else if(kc == 35) {
d.setDate(daysInMonth(d.getMonth(),d.getFullYear()));
// PAGE UP & DOWN
} else if ( kc == 33 || kc == 34) {
var add = (kc == 34) ? 1 : -1;
// CTRL + PAGE UP/DOWN: Moves to the same date in the previous/next year
if(e.ctrlKey) {
d.setFullYear(d.getFullYear() + add);
// PAGE UP/DOWN: Moves to the same date in the previous/next month
} else {
if(!((kc == 33 && o.currentYYYYMM > cursorYYYYMM) || (kc == 34 && o.currentYYYYMM < cursorYYYYMM))) {
tmp = new Date(d);
tmp.setDate(2);
tmp.setMonth(d.getMonth() + add);
d.setDate(Math.min(d.getDate(), daysInMonth(tmp.getMonth(),tmp.getFullYear())));
d.setMonth(d.getMonth() + add);
};
};
// LEFT ARROW
} else if ( kc == 37 ) {
d = new Date(o.date.getFullYear(), o.date.getMonth(), o.date.getDate() - 1);
// RIGHT ARROW
} else if ( kc == 39 || kc == 34) {
d = new Date(o.date.getFullYear(), o.date.getMonth(), o.date.getDate() + 1 );
// UP ARROW
} else if ( kc == 38 ) {
d = new Date(o.date.getFullYear(), o.date.getMonth(), o.date.getDate() - 7);
// DOWN ARROW
} else if ( kc == 40 ) {
d = new Date(o.date.getFullYear(), o.date.getMonth(), o.date.getDate() + 7);
};
if(o.outOfRange(d)) return stopEvent(e);
o.date = d;
if(o.statusBar) { o.updateStatus(printFormattedDate(o.date, o.statusFormat, true)); };
var t = String(o.date.getFullYear()) + pad(o.date.getMonth()+1) + pad(o.date.getDate())
if(e.ctrlKey || (kc == 33 || kc == 34) || t < o.firstDateShown || t > o.lastDateShown) {
o.updateTable();
/*@cc_on
@if(@_win32)
o.interval = new Date();
@end
@*/
} else {
if(!o.noToday) { o.disableTodayButton(); }
o.removeOldFocus();
var dt = "cd-" + o.date.getFullYear() + pad(o.date.getMonth()+1) + pad(o.date.getDate());
for(var i = 0, td; td = o.tds[i]; i++) {
if(td.className.search(dt) == -1) {
continue;
};
o.showHideButtons(o.date);
td.id = o.id + "-date-picker-hover";
o.setNewFocus();
break;
};
};
return stopEvent(e);
},
gotoToday: function(e) {
o.date = new Date();
o.updateTable();
return true;
},
onmousedown: function(e) {
e = e || document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
while(el.parentNode) {
if(el.id && (el.id == "fd-" + o.id || el.id == "fd-but-" + o.id)) {
return true;
};
try { el = el.parentNode; } catch(err) { break; };
};
o.removeKeyboardEvents();
o.stopTimer();
hideAll();
return stopEvent(e);
},
ontablemouseout:function(e) {
e = e || document.parentWindow.event;
var p = e.toElement || e.relatedTarget;
while (p && p != this) try { p = p.parentNode } catch(e) { p = this; };
if (p == this) return false;
if(o.currentTR) {
o.currentTR.className = "";
o.currentTR = null;
};
if(o.statusBar) { o.updateStatus(printFormattedDate(o.date, o.statusFormat, true)); };
o.noFocus = o.staticPos ? false : true;
},
ontablemouseover: function(e) {
e = e || document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
while(el.nodeType != 1) { el = el.parentNode; };
if(!el || ! el.tagName) { return; };
o.noFocus = true;
o.removeKeyboardEvents();
var statusText = getTitleTranslation(9);
switch (el.tagName.toLowerCase()) {
case "td":
if(el.className.search(/date-picker-unused|out-of-range/) != -1) {
statusText = getTitleTranslation(9);
} if(el.className.search(/cd-([0-9]{8})/) != -1) {
o.stopTimer();
var cellDate = el.className.match(/cd-([0-9]{8})/)[1];
o.removeOldFocus();
el.id = o.id+"-date-picker-hover";
o.setNewFocus();
o.date = new Date(+cellDate.substr(0,4),+cellDate.substr(4,2)-1,+cellDate.substr(6,2));
if(!o.noToday) { o.disableTodayButton(); };
statusText = printFormattedDate(o.date, o.statusFormat, true);
};
break;
case "th":
if(!o.statusBar) { break; };
if(el.className.search(/drag-enabled/) != -1) {
statusText = getTitleTranslation(10);
} else if(el.className.search(/date-picker-week-header/) != -1) {
var txt = el.firstChild ? el.firstChild.nodeValue : "";
statusText = txt.search(/^(\d+)$/) != -1 ? getTitleTranslation(7, [txt, txt < 3 && o.date.getMonth() == 11 ? getWeeksInYear(o.date.getFullYear()) + 1 : getWeeksInYear(o.date.getFullYear())]) : getTitleTranslation(9);
};
break;
case "span":
if(!o.statusBar) { break; };
if(el.className.search(/drag-enabled/) != -1) {
statusText = getTitleTranslation(10);
} else if(el.className.search(/day-([0-6])/) != -1) {
var day = el.className.match(/day-([0-6])/)[1];
statusText = getTitleTranslation(11, [getDayTranslation(day, false)]);
} else if(el.className.search(/prev-year/) != -1) {
statusText = getTitleTranslation(2);
} else if(el.className.search(/prev-month/) != -1) {
statusText = getTitleTranslation(0);
} else if(el.className.search(/next-year/) != -1) {
statusText = getTitleTranslation(3);
} else if(el.className.search(/next-month/) != -1) {
statusText = getTitleTranslation(1);
} else if(el.className.search(/today-but/) != -1 && el.className.search(/disabled/) == -1) {
statusText = getTitleTranslation(12);
};
break;
default:
statusText = "";
};
while(el.parentNode) {
el = el.parentNode;
if(el.nodeType == 1 && el.tagName.toLowerCase() == "tr") {
if(o.currentTR) {
if(el == o.currentTR) break;
o.currentTR.className = "";
};
el.className = "dp-row-highlight";
o.currentTR = el;
break;
};
};
if(o.statusBar && statusText) { o.updateStatus(statusText); };
},
onclick: function(e) {
o.removeKeyboardEvents();
if(o.opacity != o.opacityTo || this.className.search(/date-picker-unused|out-of-range|day-disabled|no-selection|not-selectable/) != -1) return stopEvent(e);
e = e || document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
while (el.nodeType != 1 || (el.tagName && el.tagName != "TD")) el = el.parentNode;
if(el.className.search(/cd-([0-9]{8})/) == -1) { return true; };
var cellDate = el.className.match(/cd-([0-9]{8})/)[1];
o.date = new Date(cellDate.substr(0,4),cellDate.substr(4,2)-1,cellDate.substr(6,2));
o.dateSet = new Date(o.date);
o.returnFormattedDate();
if(!o.staticPos) { o.hide(); };
o.stopTimer();
return stopEvent(e);
},
incDec: function(e) {
e = e || document.parentWindow.event;
var el = e.target != null ? e.target : e.srcElement;
if(el && el.className && el.className.search('fd-disabled') != -1) { return false; }
o.timerInc = 800;
o.dayInc = arguments[1];
o.yearInc = arguments[2];
o.monthInc = arguments[3];
o.timerSet = true;
o.updateTable();
return true;
},
clearTimer: function(e) {
o.stopTimer();
o.timerInc = 800;
o.yearInc = 0;
o.monthInc = 0;
o.dayInc = 0;
removeEvent(document, "mouseup", o.events.clearTimer);
}
};
var o = this;
(function() {
var elem = o.getElem();
if(elem && elem.tagName && elem.tagName.search(/select|input/i) != -1) {
addEvent(elem, "change", o.changeHandler);
if(this.splitDate) {
addEvent(document.getElementById(o.id + splitAppend[1]), "change", o.changeHandler);
addEvent(document.getElementById(o.id + splitAppend[0]), "change", o.changeHandler);
};
};
})();
if(this.staticPos) {
this.create();
this.setDateFromInput();
} else {
this.createButton();
this.setDateFromInput();
};
// We have fully created the datepicker...
this.fullCreate = true;
};
datePicker.prototype.createButton = function() {
if(this.staticPos || document.getElementById("fd-but-" + this.id)) { return; };
var inp = this.getElem(),
span = document.createElement('span'),
but = document.createElement('a');
but.href = "#" + this.id;
but.className = "date-picker-control";
but.title = getTitleTranslation(5);
but.id = "fd-but-" + this.id;
span.appendChild(document.createTextNode(nbsp));
but.appendChild(span);
span = document.createElement('span');
span.className = "fd-screen-reader";
span.appendChild(document.createTextNode(but.title));
but.appendChild(span);
// Set the ARIA role to be "button"
setARIARole(but, "button");
// Set a "haspopup" ARIA property - should this not be a list if ID's????
setARIAProperty(but, "haspopup", true);
if(this.buttonWrapper && document.getElementById(this.buttonWrapper)) {
document.getElementById(this.buttonWrapper).appendChild(but);
} else if(inp.nextSibling) {
inp.parentNode.insertBefore(but, inp.nextSibling);
} else {
inp.parentNode.appendChild(but);
};
but.onkeydown = but.onclick = function(e) {
e = e || window.event;
var inpId = this.id.replace('fd-but-',''),
dpVisible = isVisible(inpId),
autoFocus = false;
if(e.type == "keydown") {
var kc = e.keyCode != null ? e.keyCode : e.charCode;
if(kc != 13) return true;
if(dpVisible) {
this.className = this.className.replace("dp-button-active", "");
datePickerController.hideAll();
return false;
};
autoFocus = true;
};
this.className = this.className.replace("dp-button-active", "");
if(!dpVisible) {
this.className += " dp-button-active";
hideAll(inpId);
showDatePicker(inpId, autoFocus);
} else {
hideAll();
};
return false;
};
but = null;
};
datePicker.prototype.setRangeLow = function(range) {
this.low = (String(range).search(/^(\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) ? false : range;
this.checkSelectedDate();
if(this.created) { this.updateTable(); };
};
datePicker.prototype.setRangeHigh = function(range) {
this.high = (String(range).search(/^(\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) ? false : range;
this.checkSelectedDate();
if(this.created) { this.updateTable(); };
};
datePicker.prototype.setDisabledDays = function(dayArray) {
this.disabledDays = dayArray;
this.checkSelectedDate();
if(this.created) { this.updateTable(); };
};
datePicker.prototype.setDisabledDates = function(dateArray) {
this.disabledDates = {};
this.addDisabledDates(dateArray);
};
datePicker.prototype.addDisabledDates = function(dateArray) {
var disabledDateObj = {};
if(typeof dateArray !== "object") dateArray = [dateArray];
for(var i = dateArray.length; i-- ;) {
if(dateArray[i].match(/^(\d\d\d\d|\*\*\*\*)(0[1-9]|1[012]|\*\*)(0[1-9]|[12][0-9]|3[01])$/) != -1) {
this.disabledDates[dateArray[i]] = 1;
};
};
this.checkSelectedDate();
if(this.created) { this.updateTable(); };
};
datePicker.prototype.checkSelectedDate = function() {
if(!this.dateSet) return;
if(!this.canDateBeSelected(this.dateSet)) {
this.dateSet = null;
};
};
datePicker.prototype.addKeyboardEvents = function() {
if(this.kbEventsAdded || this.noFocus) {
return;
};
this.div.className = this.div.className.replace(/datepicker-focus/, "") + " datepicker-focus";
addEvent(document, "keypress", this.events.onkeydown);
/*@cc_on
@if(@_win32)
removeEvent(document, "keypress", this.events.onkeydown);
addEvent(document, "keydown", this.events.onkeydown);
@end
@*/
if(window.devicePixelRatio) {
removeEvent(document, "keypress", this.events.onkeydown);
addEvent(document, "keydown", this.events.onkeydown);
};
this.kbEventsAdded = true;
};
datePicker.prototype.removeKeyboardEvents = function() {
if(!this.kbEventsAdded) return;
this.div.className = this.div.className.replace(/datepicker-focus/, "");
removeEvent(document, "keypress", this.events.onkeydown);
removeEvent(document, "keydown", this.events.onkeydown);
this.kbEventsAdded = false;
};
datePicker.prototype.stopTimer = function() {
this.timerSet = false;
window.clearTimeout(this.timer);
};
datePicker.prototype.setOpacity = function(op) {
this.div.style.opacity = op/100;
this.div.style.filter = 'alpha(opacity=' + op + ')';
this.opacity = op;
};
datePicker.prototype.getElem = function() {
return document.getElementById(this.id.replace(/^fd-/, '')) || false;
};
datePicker.prototype.getDisabledDates = function(y, m) {
m = pad(m);
var obj = {},
lower = this.firstDateShown,
upper = this.lastDateShown,
dt1, dt2, rngLower, rngUpper;
if(!upper || !lower) {
lower = this.firstDateShown = y + pad(m) + "01";
upper = this.lastDateShown = y + pad(m) + pad(daysInMonth(m, y));
};
for(var dt in this.disabledDates) {
dt1 = dt.replace(/^(\*\*\*\*)/, y).replace(/^(\d\d\d\d)(\*\*)/, "$1"+m);
dt2 = this.disabledDates[dt];
if(dt2 == 1) {
if(+lower <= +dt1 && +upper >= +dt1) {
obj[dt1] = 1;
};
continue;
};
// Range of disabled dates
if(Number(dt1.substr(0,6)) <= +String(this.firstDateShown).substr(0,6) && Number(dt2.substr(0,6)) >= +String(this.lastDateShown).substr(0,6)) {
// Same month
if(Number(dt1.substr(0,6)) == Number(dt2.substr(0,6))) {
for(var i = dt1; i <= dt2; i++) {
obj[i] = 1;
};
continue;
};
// Different months but we only want this month
rngLower = Number(dt1.substr(0,6)) == +String(this.firstDateShown).substr(0,6) ? dt1 : lower;
rngUpper = Number(dt2.substr(0,6)) == +String(this.lastDateShown).substr(0,6) ? dt2 : upper;
for(var i = +rngLower; i <= +rngUpper; i++) {
obj[i] = 1;
};
};
};
for(dt in this.enabledDates) {
dt1 = dt.replace(/^(\*\*\*\*)/, y).replace(/^(\d\d\d\d)(\*\*)/, "$1"+m);
dt2 = this.enabledDates[dt];
if(dt2 == 1) {
if(dt1 in obj) {
obj[dt1] = null;
delete obj[dt1];
};
continue;
};
// Range
if(Number(dt1.substr(0,6)) <= +String(this.firstDateShown).substr(0,6) && Number(dt2.substr(0,6)) >= +String(this.lastDateShown).substr(0,6)) {
// Same month
if(Number(dt1.substr(0,6)) == Number(dt2.substr(0,6))) {
for(var i = dt1; i <= dt2; i++) {
if(i in obj) {
obj[i] = null;
delete obj[i];
};
};
continue;
};
// Different months but we only want this month
rngLower = Number(dt1.substr(0,6)) == +String(this.firstDateShown).substr(0,6) ? dt1 : lower;
rngUpper = Number(dt2.substr(0,6)) == +String(this.lastDateShown).substr(0,6) ? dt2 : upper;
for(var i = +rngLower; i <= +rngUpper; i++) {
if(i in obj) {
obj[i] = null;
delete obj[i];
};
};
};
};
return obj;
};
datePicker.prototype.truePosition = function(element) {
var pos = this.cumulativeOffset(element);
if(window.opera) { return pos; };
var iebody = (document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body,
dsocleft = document.all ? iebody.scrollLeft : window.pageXOffset,
dsoctop = document.all ? iebody.scrollTop : window.pageYOffset,
posReal = this.realOffset(element);
return [pos[0] - posReal[0] + dsocleft, pos[1] - posReal[1] + dsoctop];
};
datePicker.prototype.realOffset = function(element) {
var t = 0, l = 0;
do {
t += element.scrollTop || 0;
l += element.scrollLeft || 0;
element = element.parentNode;
} while(element);
return [l, t];
};
datePicker.prototype.cumulativeOffset = function(element) {
var t = 0, l = 0;
do {
t += element.offsetTop || 0;
l += element.offsetLeft || 0;
element = element.offsetParent;
} while(element);
return [l, t];
};
datePicker.prototype.equaliseDates = function() {
var clearDayFound = false, tmpDate;
for(var i = this.low; i <= this.high; i++) {
tmpDate = String(i);
if(!this.disabledDays[new Date(tmpDate.substr(0,4), tmpDate.substr(6,2), tmpDate.substr(4,2)).getDay() - 1]) {
clearDayFound = true;
break;
};
};
if(!clearDayFound) { this.disabledDays = [0,0,0,0,0,0,0] };
};
datePicker.prototype.outOfRange = function(tmpDate) {
if(!this.low && !this.high) { return false; };
var level = false;
if(!tmpDate) {
level = true;
tmpDate = this.date;
};
var d = pad(tmpDate.getDate()),
m = pad(tmpDate.getMonth() + 1),
y = tmpDate.getFullYear(),
dt = String(y)+String(m)+String(d);
if(this.low && +dt < +this.low) {
if(!level) return true;
this.date = new Date(this.low.substr(0,4), this.low.substr(4,2)-1, this.low.substr(6,2), 5, 0, 0);
return false;
};
if(this.high && +dt > +this.high) {
if(!level) return true;
this.date = new Date(this.high.substr(0,4), this.high.substr(4,2)-1, this.high.substr(6,2), 5, 0, 0);
};
return false;
};
datePicker.prototype.canDateBeSelected = function(tmpDate) {
if(!tmpDate) return false;
var d = pad(tmpDate.getDate()),
m = pad(tmpDate.getMonth() + 1),
y = tmpDate.getFullYear(),
dt = String(y)+String(m)+String(d),
dd = this.getDisabledDates(+y, +m),
wd = printFormattedDate(tmpDate, "W");
if((this.low && +dt < +this.low) || (this.high && +dt > +this.high) || (dt in dd) || this.disabledDays[wd]) {
return false;
};
return true;
};
datePicker.prototype.updateStatus = function(msg) {
while(this.statusBar.firstChild) { this.statusBar.removeChild(this.statusBar.firstChild); };
if(msg && this.statusFormat.search(/-S|S-/) != -1 && msg.search(/([0-9]{1,2})(st|nd|rd|th)/) != -1) {
msg = msg.replace(/([0-9]{1,2})(st|nd|rd|th)/, "$1$2").split(/|<\/sup>/);
var dc = document.createDocumentFragment();
for(var i = 0, nd; nd = msg[i]; i++) {
if(/^(st|nd|rd|th)$/.test(nd)) {
var sup = document.createElement("sup");
sup.appendChild(document.createTextNode(nd));
dc.appendChild(sup);
} else {
dc.appendChild(document.createTextNode(nd));
};
};
this.statusBar.appendChild(dc);
} else {
this.statusBar.appendChild(document.createTextNode(msg ? msg : getTitleTranslation(9)));
};
};
datePicker.prototype.setDateFromInput = function() {
this.dateSet = null;
var elem = this.getElem(),
upd = false,
dt;
if(!elem || elem.tagName.search(/select|input/i) == -1) return;
if(!this.splitDate && elem.value.replace(/\s/g, "") !== "") {
var dynFormatMasks = formatMasks.concat([this.format]).reverse();
for(var i = 0, fmt; fmt = dynFormatMasks[i]; i++) {
dt = parseDateString(elem.value, fmt);
if(dt) {
upd = true;
break;
};
};
} else if(this.splitDate) {
var mmN = document.getElementById(this.id + splitAppend[1]),
ddN = document.getElementById(this.id + splitAppend[0]),
tm = parseInt(mmN.tagName.toLowerCase() == "input" ? mmN.value : mmN.options[mmN.selectedIndex || 0].value, 10),
td = parseInt(ddN.tagName.toLowerCase() == "input" ? ddN.value : ddN.options[ddN.selectedIndex || 0].value, 10),
ty = parseInt(elem.tagName.toLowerCase() == "input" ? elem.value : elem.options[elem.selectedIndex || 0].value, 10);
if(!(/\d\d\d\d/.test(ty)) || !(/^(0?[1-9]|1[012])$/.test(tm)) || !(/^(0?[1-9]|[12][0-9]|3[01])$/.test(td))) {
dt = false;
} else {
if(+td > daysInMonth(+tm - 1, +ty)) {
upd = true;
td = daysInMonth(+tm - 1, +ty);
dt = new Date(ty,tm-1,td);
} else {
dt = new Date(ty,tm-1,td);
};
};
};
if(!dt || isNaN(dt)) {
this.date = new Date();
this.date.setHours(5);
this.outOfRange();
return;
};
dt.setHours(5);
this.date = new Date(dt);
this.outOfRange();
if(dt.getTime() == this.date.getTime() && this.canDateBeSelected(this.date)) {
this.dateSet = new Date(this.date);
};
if(upd) { this.returnFormattedDate(true); };
};
datePicker.prototype.setSelectIndex = function(elem, indx) {
for(var opt = elem.options.length-1; opt >= 0; opt--) {
if(elem.options[opt].value == +indx) {
elem.selectedIndex = opt;
return;
};
};
};
datePicker.prototype.returnFormattedDate = function(noFocus) {
var elem = this.getElem();
if(!elem || this.dateSet == null) return;
noFocus = !!noFocus;
var d = pad(this.date.getDate()),
m = pad(this.date.getMonth() + 1),
yyyy = this.date.getFullYear(),
disabledDates = this.getDisabledDates(+yyyy, +m),
weekDay = (this.date.getDay() + 6) % 7;
if(!(this.disabledDays[weekDay] || String(yyyy)+m+d in this.disabledDates)) {
if(this.splitDate) {
var ddE = document.getElementById(this.id+splitAppend[0]),
mmE = document.getElementById(this.id+splitAppend[1]),
tY = elem.value, tM = mmE.value, tD = ddE.value;
if(tY == elem.value && tM == mmE.value && tY == elem.value) { return; };
if(ddE.tagName.toLowerCase() == "input") { ddE.value = d; }
else { this.setSelectIndex(ddE, d); };
if(mmE.tagName.toLowerCase() == "input") { mmE.value = m; }
else { this.setSelectIndex(mmE, m); };
if(elem.tagName.toLowerCase() == "input") elem.value = yyyy;
else { this.setSelectIndex(elem, yyyy); };
} else if(elem.tagName.toLowerCase() == "input") {
var oldVal = elem.value,
newVal = printFormattedDate(this.date, this.format);
if(oldVal == newVal) { return; };
elem.value = newVal;
};
if(this.staticPos) {
this.noFocus = true;
this.updateTable();
this.noFocus = false;
};
if(this.fullCreate) {
if(elem.type && elem.type != "hidden" && !noFocus) { elem.focus(); };
this.callback("dateselect", { "id":this.id, "date":this.dateSet, "dd":d, "mm":m, "yyyy":yyyy });
};
};
};
datePicker.prototype.disableTodayButton = function() {
var today = new Date();
this.butToday.className = this.butToday.className.replace("fd-disabled", "");
if(this.outOfRange(today) || (this.date.getDate() == today.getDate() && this.date.getMonth() == today.getMonth() && this.date.getFullYear() == today.getFullYear())) {
this.butToday.className += " fd-disabled";
this.butToday.onclick = null;
} else {
this.butToday.onclick = this.events.gotoToday;
};
};
datePicker.prototype.updateTableHeaders = function() {
var colspanTotal = this.showWeeks ? 8 : 7,
colOffset = this.showWeeks ? 1 : 0,
d, but;
for(var col = colOffset; col < colspanTotal; col++ ) {
d = (this.firstDayOfWeek + (col - colOffset)) % 7;
this.ths[col].title = getDayTranslation(d, false);
if(col > colOffset) {
but = this.ths[col].getElementsByTagName("span")[0];
while(but.firstChild) { but.removeChild(but.firstChild); };
but.appendChild(document.createTextNode(getDayTranslation(d, true)));
but.title = this.ths[col].title;
but.className = but.className.replace(/day-([0-6])/, "") + " day-" + d;
but = null;
} else {
while(this.ths[col].firstChild) { this.ths[col].removeChild(this.ths[col].firstChild); };
this.ths[col].appendChild(document.createTextNode(getDayTranslation(d, true)));
};
this.ths[col].className = this.ths[col].className.replace(/date-picker-highlight/g, "");
if(this.highlightDays[d]) {
this.ths[col].className += " date-picker-highlight";
};
};
if(this.created) { this.updateTable(); }
};
datePicker.prototype.callback = function(type, args) {
if(!type || !(type in this.callbacks)) return false;
var ret = false;
for(var func = 0; func < this.callbacks[type].length; func++) {
ret = this.callbacks[type][func](args || this.id);
if(!ret) return false;
};
return ret;
};
datePicker.prototype.showHideButtons = function(tmpDate) {
var tdm = tmpDate.getMonth(),
tdy = tmpDate.getFullYear();
this.butPrevYear.className = this.butPrevYear.className.replace("fd-disabled", "");
if(this.outOfRange(new Date((tdy - 1), tdm, daysInMonth(+tdm, tdy-1)))) {
this.butPrevYear.className += " fd-disabled";
if(this.yearInc == -1) this.stopTimer();
};
this.butPrevMonth.className = this.butPrevMonth.className.replace("fd-disabled", "");
if(this.outOfRange(new Date(tdy, (+tdm - 1), daysInMonth(+tdm-1, tdy)))) {
this.butPrevMonth.className += " fd-disabled";
if(this.monthInc == -1) this.stopTimer();
};
this.butNextYear.className = this.butNextYear.className.replace("fd-disabled", "");
if(this.outOfRange(new Date((tdy + 1), +tdm, 1))) {
this.butNextYear.className += " fd-disabled";
if(this.yearInc == 1) this.stopTimer();
};
this.butNextMonth.className = this.butNextMonth.className.replace("fd-disabled", "");
if(this.outOfRange(new Date(tdy, +tdm + 1, 1))) {
this.butNextMonth.className += " fd-disabled";
if(this.monthInc == 1) this.stopTimer();
};
};
var localeDefaults = {
fullMonths:["January","February","March","April","May","June","July","August","September","October","November","December"],
monthAbbrs:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
fullDays: ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
dayAbbrs: ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],
titles: ["Previous month","Next month","Previous year","Next year", "Today", "Show Calendar", "wk", "Week [[%0%]] of [[%1%]]", "Week", "Select a date", "Click \u0026 Drag to move", "Display \u201C[[%0%]]\u201D first", "Go to Today\u2019s date", "Disabled date"],
imported: false
};
var grepRangeLimits = function(sel) {
var range = [];
for(var i = 0; i < sel.options.length; i++) {
if(sel.options[i].value.search(/^\d\d\d\d$/) == -1) { continue; };
if(!range[0] || Number(sel.options[i].value) < range[0]) { range[0] = Number(sel.options[i].value); };
if(!range[1] || Number(sel.options[i].value) > range[1]) { range[1] = Number(sel.options[i].value); };
};
return range;
};
var joinNodeLists = function() {
if(!arguments.length) { return []; }
var nodeList = [];
for (var i = 0; i < arguments.length; i++) {
for (var j = 0, item; item = arguments[i][j]; j++) {
nodeList[nodeList.length] = item;
};
};
return nodeList;
};
var cleanUp = function() {
var dp;
for(dp in datePickers) {
if(!document.getElementById(datePickers[dp].id)) {
if(datePickers[dp].created) datePickers[dp].destroy();
datePickers[dp] = null;
delete datePickers[dp];
};
};
};
var hideAll = function(exception) {
var dp;
for(dp in datePickers) {
if(!datePickers[dp].created || datePickers[dp].staticPos || (exception && exception == datePickers[dp].id)) continue;
datePickers[dp].hide();
};
};
var hideDatePicker = function(inpID) {
if(inpID in datePickers) {
if(!datePickers[inpID].created || datePickers[inpID].staticPos) return;
datePickers[inpID].hide();
};
};
var showDatePicker = function(inpID, autoFocus) {
if(!(inpID in datePickers)) return false;
datePickers[inpID].show(autoFocus);
return true;
};
var destroy = function() {
for(dp in datePickers) {
if(datePickers[dp].created) datePickers[dp].destroy();
datePickers[dp] = null;
delete datePickers[dp];
};
datePickers = null;
removeEvent(window, 'load', datePickerController.create);
removeEvent(window, 'unload', datePickerController.destroy);
};
var getTitleTranslation = function(num, replacements) {
replacements = replacements || [];
if(localeImport.titles.length > num) {
var txt = localeImport.titles[num];
if(replacements && replacements.length) {
for(var i = 0; i < replacements.length; i++) {
txt = txt.replace("[[%" + i + "%]]", replacements[i]);
};
};
return txt.replace(/[[%(\d)%]]/g,"");
};
return "";
};
var getDayTranslation = function(day, abbreviation) {
var titles = localeImport[abbreviation ? "dayAbbrs" : "fullDays"];
return titles.length && titles.length > day ? titles[day] : "";
};
var getMonthTranslation = function(month, abbreviation) {
var titles = localeImport[abbreviation ? "monthAbbrs" : "fullMonths"];
return titles.length && titles.length > month ? titles[month] : "";
};
var daysInMonth = function(nMonth, nYear) {
nMonth = (nMonth + 12) % 12;
return (((0 == (nYear%4)) && ((0 != (nYear%100)) || (0 == (nYear%400)))) && nMonth == 1) ? 29: [31,28,31,30,31,30,31,31,30,31,30,31][nMonth];
};
var getWeeksInYear = function(Y) {
if(Y in weeksInYearCache) {
return weeksInYearCache[Y];
};
var X1, X2, NW;
with (X1 = new Date(Y, 0, 4)) {
setDate(getDate() - (6 + getDay()) % 7);
};
with (X2 = new Date(Y, 11, 28)) {
setDate(getDate() + (7 - getDay()) % 7);
};
weeksInYearCache[Y] = Math.round((X2 - X1) / 604800000);
return weeksInYearCache[Y];
};
var parseRangeFromString = function(str) {
if(!str) return "";
var low = str.search(/^range-low-/) != -1;
str = str.replace(/range-(low|high)-/, "");
if(str.search(/^(\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) != -1) { return str; };
var tmpDate = new Date();
if(str.search(/^today$/) != -1) { return tmpDate.getFullYear() + pad(tmpDate.getMonth() + 1) + pad(tmpDate.getDate()); };
var regExp = /^(\d)-(day|week|month|year)$/;
if(str.search(regExp) != -1) {
var parts = str.match(regExp),
acc = { day:0,week:0,month:0,year:0 };
acc[parts[2]] = low ? -(+parts[1]) : +parts[1];
tmpDate.setFullYear(tmpDate.getFullYear() + +acc.year);
tmpDate.setMonth(tmpDate.getMonth() + +acc.month);
tmpDate.setDate(tmpDate.getDate() + +acc.day + (7 * +acc.week));
return !tmpDate || isNaN(tmpDate) ? "" : tmpDate.getFullYear() + pad(tmpDate.getMonth() + 1) + pad(tmpDate.getDate());
};
return "";
};
var getWeekNumber = function(y,m,d) {
var d = new Date(y, m, d, 0, 0, 0);
var DoW = d.getDay();
d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
var ms = d.valueOf(); // GMT
d.setMonth(0);
d.setDate(4); // Thu in Week 1
return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};
var printFormattedDate = function(date, fmt, useImportedLocale) {
if(!date || isNaN(date)) { return ""; };
var parts = fmt.split("-"),
str = [],
d = date.getDate(),
D = date.getDay(),
m = date.getMonth(),
y = date.getFullYear(),
flags = {
"sp":" ",
"dt":".",
"sl":"/",
"ds":"-",
"cc":",",
"d":pad(d),
"D":useImportedLocale ? localeImport.dayAbbrs[D == 0 ? 6 : D - 1] : localeDefaults.dayAbbrs[D == 0 ? 6 : D - 1],
"l":useImportedLocale ? localeImport.fullDays[D == 0 ? 6 : D - 1] : localeDefaults.fullDays[D == 0 ? 6 : D - 1],
"j":d,
"N":D == 0 ? 7 : D,
"w":D,
"W":getWeekNumber(date),
"M":useImportedLocale ? localeImport.monthAbbrs[m] : localeDefaults.monthAbbrs[m],
"F":useImportedLocale ? localeImport.fullMonths[m] : localeDefaults.fullMonths[m],
"m":pad(++m),
"n":++m,
"t":daysInMonth(++m, y),
"Y":y,
"o":y,
"y":String(y).substr(2,2),
"S":["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
};
for(var pt = 0, part; part = parts[pt]; pt++) {
str.push(!(part in flags) ? "" : flags[part]);
};
return str.join("");
};
var parseDateString = function(str, fmt) {
var d = false,
m = false,
y = false,
now = new Date(),
parts = fmt.replace(/-sp(-sp)+/g, "-sp").split("-"),
divds = { "dt":".","sl":"/","ds":"-","cc":"," };
loopLabel:
for(var pt = 0, part; part = parts[pt]; pt++) {
if(str.length == 0) { return false; };
switch(part) {
// Dividers
case "sp": // Space " "
if(str.charAt(0).search(/\s/) != -1) {
// Be easy on multiple spaces...
while(str.charAt(0).search(/\s/) != -1) { str = str.substr(1); };
break;
} else return "";
case "dt":
case "sl":
case "ds":
case "cc":
if(str.charAt(0) == divds[part]) {
str = str.substr(1);
break;
} else return "";
// DAY
case "d": // Day of the month, 2 digits with leading zeros (01 - 31)
case "j": // Day of the month without leading zeros (1 - 31)
// Accept both when parsing
if(str.search(/^(3[01]|[12][0-9]|0?[1-9])/) != -1) {
d = +str.match(/^(3[01]|[12][0-9]|0?[1-9])/)[0];
str = str.substr(str.match(/^(3[01]|[12][0-9]|0?[1-9])/)[0].length);
break;
} else return "";
case "D": // A textual representation of a day, three letters (Mon - Sun)
case "l": // A full textual representation of the day of the week (Monday - Sunday)
l = part == "D" ? localeDefaults.dayAbbrs : localeDefaults.fullDays;
for(var i = 0; i < 7; i++) {
if(new RegExp("^" + l[i], "i").test(str)) {
str = str.substr(l[i].length);
continue loopLabel;
};
};
return "";
/*
case "j": // Day of the month without leading zeros (1 - 31)
if(str.search(/^([1-9]|[12][0-9]|3[01])/) != -1) {
d = +str.match(/^([1-9]|[12][0-9]|3[01])/)[0];
str = str.substr(str.match(/^(\s?[1-9]|[12][0-9]|3[01])/)[0].length);
break;
} else return "";
*/
case "N": // ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) 1 (for Monday) through 7 (for Sunday)
case "w": // Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
if(str.search(part == "N" ? /^([1-7])/ : /^([0-6])/) != -1) {
str = str.substr(1);
break;
} else return "";
case "S": // English ordinal suffix for the day of the month, 2 characters: st, nd, rd or th
if(str.search(/^(st|nd|rd|th)/i) != -1) {
str = str.substr(2);
break;
} else return "";
case "z": // The day of the year (starting from 0): 0 - 365
if(str.search(/^([0-9]|[1-9][0-9]|[12][0-9]{2}|3[0-5][0-9]|36[0-5])/) != -1) {
str = str.substr(str.match(/^([0-9]|[1-9][0-9]|[12][0-9]{2}|3[0-5][0-9]|36[0-5])/)[0].length);
break;
} else return "";
// WEEK
case "W": // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0): 1 - 53
if(str.search(/^([1-9]|[1234[0-9]|5[0-3])/) != -1) {
str = str.substr(str.match(/^([1-9]|[1234[0-9]|5[0-3])/)[0].length);
break;
} else return "";
// MONTH
case "M": // A short textual representation of a month, three letters
case "F": // A full textual representation of a month, such as January or March
l = localeDefaults.fullMonths.concat(localeDefaults.monthAbbrs); // : localeDefaults.fullMonths;
for(var i = 0; i < 24; i++) {
if(str.search(new RegExp("^" + l[i],"i")) != -1) {
str = str.substr(l[i].length);
m = ((i + 12) % 12);
continue loopLabel;
};
};
return "";
case "m": // Numeric representation of a month, with leading zeros
case "n": // Numeric representation of a month, without leading zeros
//l = part == "m" ? /^(0[1-9]|1[012])/ : /^([1-9]|1[012])/;
// Accept either when parsing
l = /^(1[012]|0?[1-9])/;
if(str.search(l) != -1) {
m = +str.match(l)[0] - 1;
str = str.substr(str.match(l)[0].length);
break;
} else return "";
case "t": // Number of days in the given month: 28 through 31
if(str.search(/2[89]|3[01]/) != -1) {
str = str.substr(2);
break;
} else return "";
// YEAR
case "Y": // A full numeric representation of a year, 4 digits
case "o": // ISO-8601 year number. This has the same value as Y
if(str.search(/^(\d{4})/) != -1) {
y = str.substr(0,4);
str = str.substr(4);
break;
} else return "";
case "y": // A two digit representation of a year
if(str.search(/^(0[0-9]|[1-9][0-9])/) != -1) {
y = +str.substr(0,2);
y = +y < 50 ? '20' + y : '19' + y;
str = str.substr(2);
break;
} else return "";
default:
return "";
};
};
d = d === false ? now.getDate() : d;
m = m === false ? now.getMonth() - 1 : m;
y = y === false ? now.getFullYear() : y;
var tmpDate = new Date(y,m,d);
return isNaN(tmpDate) ? "" : tmpDate;
};
var repositionDatePickers = function(e) {
for(dp in datePickers) {
if(!datePickers[dp].created || datePickers[dp].staticPos || (!datePickers[dp].staticPos && !datePickers[dp].dragDisabled)) continue;
datePickers[dp].reposition();
};
};
var findLabelForElement = function(element) {
var label;
if(element.parentNode && element.parentNode.tagName.toLowerCase() == "label") lebel = element.parentNode;
else {
var labelList = document.getElementsByTagName('label');
// loop through label array attempting to match each 'for' attribute to the id of the current element
for(var lbl = 0; lbl < labelList.length; lbl++) {
// Internet Explorer requires the htmlFor test
if((labelList[lbl]['htmlFor'] && labelList[lbl]['htmlFor'] == element.id) || (labelList[lbl].getAttribute('for') == element.id)) {
label = labelList[lbl];
break;
};
};
};
if(label && !label.id) { label.id = element.id + "_label"; };
return label;
};
var addDatePicker = function(options) {
if(!options.id) { throw "A datePicker requires an associated element with an id attribute"; };
if(options.id in datePickers) { return; };
var elem = document.getElementById(options.id);
if(!elem) throw "Cannot locate a datePicker's associated element with an id of:" + options.id;
if(elem.tagName.search(/select|input/i) == -1) {
if(!("callbacks" in options) || !("dateselect" in options.callbacks)) {
throw "A 'dateselect' callback function is required for datePickers not associated with a form element";
};
options.staticPos = true;
options.splitDate = false;
options.hideInput = false;
options.noFadeEffect = true;
options.dragDisabled = true;
options.positioned = false;
} else if(!options.staticPos) {
options.hideInput = false;
} else {
options.noFadeEffect = true;
options.dragDisabled = true;
};
datePickers[options.id] = new datePicker(options);
};
var parseCallbacks = function(cbs) {
if(cbs == null) { return {}; };
var func,
type,
cbObj = {},
parts,
obj;
for(var i = 0, fn; fn = cbs[i]; i++) {
type = fn.match(/(cb_(dateselect|redraw|create)_)([^\s|$]+)/i)[1].replace(/^cb_/i, "").replace(/_$/, "");
fn = fn.replace(/cb_(dateselect|redraw|create)_/i, "").replace(/-/g, ".");
try {
if(fn.indexOf(".") != -1) {
parts = fn.split('.');
obj = window;
for (var x = 0, part; part = obj[parts[x]]; x++) {
if(part instanceof Function) {
(function() {
var method = part;
func = function (data) { method.apply(obj, [data]) };
})();
} else {
obj = part;
};
};
} else {
func = window[fn];
};
if(!(func instanceof Function)) continue;
if(!(type in cbObj)) { cbObj[type] = []; };
cbObj[type][cbObj[type].length] = func;
} catch (err) {};
};
return cbObj;
};
// Used by the button to dictate whether to open or close the datePicker
var isVisible = function(id) {
return (!id || !(id in datePickers)) ? false : datePickers[id].visible;
};
var create = function(inp) {
if(!(typeof document.createElement != "undefined" && typeof document.documentElement != "undefined" && typeof document.documentElement.offsetWidth == "number")) { return; };
// Has the locale file loaded?
if(typeof(fdLocale) == "object" && !localeImport) {
localeImport = {
titles : fdLocale.titles,
fullMonths : fdLocale.fullMonths,
monthAbbrs : fdLocale.monthAbbrs,
fullDays : fdLocale.fullDays,
dayAbbrs : fdLocale.dayAbbrs,
firstDayOfWeek : ("firstDayOfWeek" in fdLocale) ? fdLocale.firstDayOfWeek : 0,
imported : true
};
} else if(!localeImport) {
localeImport = localeDefaults;
};
var formElements = (inp && inp.tagName) ? [inp] : joinNodeLists(document.getElementsByTagName('input'), document.getElementsByTagName('select')),
disableDays = /disable-days-([1-7]){1,6}/g,
highlight = /highlight-days-([1-7]{1,7})/,
rangeLow = /range-low-(((\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]))|((\d)-(day|week|month|year))|(today))/,
rangeHigh = /range-high-(((\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]))|((\d)-(day|week|month|year))|(today))/,
dateFormat = /dateformat(-((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p])))+/,
statusFormat = /statusformat(-((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p])))+/,
tdCellFormat = /cellformat(-((sp|dt|sl|ds|cc)|([d|D|l|j|N|w|S|W|M|F|m|n|t|Y|o|y|O|p])))+/,
disableDates = /disable((-(\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])){2}|(-((\d\d\d\d)|(xxxx))((0[1-9]|1[012])|(xx))(0[1-9]|[12][0-9]|3[01])))/g,
enableDates = /enable((-(\d\d\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])){2}|(-((\d\d\d\d)|(xxxx))((0[1-9]|1[012])|(xx))(0[1-9]|[12][0-9]|3[01])))/g,
callbacks = /((cb_(dateselect|redraw|create)_)([^\s|$]+))/ig,
positioned = /display-inline-([^\s|$]+)/i,
bPositioned = /button-([^\s|$]+)/i,
range,tmp,j,t,options,dts,parts;
for(var i = 0, elem; elem = formElements[i]; i++) {
if(elem.className && (elem.className.search(dateFormat) != -1 || elem.className.search(/split-date/) != -1) && ((elem.tagName.toLowerCase() == "input" && (elem.type == "text" || elem.type == "hidden")) || elem.tagName.toLowerCase() == "select")) {
if(elem.id && elem.id in datePickers) {
if(!datePickers[elem.id].staticPos) { datePickers[elem.id].createButton(); }
else {
if(!document.getElementById("fd-" + elem.id)) {
datePickers[elem.id].created = false;
datePickers[elem.id].create();
} else if(inp) {
// Only do this if called from an ajax update etc
datePickers[elem.id].setDateFromInput();
datePickers[elem.id].updateTable();
};
};
continue;
};
if(!elem.id) { elem.id = "fdDatePickerInput-" + uniqueId++; };
options = {
id:elem.id,
low:"",
high:"",
format:"d-sl-m-sl-Y",
statusFormat:"",
cellFormat:cellFormat,
highlightDays:[0,0,0,0,0,1,1],
disabledDays:[0,0,0,0,0,0,0],
disabledDates:{},
enabledDates:{},
noFadeEffect:elem.className.search(/no-animation/i) != -1,
staticPos:elem.className.search(/display-inline/i) != -1,
hideInput:elem.className.search(/hide-input/i) != -1,
noToday:elem.className.search(/no-today-button/i) != -1,
showWeeks:elem.className.search(/show-week/i) != -1,
dragDisabled:nodrag ? true : elem.className.search(/disable-drag/i) != -1,
positioned:false,
firstDayOfWeek:localeImport.firstDayOfWeek,
fillGrid:elem.className.search(/fill-grid/i) != -1,
constrainSelection:elem.className.search(/fill-grid-no-select/i) != -1,
callbacks:parseCallbacks(elem.className.match(callbacks)),
buttonWrapper:"",
labelledBy:findLabelForElement(elem)
};
// Positioning of static dp's
if(options.staticPos && elem.className.search(positioned) != -1) {
options.positioned = elem.className.match(positioned)[1];
};
// Positioning of non-static dp's button
if(!options.staticPos && elem.className.search(bPositioned) != -1) {
options.buttonWrapper = elem.className.match(bPositioned)[1];
};
// Opacity of non-static datePickers
if(!options.staticPos) {
options.finalOpacity = elem.className.search(/opacity-([1-9]{1}[0-9]{1})/i) != -1 ? elem.className.match(/opacity-([1-9]{1}[0-9]{1})/i)[1] : 90
};
// Dates to disable
dts = elem.className.match(disableDates);
if(dts) {
for(t = 0; t < dts.length; t++) {
parts = dts[t].replace(/xxxx/, "****").replace(/xx/, "**").replace("disable-", "").split("-");
options.disabledDates[parts[0]] = (parts.length && parts.length == 2) ? parts[1] : 1;
};
};
// Dates to enable
dts = elem.className.match(enableDates);
if(dts) {
for(t = 0; t < dts.length; t++) {
parts = dts[t].replace(/xxxx/, "****").replace(/xx/, "**").replace("enable-", "").split("-");
options.enabledDates[parts[0]] = (parts.length && parts.length == 2) ? parts[1] : 1;
};
};
// Split the date into three parts ?
options.splitDate = (elem.className.search(/split-date/) != -1 && document.getElementById(elem.id+splitAppend[0]) && document.getElementById(elem.id+splitAppend[1]) && document.getElementById(elem.id+splitAppend[0]).tagName.search(/input|select/i) != -1 && document.getElementById(elem.id+splitAppend[1]).tagName.search(/input|select/i) != -1);
// Date format
if(!options.splitDate && elem.className.search(dateFormat) != -1) {
options.format = elem.className.match(dateFormat)[0].replace('dateformat-','');
};
// Status bar date format
if(elem.className.search(statusFormat) != -1) {
options.statusFormat = elem.className.match(statusFormat)[0].replace('statusformat-','');
};
// TD cell title date format
if(elem.className.search(tdCellFormat) != -1) {
options.cellFormat = elem.className.match(tdCellFormat)[0].replace('cellformat-','');
};
// The days of the week to highlight
if(elem.className.search(highlight) != -1) {
tmp = elem.className.match(highlight)[0].replace(/highlight-days-/, '');
options.highlightDays = [0,0,0,0,0,0,0];
for(j = 0; j < tmp.length; j++) {
options.highlightDays[tmp.charAt(j) - 1] = 1;
};
};
// The days of the week to disable
if(elem.className.search(disableDays) != -1) {
tmp = elem.className.match(disableDays)[0].replace(/disable-days-/, '');
options.disabledDays = [0,0,0,0,0,0,0];
for(j = 0; j < tmp.length; j++) {
options.disabledDays[tmp.charAt(j) - 1] = 1;
};
};
// The lower limit
if(elem.className.search(rangeLow) != -1) {
options.low = parseRangeFromString(elem.className.match(rangeLow)[0]);
};
// The higher limit
if(elem.className.search(rangeHigh) != -1) {
options.high = parseRangeFromString(elem.className.match(rangeHigh)[0]);
};
// Always round lower & higher limits if a selectList involved
if(elem.tagName.search(/select/i) != -1) {
range = grepRangeLimits(elem);
options.low = options.low ? range[0] + String(options.low).substr(4,4) : range[0] + "0101";
options.high = options.high ? range[1] + String(options.high).substr(4,4) : range[1] + "1231";
};
addDatePicker(options);
};
};
};
addEvent(window, 'load', create);
addEvent(window, 'unload', destroy);
addEvent(window, 'resize', repositionDatePickers);
return {
addEvent: function(obj, type, fn) { return addEvent(obj, type, fn); },
removeEvent: function(obj, type, fn) { return removeEvent(obj, type, fn); },
stopEvent: function(e) { return stopEvent(e); },
show: function(inpID) { return showDatePicker(inpID, false); },
hide: function(inpID) { return hideDatePicker(inpID); },
create: function(inp) { create(inp); },
repositionDatePickers: function() { repositionDatePickers(); },
printFormattedDate: function(dt, fmt, useImportedLocale) { return printFormattedDate(dt, fmt, useImportedLocale); },
setDateFromInput: function(inpID) { if(!inpID || !(inpID in datePickers) || !datePickers[inpID].created) return false; datePickers[inpID].setDateFromInput(); },
setRangeLow: function(inpID, yyyymmdd) { if(!inpID || !(inpID in datePickers)) return false; datePickers[inpID].setRangeLow(yyyymmdd); },
setRangeHigh: function(inpID, yyyymmdd) { if(!inpID || !(inpID in datePickers)) return false; datePickers[inpID].setRangeHigh(yyyymmdd); },
parseDateString: function(str, format) { return parseDateString(str, format); },
setGlobalVars: function(json) { affectJSON(json); },
dateValidForSelection: function(inpID, dt) { if(!inpID || !(inpID in datePickers)) return false; datePickers[inpID].canDateBeSelected(dt); },
addDisabledDates: function(inpID, dts) { if(!inpID || !(inpID in datePickers)) return false; datePickers[inpID].addDisabledDates(dts); },
setDisabledDates: function(inpID, dts) { if(!inpID || !(inpID in datePickers)) return false; datePickers[inpID].setDisabledDates(dts); }
};
})();