Yet Another DatePicker
An attempt at writing a flexible, framework free, feature-rich and accessible datepicker. The more impatient amongst you may want to see the various demos or head directly over to the github repository to ponder over the source before reading any further.
At a glance…
- Keyboard shortcuts adhere to The DHTML Style Guide Working Group (DSGWG) recommendations
- Accessibility enhancements include support for ARIA Roles and States
- The script can parse and format dates using a subset of the PHP date conversion specifiers
- Both upper and lower date limits can be set
- Bespoke days of the week can be disabled
- Bespoke dates can be disabled/enabled and “*” wildcards used to stipulate the dates in question
- Bespoke days of the week can be highlighted within the U.I.
- Works with any combination of text inputs or select lists
- DOM friendly – the datepicker is only added to the DOM when actually required
- Includes a “smart localisation” option and has been translated into many languages
- Can display an optional status bar and week numbers
- Popup datepickers can be dragged within the viewport by the user
- Global configuration parameters can be specified using JSON within the script tag itself
- The “button” used for popup datepickers can be styled for default, hover, focus, active and disabled states, be arbitrarily positioned within the DOM and removed from the document tabindex if so desired
- Inline datepickers are available, are automatically added to the document tabindex and can be arbitrarily positioned within the DOM
- A bespoke final opacity can be defined and if desired, the fade in/out animation effect disabled
- The entire U.I. grid can be filled with dates
- The “Today” button can be removed from the U.I.
- Fully skinnable with CSS
- Compatible down to IE6
Creating datepickers
Datepickers are created by calling the datePickerController.createDatePicker
method, which expects an initialisation Object as the sole argument. An example of a basic creation call is shown below:
<input type="text" id="inp1" name="inp1" />
<script>
// Attach a datepicker to the above input element
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
}
});
</script>
Associating form elements with a datepicker
Each datepicker has to be associated with at least one form element and each form element has to be associated with a valid date format. This is acheived by setting the formElements
parameter passed within the initialisation Object; for example, the following code will associate a datepicker with the three distinct form elements whose ids are “inp1” (representing the day date part), “inp2” (representing the month date part) and “inp3” (representing the year date part):
<input type="text" id="inp1" name="inp1" />
<input type="text" id="inp2" name="inp2" />
<input type="text" id="inp3" name="inp3" />
<script>
datePickerController.createDatePicker({
formElements:{
// Associate #inp1 with the day date part
"inp1":"%d",
// Associate #inp2 with the month date part
"inp2":"%m",
// Associate #inp3 with the year date part
"inp3":"%Y"
}
});
</script>
The formElements
parameter is itself an Object whose keys represent the unique id of an associated form element and whose values represent the date format to assign to the form element in question.
The order of the values set within the “formElements” parameter
The first form element stipulated within the formElements
parameter is the element that receives focus after a date has been successfuly selected using the datepicker; for example, the previous example will set the focus on the “inp1” form element as it was the first element listed within the formElements
parameter.
Additionally, the id of the first form element listed is the id that needs to be used when calling certain methods of the datePickerController
Object; for example, to destroy the datepicker created within the previous example, the id “inp1” would be passed to the destroyDatePicker
method as is shown below:
// Remove the datepicker created above
datePickerController.destroyDatePicker("inp1");
Popup datepickers
By default, the script creates “popup” datepickers i.e. an activation button is positioned beside the associated form element and the datepicker only appears when the button has been activated using the mouse or the keyboard. The activation button is, by default, positioned directly after the associated form element within the DOM.
Positioning the activation button
Should you wish to position the activation button within a specific DOM node, add the parameter positioned
to the initialisation Object and set the parameter value to be the id of the DOM node that you wish to position the button within; for example:
<!-- The span that will hold the activation button -->
<span id="pos-demo"></span>
<!-- The input associated with the datepicker -->
<input id="inp1" name="inp1" />
<script>
// Create the datepicker
datePickerController.createDatePicker({
formElements: {
"inp1": "%d/%m/%Y"
},
// Position the activation button within the span
positioned: "pos-demo"
});
</script>
Setting a bespoke tabIndex for the activation button
Should you wish to set a bespoke tabIndex for the activation button, add the parameter bespokeTabIndex
to the the initialisation Object and set the parameter value to be an Integer representing the desired tabindex.
Removing all activation buttons from the document tabIndex
This can be only be done on a global level by using the buttontabindex
property within the JSON passed to the script – this is explained in more detail within the section Setting Global configuration parameters.
Removing the buttons from the document tabIndex means, of course, that all “popup” datepickers are no longer keyboard accessible and is therefore not recommended.
Inline (non-popup) datepickers
If you wish to have the datepicker always displayed on screen i.e. with no activation button; add the parameter nopopup
to the initialisation Object and set the parameter value to “true”. By default, the script adds inline datepickers to the DOM as the next sibling of the first associated form element.
Positioning inline datepickers
Should you wish to position inline datepickers within a bespoke DOM node, add the parameter positioned
to the initialisation Object and set the parameter value to be the id of the DOM node that you wish to position the datepicker within.
Date formats
The following list of conversion specifiers are valid for use within the date format:
Specifier | Description |
---|---|
%d |
Day of the month, 2 digits with leading zeros (01 – 31) |
%j |
Day of the month without leading zeros (1 – 31) |
%D |
An abbreviated textual representation of a day (Mon – Sun) |
%l |
A full textual representation of the day of the week (Monday – Sunday) |
%N |
ISO-8601 numeric representation of the day of the week 1 (for Monday) through 7 (for Sunday) |
%w |
Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday) |
%S |
English ordinal suffix for the day of the month: st, nd, rd or th |
%W |
ISO-8601 week number of year, weeks starting on Monday: 1 – 53 |
%M |
A short textual representation of a month, three letters |
%F |
A full textual representation of a month, such as January or March |
%m |
Numeric representation of a month, with leading zeros |
%n |
Numeric representation of a month, without leading zeros |
%t |
Number of days in the given month: 28 through 31 |
%Y |
A full numeric representation of a year, 4 digits |
%y |
A two digit representation of a year |
Date parsing
The script will first check to see if the form element value matches the associated date format. If that does not produce a valid date and a language file has been downloaded, all month names in that language are replaced by their English counterparts; for example, the French “mars” would be replaced by the English “March”. Any English ordinal suffix is then removed, dashes “-” are replaced by forward slashes “/” (as some browsers just don’t like parsing dates containing dashes) and finally, the result is passed to the native Javascript Date.parse
method.
The Date.parse
method should, theoretically, parse a string representing an RFC2822 or ISO 8601 date – which is way better than any date parser I would hazard to write. Unfortunately, the Date.parse
implementation is platform dependant so don’t expect consistency, rhyme or reason.
If a date is sucessfully parsed, the associated form element is automatically updated to reflect the desired date format; for example, if a user enters “jan” and a “%m” format (a zero filled two character representation of the month) has been assigned to the form element, the script will automatically update the form element value to be “01”.
Removing the use of the Javascript Date.parse fallback
You may not wish to use the native Date.parse
method as a fallback parser. This can be achieved by setting the dateparsefallback
configuration parameter when calling the datePickerController.setGlobalOptions
method or by using JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters.
Displaying a status bar
To show a status bar, add the parameter statusFormat
to the initialisation object and set the parameter value to be the date format you wish to have displayed; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Instruct the script to add a status bar and set the date format to be used
statusFormat:"%l, %d%S %F %Y"
});
Setting the status bar date format for all datepickers
Setting a status bar date format to be shared across all datepickers can be achieved by setting the statusformat
configuration parameter when calling the datePickerController.setGlobalOptions
method or by using JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters.
Displaying bespoke messages within the status bar
Short text messages can be displayed within the status bar. Each message is associated to a specific date is displayed whenever this date represents the current cursor. Messages can either be assigned globally i.e. shared across all datepickers, or individually i.e. for a single datepicker instance only.
Setting messages to be shared across all datepickers can be achieved by setting the bespoketitles
configuration parameter when calling the datePickerController.setGlobalOptions
method or by using JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters.
To set messages for a specific datepicker instance, add the parameter bespokeTitles
to the initialisation object and set the parameter value to itself be an Object of key/value pairs – where the keys represent a YYYYMMDD date String and the associated values the message to show for the date in question. The “*” wilcard character can be used within the keys; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
bespokeTitles:{
// Show a title for the 25th of December for all years
"****1225":"Christmas Day",
// Show a title for the 13th of March for all years
"****0313":"My Birthday",
// Show a title for the 16th of August 1977
"19770816":"Elvis dies"
}
});
Setting status bar messages dynamically
Setting messages for a specific datepicker instance can also be achieved dynamically by calling either the setBespokeTitles
or addBespokeTitles
methods of the datePickerController
Object; for example:
datePickerController.setBespokeTitles("inp1", {
// Show a title for the 25th of December for all years
"****1225":"Christmas Day",
// Show a title for the 13th of March for all years
"****0313":"My Birthday",
// Show a title for the 16th of August 1977
"19770816":"Elvis dies"
});
The setBespokeTitles
method replaces any previous messages assigned to the datepicker with the new list of messages while the addBespokeTitles
adds the new messages to the existing list.
Highlighting days of the week
By default, Saturday and Sunday are highlighted in another colour within the datepicker U.I. Should you wish to highlight other days of the week, add the parameter highlightDays
to the initialisation object and set the parameter value to be a seven item Array where the numeric Array keys each represent a day of the week (index 0 represents Monday through index 6, which represents Sunday) and the corresponding value (either a “0” or “1”) indicates if the day in question should be highlighted or not; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Highlight Monday (index 0) and Wednesday (index 2)
highlightDays:[1,0,1,0,0,0,0]
});
Localisation
Should a language not have been explicitly set, the script attempts to determine the language of the current webpage by checking the value of the lang
attribute on the HTML node. If a language code is successfuly recovered, the script then attempts to download the corresponding language file from the server.
Should the detected language have a region code set (i.e. en-US), the script will also attempt to download the language file associated with this region code.
If the script is unable to determine a language or no language file can be successfuly downloaded, the datepicker display defaults to English.
Filepaths and language files
In order for the script to successfuly download the appropriate language file, they should be placed within a directory named “lang”, itself resident within the same directory as the datepicker.min.js
file.
Currently available languages
The datepicker has been translated into the following languages:
- Arabic (Thanks to hosam alaa eldien)
- Catalan (thanks to Thomas Sjödin Dahl)
- Chinese – simple (thanks to liuyang.0×18)
- Czech (thanks to Stano Matousek)
- Danish (thanks to Brian Jensen)
- Dutch (thanks to Alfred Vorsselman)
- English – British (en-GB as the in-built default)
- English – American
- Esperanto (thanks to Greg Naçu)
- Estonian (thanks to Kaius Karon)
- French
- Finnish (thanks to Keijo Mukku)
- German (thanks to “too many people to list”)
- Hebrew (thanks to Neil Osman)
- Hungarian (thanks to Hetesi Tams)
- Indonesian (thanks to Krishna Hendrakusuma)
- Italian (thanks to Valerio Pilo)
- Korean (thanks to Taehyun Kim)
- Latvian (thanks to Māris Kiseļovs)
- Norwegian (thanks to Geir Rune Brandt)
- Portuguese (thanks to Paulo Monteiro)
- Portuguese – Brazil (thanks to Francis Rebouças)
- Russian (thanks to Кирилл Асташов)
- Slovak (thanks to Marek Štefkovič)
- Spanish (thanks to Augusto)
- Spanish – Mexico (thanks to Moisés Durán)
- Swedish (thanks to Henrik Marik)
- Thai (thanks to Trongchat Sottipayapun)
- Turkish (thanks to Ogan Keskiner)
Many thanks to the above contributers for their time and effort in creating the localisations.
Creating a bespoke language file
If you don’t see your language in the list, you can easily create one by using the language file creator script bundled with the download – it’s a painless process that takes no more than a couple of minutes. I would, of course, appreciate a copy of the new language file to add to the distribution – many thanks!.
Stipulating a language to use
You can disable the detect locale functionality and stipulate the required language by either using JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters – or, more easily, by adding the desired language.js
file before the datepicker.min.js
file within the HTML source; for example:
<!-- Explicitly add the French "fr.js" language file -->
<script src="/the/path/to/lang/fr.js"></script>
<!-- Now add the datepicker.min.js file -->
<script src="/the/path/to/datepicker.min.js"></script>
The locale used when formatting dates that include non-numeric date parts
Should no language be explicitly defined for use as described above (i.e. the auto-detect functionality has kicked in and downloaded a language file from the server), the date displayed within the datepicker U.I. will use the downloaded locale but all dates formatted for updating the associated input value will display in English.
This is to make life easier on the server, as you know for certain that English (and not Spanish or French or Slovak for example) dates are being returned for processing e.g. the English version “Friday, 13 March 1970” will be returned and not the French “Vendredi, 13 Mars 1970”.
Should a language have been explicitly set, the date returned to the server will always use this language.
The “first day of the week”
The first day of the week is stipulated within the downloaded language file (as logically, it’s a locale-specific setting). Should the language file not contain this setting, the first day of the week defaults to Monday.
Additionally, users can click on any of the day headers to dynamically set it as the first day of the week (or alternately, press the numbers 2-7 on the regular keyboard or numpad whenever the datepicker has keyboard focus).
Limiting date selection i.e. setting date ranges
To add a lower or upper limit for date selection, add the parameters rangeHigh
and/or rangeLow
to the initialisation object and set the parameter values to be either a YYYYMMDD date format String or a Date Object; for example, the following code will limit date selection outside of the range 13/03/1970 and today's date:
<input type="text" id="inp1" name="inp1" />
<script>
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Set a range low of 13/03/1970 using a YYYYMMDD format String
rangeLow:"19700313",
// Set a range high of today's date using a Date Object
rangeHigh:new Date()
});
</script>
Setting the date range dynamically
The upper and lower date ranges can also be set dynamically by calling the datePickerController.setRangeLow
and datePickerController.setRangeHigh
methods; for example:
// Set the lower limit to be 01/12/2008
datePickerController.setRangeLow("inp1", "20081201");
// Set the upper limit to be today's date
datePickerController.setRangeHigh("inp1", new Date());
Both methods accept a String representing an input id as the first argument and either a YYYYMMDD formatted date String or a Javascript Date Object as a second argument.
Select lists and automatic date ranges
As a select list can only ever stipulate a finite range, the datepicker will automatically create the higher and lower ranges whenever a selectlist is used to represent the year part of the date format i.e. if the year select list starts at 1960 and ends at 1990, the associated datepicker will automatically disallow the selection of dates outside of this range.
Disabling day selection
Should you wish to disable certain days of the week, add the parameter disabledDays
to the initialisation object and set the parameter value to be a seven item Array where the numeric Array keys each represent a day of the week (index 0 represents Monday through index 6, which represents Sunday) and the corresponding value (either a “0” or “1”) indicates if the day in question should be disabled or not; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Disable Saturday (index 5) and Sunday (index 6)
disabledDays:[0,0,0,0,0,1,1]
});
Disabling date selection
Dates can be dynamically disabled by calling the setDisabledDates
or addDisabledDates
methods of the datePickerController
Object.
The setDisabledDates
method will replace the current list of disabled dates with the new list while the addDisabledDates
method will add the new dates to the list already assigned to the datepicker.
Both methods accept an Object whose keys represent a YYYYMMDD formatted date String and associated value another YYYYMMDD formatted date String (to indicate a date range) or simply the Integer value 1 (to indicate an individual date).
Wildcards can be used when stipulating individual dates to disable/enable by substituting the day, month or year parts with asterisks (”*”).
var opts = {
formElements:{
"inp1":"%d/%m/%Y"
}
},
disabledDates = {
// Single Date: Disable the 25th December 2009
"20091225":1,
// Wilcard Date: Disable the 31st of December for all years
"****1231":1,
/* Date Range: Disable from the 1st of January 2011 to the
20th of January 2011. Note, wildcards can't be used
within range declarations */
"20110101":"20110120"
};
datePickerController.createDatePicker(opts);
datePickerController.setDisabledDates("inp1", disabledDates);
Enabling date selection
Should you wish to enable dates that have been previously disabled then use the setEnabledDates
or addEnabledDates
methods of the datePickerController
Object.
The setEnabledDates
method will replace the current list of enabled dates with the new list while the addEnabledDates
method will add the new dates to the list already assigned to the datepicker.
Both methods accept an Object whose keys represent a YYYYMMDD formatted date String and associated value another YYYYMMDD formatted date String (to indicate a date range) or simply the Integer value 1 (to indicate an individual date).
Wildcards can be used when stipulating individual dates to disable/enable by substituting the day, month or year parts with asterisks (“*”).
Disabling the fade-in animation effect
To disable the fade effect, add the parameter noFadeEffect
to the initialisation object and set the parameter value to “true”; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Disable the fade effect
noFadeEffect:true
});
Setting a bespoke opacity
To set a bespoke final opacity for a datepicker, add the parameter finalOpacity
to the initialisation Object and set the parameter value to be an Integer value between 20 and 100; for example:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Set a final opacity of 80%
finalOpacity:80
});
Displaying week numbers
To display week numbers within the datepicker U.I, add the parameter showWeeks
to the initialisation object and set the parameter value to “true”.
Removing the “Today” button from the U.I.
To remove the “today” button, add the parameter noTodayButton
to the initialisation object and set the parameter value to “true”.
Setting the default cursor date
By default, the cursor date is set to today’s date but there may be times when you wish the cursor to start at a date of your choice – when stipulating a range of valid dates, you may wish for the cursor to start in the middle of the range for example.
To set the cursor to a date of your choice, add the parameter cursorDate
to the initialisation object and set the parameter value to be either a YYYYMMDD format date String or a Javascript Date Object.
Setting the cursor dynamically
The cursor date can also be set dynamically by calling the setCursorDate
method of the datePickerController
Object. The setCursorDate
method accept a String representing an input id as the first argument and either a YYYYMMDD formatted date String or a Javascript Date Object as a second argument.
// Set the cursor to the date 01/12/2008
datePickerController.setCursorDate("inp1", "20081201");
Hiding the associated form elements
To hide the associated form elements, add the parameter hideInput
to the initialisation object and set the parameter value to true. The form elements will then be given the class “fd-hidden-input” which, if using the default stylesheet, sets the display
property to none
(which still sends a value to the server whenever the form submit is fired).
This parameter is ignored when creating popup datepickers and is only taken into account for inline datepickers.
Disabling the drag effect
To disable the drag effect for an individual popup datepicker, add the parameter noDrag
to the initialisation Object and set the parameter value to true.
Disabling the drag effect for all datepickers
Disabling the drag effect for all datepickers can be achieved by setting the nodrag
configuration parameter when calling datePickerController.setGlobalOptions
method or by using JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters.
Filling the entire grid with dates
Should you wish to fill the entire grid with dates, add the parameter fillGrid
to the initialisation object and set the parameter value to true.
Stopping the selection of “out-of-month” dates
By default, all dates rendered on the grid can be selected. To constrain the selection of dates to the current in-view month only, add the parameter constrainSelection
to the initialisation object and set the parameter value to true. Of course, this parameter is only taken into consideration when the fillGrid
parameter has also been set to true.
Styling the datepicker
The datepicker currently ships with CSS skin that, for simplicities sake, uses base64 encoded images for all browsers apart from Internet Explorer 6 and 7 – which use “normal” .png
images downloaded from the server. The unminified version of the file is well commented, so altering the colours etc to suit your installation should be a relatively easy task for those of you knowledgeable in the dark arts of CSS.
A little CSS3 animation flourish has been added in the form of a pulse effect on the activation button and current cursor cell (when keyboard enabled).
Additionally, the icon used to activate the datepicker updates if the associated form element(s) represent a valid date.
Styling individual dates
To enable you to target and style individual dates, each cell rendered within the interface is given three extra classNames of the format yyyymmdd-YYYYMMDD, yyyymm-YYYYMM and mmdd-MMDD, where DD is replaced by the two figure date value, MM is replaced by the two figure month value and YYYY replaced by the four figure year value e.g. the TD node frepresenting the date 21/03/2007 will be given the classNames yyyymmdd-20070321
, yyyymm-200703
and mmdd-0321
.
Setting Global configuration parameters
The script accepts the passing of Global configuration parameters by using a JSON Object within the script tag – an example of this is shown below:
<script src="/the/path/to/datepicker.js">
{
"nodrag":1,
"lang":"en"
}
</script>
It’s worth noting that JSON notation doesn’t care about whitespace so the above code block could have been written in one line (with no line breaks). Should a native JSON parser exist, it is used to parse the JSON passed to the script.
You can also pass the JSON Object programmatically by calling the datePickerController.setGlobalOptions
method as is shown below:
<!-- Load the datePicker script -->
<script src="/the/path/to/datepicker.min.js"></script>
<!-- Now pass our configuration Object to the "setGlobalOptions" method -->
<script>
datePickerController.setGlobalOptions({
"nodrag":1
});
</script>
The following parameters can currently be passed to the script:
Parameter | Description |
---|---|
nodrag |
Accepts a Boolean value that, when set to TRUE, disables the drag effect for all datepickers. Defaults to FALSE |
lang |
Accepts a valid rfc4646 language code e.g. “de” for German and, if required, an optional region subtag e.g. “de-CH”, and attempts to retrieve the corresponding language file from the server. This variable is only taken into consideration when passing the JSON between the script tags and has no effect if passed to the setGlobalOptions method. |
cellformat |
Accepts a date format String that is used to create the full date for each cell whenever the the associated datepicker has keyboard control. This parameter defaults to the value “%d %F %Y” i.e. “13 March 1970”. Only the day date format parts “%d” or “%j” are actually displayed (which means that they have to be present within the date format), all other date format parts are hidden from view but made available to screen-readers. |
titleformat |
Accepts a date format String that is used to create the title attribute for each cell. This parameter defaults to a screen-reader friendly value of “%F %d, %Y” i.e. “March 13, 1970” |
statusformat |
Accepts a String value that is used as the default statusbar date format for all datepickers. |
buttontabindex |
Accepts a Boolean value that adds or removes all popup datepicker activation buttons from the document tabindex (FALSE) or not (TRUE). Deafults to TRUE. Removing the buttons from the document tabindex means that the associated datepicker cannot be controlled using the keyboard and so isn’t recommended or encouraged in any way. |
mousewheel |
Accepts a Boolean value that enables or disables the mouseWheel activity for all popup datepickers. Defaluts to TRUE. |
describedby |
Accepts a String value that represents the id of the DOM node to use for the ARIA described-by property. |
finalopacity |
Accepts an Integer value between 20 and 100 and sets the opacity for all pop-up datepickers. |
bespoketitles |
Accepts an Object whose keys are a YYYYMMDD date String and whose values represent the message to display within the statusbar for the date in question. Wildcards are accepted for both the Year and Month parts of a key. |
derivelocale |
Accepts a Boolean value that enables or disables the smart localisation feature. Only taken into account when the JSON is passed within the script tag. Defaults to TRUE. |
dateparsefallback |
Accepts a Boolean value that enables or disables the use of the native Date.parse method as a fallback date parser. Defaults to TRUE. |
The active “cursor”
Indicating the active cursor is necessary as the datepicker is keyboard accessible and keyboard users require a visual clue as to which date is currently active i.e. which date will be selected when the carriage return key is pressed. The default sylesheet shows the selected date with a black border and black text and the current cursor position in blue.
In supporting browsers, the cursor is scaled by 1.2 whenever the datepicker has keyboard control and also given a discrete blue “pulse” effect.
Accessibility
The datepicker includes features designed with assitive technologies in mind.
The table structure
The HTML table representing the datepicker has been marked up with a THEAD, TBODY and, if a status bar is used, a TFOOT. The TH nodes representing the day names have their scope
attribute set to “col” and the nodes representing the week numbers, if used, have their scope
attribute set to “row”.
The use of the TITLE attribute
Each focusable TD node has been given a title
attribute that uses a default format of “%F %d, %Y” to describe the cells representative full date; for example, “March 13, 1970”. As some screen reader users disactivate the reading of title attributes, the full date is also added to each TD node but only the day part of the date format is actually displayed.
This means that screen reader users will still have a full date read aloud whenever the active “cursor” is given focus by the script. By default, the TD cell date format is of the form “%d %F %Y” i.e “13 March 1970” but both this and the title format can be changed to suit your needs by passing JSON within the script tag – this is explained in more detail within the section Setting Global configuration parameters.
Keyboard accessibility
All keyboard shortcuts – with the exception of the space bar – now adhere to The DHTML Style Guide Working Group (DSGWG) recommendations. It’s worth noting that keeping the key depressed activates a timed increment i.e. there’s absolutely no need to repeatedly press the key in order to change the month or year value within the interface (which helps with the dreaded “year of birth” conundrum). Key combinations are listed below:
Key Combination | Action |
---|---|
← → ↑ ↓ | Day navigation |
Page Up | Previous month |
Page Down | Next month |
Ctrl + page up | Previous year |
Ctrl + page down | Next year |
Space | Today’s date |
Esc | Close datepicker (without selecting date) |
Return | Select highlighted date and close datepicker |
2–7 | Select the corresponding day as the first day of the week |
ARIA Roles & Properties
The following ARIA Roles are set for the datepicker:
Role | Associated HTML element |
---|---|
grid | Assigned to the TABLE |
gridcell | Assigned to all TD nodes |
row | Assigned to all TR nodes within the TBODY |
columnheader | Assigned to all of the TH nodes representing the day of the week |
rowheader | Assigned to all of the week number TH nodes (if present) |
button | Assigned to a popup datepickers activation button |
The following ARIA Properties are set for the datepicker:
Property | Associated HTML element |
---|---|
hidden | Assigned to the wrapper DIV for all invisible popup datepickers, the first two TR nodes within the THEAD (used to display the day & month and navigation buttons) and disabled datepickers and activation buttons. |
selected | Assigned to the currently selected dates TD node |
describedby | If the describedby global configuration parameter has been set, then this is used to set the describedby relationship |
labelledby | If the associated form element has a label, the label is used to set the labelledby relationship |
haspopup | Assigned to a popup datepickers activation button |
disabled | Assigned to a disabled datepicker |
Callback functions
The following callback events are available:
Event | Description |
---|---|
datereturned |
Called everytime the script updates the associated form element(s) value |
dateset |
Called before the script updates the currently selected value – this is called whenever the associated form elements onchange event fires or a date has been selected using the datepicker |
redraw |
Called whenever a datepicker updates the U.I. |
domcreate |
Called whenever the datepicker is added to the DOM |
dombuttoncreate |
Called whenever a popup datepickers activation button is added to the DOM |
Stipulating callback functions is as easy as adding a “callbackFunctions” parameter to the initialisation Object and setting the parameter value to be itself an Object of key/value pairs – where the key names one of the available callbacks and the associated value is an Array of functions to call.
A pseudocode example of this is shown below:
datePickerController.createDatePicker({
formElements:{
"inp1":"%d/%m/%Y"
},
// Stipulate some callback functions
callbackFunctions:{
"redraw":[function1, function2, ... functionN],
"dombuttoncreate":[function1, function2, ... functionN]
}
});
Callback function arguments
All callback functions are passed one argument, a Javascript Object containing the following list of key/value pairs:
Key | Value |
---|---|
id |
the ID of the first form element stipulated within the initialisation object |
date |
A Javascript Date Object representing the selected date or NULL if no date is selected |
dd |
The two figure date part of the selected date or NULL if no date is selected |
mm |
The two figure month part of the selected date or NULL if no date is selected |
yyyy |
The four figure year part of the selected date or NULL if no date is selected |
The “redraw” callback function
The “redraw” callback is a special case and receives the following two additional parameters:
Key | Value |
---|---|
firstDateDisplayed |
A String representing the YYYYMMDD value of the first date currently displayed |
lastDateDisplayed |
A String representing the YYYYMMDD value of the last date currently displayed |
Additionally, functions defined for the “redraw” callback can return a Javascript Object whose keys are YYYYMMDD Date format Strings and associated key value a String representing classNames to add to the table cells representing specific dates. For example, the following Object, when returned from the “redraw” callback function, will add the class “santa” to the cell that represents Christmas day 2009:
{
"20091225":"santa"
}
The Javascript A.P.I
The datePickerController
Object has the following list of public methods:
Method | Description |
---|---|
setDebug(Boolean debug) |
Accepts a Boolean value that, when set to TRUE, will make the script throw Javascript errors should a problem occur. When set to FALSE, the script should silently fail whenever an error occurs. |
addEvent(obj, type, fn) |
A classic addEvent function (just in case you need one). |
removeEvent(obj, type, fn) |
A classic removeEvent function. |
show(String inputID) |
Makes a popUp datepicker associated with form element “inputID” appear i.e. fade in. |
hide(String inputID) |
Makes a popUp datepicker associated with form element “inputID” dissappear i.e. fade out. |
destroyDatePicker(String inputID) |
Removes the datepicker associated with form element “inputID” from the DOM and browser memory. |
cleanUp() |
Loops through the current list of in-memory datepickers and checks to see if their associated form element(s) exist within the DOM; if not, the datepicker is itself removed from the DOM and browser memory. |
printFormattedDate(Date dt, String fmt, Boolean useImportedLocale) |
Accepts three arguments, a Javascript Date Object, a date format String and a Boolean value that when TRUE, instructs the script to use the imported locale or when FALSE, to default to using the English locale. Returns a String containing the Date “dt” formatted to format “fmt”. |
setDateFromInput(String inputID) |
Instructs the datepicker associated with form element “inputID” to update its currently selected date by parsing the associated form element value(s). |
setSelectedDate(String inputID, [String|Date] yyyymmdd) |
Instructs the datepicker associated with form element “inputID” to update its currently selected date to the “yyyymmdd” value passed as the second argument. This value can be either a YYYYMMDD date format String or a Javascript Date Object. If the setting of the date is successful, the associated form element values will be updated to reflect the new date. |
setRangeLow(String inputID, [String|Date] yyyymmdd) |
Explained in more detail within the section Setting the date range dynamically. |
setRangeHigh(String inputID, [String|Date] yyyymmdd) |
Explained in more detail within the section Setting the date range dynamically. |
parseDateString(String str, String format) |
Accepts two arguments, the first a fully formed date String (e.g. “13th March 1970”) and the second, a date format String that the first argument is parsed against. Returns a Javascript Date Object on success or FALSE on failure. |
setGlobalOptions(String JSON) |
Explained in more detail within the section Setting Global configuration parameters. |
dateValidForSelection(String inputID, Date date) |
Returns a Boolean value indicating whether the Date “date” is valid for selection or not i.e. within the allowed date ranges and not disabled etc for the datepicker associated with form element “inputID”. |
getSelectedDate(String inputID) |
Returns a JavaScript Date Object if the datepicker associated with form element “inputID” has a currently set date or FALSE if not. |
setBespokeTitles(String inputID, Object titles) |
Explained in more detail within the section Setting status bar messages dynamically. |
addBespokeTitles(String inputID, Object titles) |
Explained in more detail within the section Setting status bar messages dynamically. |
setDisabledDates(String inputID, Object datelist) |
Explained in more detail within the section Disabling date selection. |
addDisabledDates(String inputID, Object datelist) |
Explained in more detail within the section Disabling date selection. |
setEnabledDates(String inputID, Object datelist) |
Explained in more detail within the section Enabling date selection. |
addEnabledDates(String inputID, Object datelist) |
Explained in more detail within the section Enabling date selection. |
disable(String inputID) |
Disables the datepicker associated with the form element “inputID” and stops all mouse and keyboard interaction. |
enable(String inputID) |
Enables the datepicker associated with the form element “inputID”. |
createDatePicker(Object options) |
Creates a datepicker using the initialisation Object “options”. |
dateToYYYYMMDDStr(Date date) |
Returns a YYYYMMDD date format String from the Javascript Date Object “date”. |
Installation guide
A quick guide to installing the script on your server.
Please note: Steps #1 and #2 are only necessary if you want to support Internet Explorer versions 6 & 7. If no support for these browsers is required then jump straight to step #3.
- Step #1: Upload the images to your server
Upload the images downloaded with the distribution into a directory of your choice on the server.
- Step #2: Update the CSS file to point to the uploaded images
Open the
datepicker.min.css
file in a text editor and find/replace the Stringhttp://www.yourdomain.com/the/path/to/the/images/
with the absolute path to the folder into which you uploaded the images in step #1.- Step #3: Upload the JS and CSS files to your server
Upload all CSS and JS files to your server, not forgetting to add the various
language.js
files within a directory named “lang”, itself resident within the same directory as thedatepicker.min.js
file.
The minified versions of the Javascript and CSS files can then be referenced within your HTML page; for example:
<!-- Add the CSS file -->
<link href="/the/path/to/datepicker.min.css" rel="stylesheet" type="text/css" />
<!-- Add the Javascript file -->
<script src="/the/path/to/datepicker.min.js"></script>
The License
The script is now released under a double MIT/GPL2 license. If you require another license, just ask politely.