var datePickerDivID = 'datepicker';
var iFrameDivID = 'datepickeriframe';
var dayNameListShort = new Array(
'Zo',
'Ma',
'Di',
'Wo',
'Do',
'Vr',
'Za'
);
var dayNameListLong = new Array(
'Zondag',
'Maandag',
'Dinsdag',
'Woensdag',
'Donderdag',
'Vrijdag',
'Zaterdag'
);
var monthNameListShort = new Array(
'Jan',
'Feb',
'Mrt',
'Apr',
'Mei',
'Jun',
'Jul',
'Aug',
'Sep',
'Okt',
'Nov',
'Dec'
);
var monthNameListLong = new Array(
'Januari',
'Februari',
'Maart',
'April',
'Mei',
'Juni',
'Juli',
'Augustus',
'September',
'Oktober',
'November',
'December'
);
var currentlySelectedDate;
var minimumDate;
var maximumDate;
/* these variables define the date formatting we're expecting and outputting. */
/* If you want to use a different format by default, change the */
/* defaultDateSeparator and defaultDateFormat variables either here or on */
/* your HTML page. */
var defaultDateSeparator = '/'; /* common values would be '/' or '-' */
var defaultDateFormat = 'dmy' /* valid values are 'mdy', 'dmy', and 'ymd' */
var dateSeparator = defaultDateSeparator;
var dateFormat = defaultDateFormat;
function displayDatePicker(dateFieldName, displayBelowThisObject, dtFormat, dtSep)
{
var targetDateField = document.getElementsByName(dateFieldName).item(0);
/* fetch the current date */
currentlySelectedDate = getFieldDate(targetDateField.value);
currentlySelectedDate = dateClearTime(currentlySelectedDate);
/* set the range of valid dates */
minimumDate = new Date();
minimumDate = dateClearTime(minimumDate);
minimumDate.setDate(minimumDate.getDate() + 7);
maximumDate = new Date();
maximumDate = dateClearTime(maximumDate);
maximumDate.setDate(maximumDate.getDate() - 1);
maximumDate.setMonth(maximumDate.getMonth() + 6);
/* if we weren't told what node to display the datepicker beneath, just */
/* display it beneath the date field we're updating */
if (! displayBelowThisObject)
{
displayBelowThisObject = targetDateField;
}
/* if a date separator character was given, update the dateSeparator variable */
if (dtSep)
{
dateSeparator = dtSep;
}
else
{
dateSeparator = defaultDateSeparator;
}
/* if a date format was given, update the dateFormat variable */
if (dtFormat)
{
dateFormat = dtFormat;
}
else
{
dateFormat = defaultDateFormat;
}
var x = displayBelowThisObject.offsetLeft;
var y = displayBelowThisObject.offsetTop + displayBelowThisObject.offsetHeight ;
/* deal with elements inside tables and such */
var parent = displayBelowThisObject;
while (parent.offsetParent)
{
parent = parent.offsetParent;
x += parent.offsetLeft;
y += parent.offsetTop ;
}
drawDatePicker(targetDateField, x, y);
}
/* Draw the datepicker object (which is just a table with calendar elements) */
/* at the specified x and y coordinates, using the targetDateField object as */
/* the input tag that will ultimately be populated with a date. */
/* This function will normally be called by the displayDatePicker function. */
function drawDatePicker(targetDateField, x, y)
{
/* the datepicker table will be drawn inside of a
with an ID defined by */
/* the global datePickerDivID variable. If such a div doesn't yet exist on */
/* the HTML document we're working with, add one. */
if (! document.getElementById(datePickerDivID))
{
var newNode = document.createElement('div');
newNode.setAttribute('id', datePickerDivID);
newNode.setAttribute('class', 'dpDiv');
newNode.setAttribute('style', 'visibility: hidden;');
document.body.appendChild(newNode);
}
/* move the datepicker div to the proper x,y coordinate and toggle the */
/* visiblity */
var pickerDiv = document.getElementById(datePickerDivID);
pickerDiv.style.position = 'absolute';
pickerDiv.style.left = x + 'px';
pickerDiv.style.top = y + 'px';
pickerDiv.style.visibility = (pickerDiv.style.visibility == 'visible' ? 'hidden' : 'visible');
pickerDiv.style.display = (pickerDiv.style.display == 'block' ? 'none' : 'block');
pickerDiv.style.zIndex = 10000;
/* draw the datepicker table */
refreshDatePicker(targetDateField.name);
}
/* This is the function that actually draws the datepicker calendar. */
function refreshDatePicker(dateFieldName, year, month)
{
/* if no arguments are passed, use today's date; otherwise, month and year */
/* are required */
var thisDay = new Date();
if (month >= 0 && year > 0)
{
thisDay = new Date(year, month, 1);
}
thisDay = dateClearTime(thisDay);
thisDay.setDate(1);
/* the calendar will be drawn as a table; you can customize the table */
/* elements with a global CSS style sheet or by hardcoding style and */
/* formatting elements below */
var CRLF = '\r\n';
var HTML_ELEMENT_TABLE = '
' + CRLF;
var HTML_ELEMENT_END_TABLE = '
' + CRLF;
var HTML_ELEMENT_TR = '
';
var HTML_ELEMENT_TR_TITLE = '
';
var HTML_ELEMENT_TR_DAYS = '
';
var HTML_ELEMENT_TR_TODAYBUTTON = '
';
var HTML_ELEMENT_END_TR = '
' + CRLF;
var HTML_ELEMENT_TD = '
';
}
else if (thisDay.getTime() >= maximumDate.getTime())
{
onClickEventHtml = ' onclick="alert(\'You have to select a date prior to 6 months in the future.\');return false;">';
}
else
{
onClickEventHtml = ' onclick="updateDateField(\'' + dateFieldName + '\', \'' + getDateString(thisDay) + '\');">';
}
if (thisDay.getTime() < minimumDate.getTime() || thisDay.getTime() >= maximumDate.getTime())
{
calendarHtml += HTML_ELEMENT_TD_OUT_OF_RANGE + onClickEventHtml + thisDay.getDate() + HTML_ELEMENT_END_TD;
}
else if (thisDay.getTime() == currentlySelectedDate.getTime())
{
calendarHtml += HTML_ELEMENT_TD_SELECTED + onClickEventHtml + HTML_ELEMENT_DIV_SELECTED + thisDay.getDate() + HTML_ELEMENT_END_DIV + HTML_ELEMENT_END_TD;
}
else
{
calendarHtml += HTML_ELEMENT_TD + onClickEventHtml + thisDay.getDate() + HTML_ELEMENT_END_TD;
}
/* if this is a Saturday, start a new row */
if (thisDay.getDay() == 6)
{
calendarHtml += HTML_ELEMENT_END_TR;
calendarHtml += HTML_ELEMENT_TR;
}
/* increment the day */
thisDay.setDate(thisDay.getDate() + 1);
}
while (thisDay.getDate() > 1)
/* fill in any trailing blanks */
if (thisDay.getDay() > 0)
{
for (i = 6; i > thisDay.getDay(); i--)
calendarHtml += HTML_ELEMENT_TD + ' ' + HTML_ELEMENT_END_TD;
}
calendarHtml += HTML_ELEMENT_END_TR;
/* add a button to allow the user to easily return to today, or close the */
/* calendar */
var today = new Date();
var todayString = 'Today is ' + dayNameListShort[today.getDay()] + ', ' + monthNameListShort[today.getMonth()] + ' ' + today.getDate();
calendarHtml += HTML_ELEMENT_TR_TODAYBUTTON + HTML_ELEMENT_TD_TODAYBUTTON;
calendarHtml += ' ';
calendarHtml += '';
calendarHtml += HTML_ELEMENT_END_TD + HTML_ELEMENT_END_TR;
/* and finally, close the table */
calendarHtml += HTML_ELEMENT_END_TABLE;
document.getElementById(datePickerDivID).innerHTML = calendarHtml;
/* add an "iFrame shim" to allow the datepicker to display above selection */
/* lists */
adjustiFrame();
}
/* Convenience function for writing the code for the buttons that bring us */
/* back or forward a month. */
function getButtonCode(dateFieldName, dateVal, adjust, label)
{
var newMonth = (dateVal.getMonth () + adjust) % 12;
var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
if (newMonth < 0)
{
newMonth += 12;
newYear += -1;
}
return '';
}
/* Convert a JavaScript Date object to a string, based on the dateFormat and */
/* dateSeparator variables at the beginning of this script library. */
function getDateString(dateVal)
{
var dayString = '00' + dateVal.getDate();
var monthString = '00' + (dateVal.getMonth()+1);
dayString = dayString.substring(dayString.length - 2);
monthString = monthString.substring(monthString.length - 2);
switch (dateFormat)
{
case 'dmy':
return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear();
case 'ymd':
return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString;
case 'mdy':
default:
return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear();
}
}
/* Convert a string to a JavaScript Date object. */
function getFieldDate(dateString)
{
var dateVal;
var dArray;
var d, m, y;
try
{
dArray = splitDateString(dateString);
if (dArray)
{
switch (dateFormat)
{
case 'dmy':
d = parseInt(dArray[0], 10);
m = parseInt(dArray[1], 10) - 1;
y = parseInt(dArray[2], 10);
break;
case 'ymd':
d = parseInt(dArray[2], 10);
m = parseInt(dArray[1], 10) - 1;
y = parseInt(dArray[0], 10);
break;
case 'mdy':
default :
d = parseInt(dArray[1], 10);
m = parseInt(dArray[0], 10) - 1;
y = parseInt(dArray[2], 10);
break;
}
dateVal = new Date(y, m, d);
}
else if (dateString)
{
dateVal = new Date(dateString);
}
else
{
dateVal = new Date();
}
}
catch(e)
{
dateVal = new Date();
}
return dateVal;
}
/* Try to split a date string into an array of elements, using common date */
/* separators. If the date is split, an array is returned; otherwise, we just */
/* return false. */
function splitDateString(dateString)
{
var dArray;
if (dateString.indexOf('/') >= 0)
dArray = dateString.split('/');
else if (dateString.indexOf('.') >= 0)
dArray = dateString.split('.');
else if (dateString.indexOf('-') >= 0)
dArray = dateString.split('-');
else if (dateString.indexOf('\\') >= 0)
dArray = dateString.split('\\');
else
dArray = false;
return dArray;
}
/* Update the field with the given dateFieldName with the dateString that has */
/* been passed, and hide the datepicker. If no dateString is passed, just */
/* close the datepicker without changing the field value. */
/* Also, if the page developer has defined a function called datePickerClosed */
/* anywhere on the page or in an imported library, we will attempt to run */
/* that function with the updated field as a parameter. This can be used for */
/* such things as date validation, setting default values for related fields, */
/* etc. For example, you might have a function like this to validate a start */
/* date field: */
/*
function datePickerClosed(dateField)
{
var dateObj = getFieldDate(dateField.value);
var today = new Date();
today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
if (dateField.name == 'StartDate')
{
if (dateObj < today)
{
// if the date is before today, alert the user and display the datepicker //
// again //
alert('Please enter a date that is today or later');
dateField.value = '';
document.getElementById(datePickerDivID).style.visibility = 'visible';
adjustiFrame();
}
else
{
// if the date is okay, set the EndDate field to 7 days after the StartDate //
dateObj.setTime(dateObj.getTime() + (7 * 24 * 60 * 60 * 1000));
var endDateField = document.getElementsByName('EndDate').item(0);
endDateField.value = getDateString(dateObj);
}
}
}
*/
function updateDateField(dateFieldName, dateString)
{
var targetDateField = document.getElementsByName(dateFieldName).item(0);
if (dateString)
{
targetDateField.value = dateString;
document.getElementById('cancelDateContainer').innerHTML = dateString;
}
var pickerDiv = document.getElementById(datePickerDivID);
pickerDiv.style.visibility = 'hidden';
pickerDiv.style.display = 'none';
adjustiFrame();
/* after the datepicker has closed, optionally run a user-defined function */
/* called datePickerClosed, passing the field that was just updated as a */
/* parameter (note that this will only run if the user actually selected a */
/* date from the datepicker) */
if ((dateString) && (typeof(datePickerClosed) == 'function'))
{
datePickerClosed(targetDateField);
}
}
/* Use an "iFrame shim" to deal with problems where the datepicker shows up */
/* behind selection list elements, if they're below the datepicker. The */
/* problem and solution are described at: */
/* http://dotnetjunkies.com/WebLog/jking/archive/2003/07/21/488.aspx */
function adjustiFrame(pickerDiv, iFrameDiv)
{
/* we know that Opera doesn't like something about this, so if we think we're */
/* using Opera, don't even try */
if (navigator.userAgent.toLowerCase().indexOf('opera') == -1)
{
/* put a try/catch block around the whole thing, just in case */
try
{
if (! document.getElementById(iFrameDivID))
{
var newNode = document.createElement('iFrame');
newNode.setAttribute('id', iFrameDivID);
newNode.setAttribute('src', 'javascript:false;');
newNode.setAttribute('scrolling', 'no');
newNode.setAttribute('frameborder', '0');
document.body.appendChild(newNode);
}
if (! pickerDiv)
{
pickerDiv = document.getElementById(datePickerDivID);
}
if (! iFrameDiv)
{
iFrameDiv = document.getElementById(iFrameDivID);
}
try
{
iFrameDiv.style.position = 'absolute';
iFrameDiv.style.width = pickerDiv.offsetWidth;
iFrameDiv.style.height = pickerDiv.offsetHeight ;
iFrameDiv.style.top = pickerDiv.style.top;
iFrameDiv.style.left = pickerDiv.style.left;
iFrameDiv.style.zIndex = pickerDiv.style.zIndex - 1;
iFrameDiv.style.visibility = pickerDiv.style.visibility ;
iFrameDiv.style.display = pickerDiv.style.display;
}
catch(exceptionObject)
{
}
}
catch (exceptionObject)
{
}
}
}
function dateClearTime(aDate)
{
aDate.setHours(12);
aDate.setMinutes(0);
aDate.setSeconds(0);
aDate.setMilliseconds(0);
return aDate;
}