Andrew_M_Andrews_III =
( AJAX + JSON + XML ) * ( Consulting + Training );

Any+Time DatePicker/TimePicker AJAX Calendar Widget

The Any+Time™ JavaScript Library includes a highly-customizable datepicker/ timepicker (calendar) and a powerful Date/String parse/format utility.

NEW! Any+Time™ Version 3 is now jQuery compatible!

Above: example datepicker and timepicker, with selectable themes (using jQuery UI Theme Switcher). Below: Date/time widget using default style, a 24-hour clock and era selection. Click the buttons on any of these widgets to change values. Examples of pop-up widgets and other variations follow.

AnyTime.widget() creates a JavaScript date/time picker with many unusual features and options:

DATE/TIME OPTIONS:

  • 12-hour or 24-hour clock
  • custom date/time format (many options)
  • date-only, time-only, or specific fields!
  • date/time range limits
  • prehistoric dates (BCE/CE, BC/AD, etc.)
  • start week on any day (Sunday, Monday, etc.)
  • custom 2-digit base year (1900, 2000, etc.)

STYLING OPTIONS:

PROGRAMMER-FRIENDLY:

  • write a single line of JavaScript code!
  • easy AJAX validation
  • easy Date/String conversion (using AnyTime.Converter)

USABILITY FEATURES:

  • em-based relative-size
  • single-click value selection
  • WAI-ARIA 1.0 keyboard accessibility

A single line of JavaScript code is all you need to add a date/time picker to any <input> field! Choose between a pop-up (appearing when the corresponding field receives focus) or always-present widget (with either a visible or hidden field).

Use AnyTime.Converter to parse a String into a Date, or convert a Date to a String. Many format options are supported—in fact, most of the fields specified by the MySQL DATE_FORMAT() function!

Any+Time™ uses (and is therefore compatible with) the free jQuery JavaScript Library. The compatible jQuery version number is mentioned in the header comment in the JavaScript source code (anytime.js). An older version (2.x), based on Prototype, is still available below.

AnyTime.widget() has been tested compatible with Chrome 3.0, Firefox 3.0, Internet Explorer 8.0, Opera 10.10 and Safari 4.0, and should work with any version of ECMA-262 (JavaScript, JScript, ECMAScript, etc.) and HTML/XHTML supported by jQuery.

Any+Time™ follows WIA-ARIA Authoring Practices 1.0 for Date Picker keyboard interaction as closely as possible, to maximize accessibility without a mouse. Use Tab to navigate between the date and time sections, and arrows to navigate between time-selection buttons.

Creative Commons License

Any+Time™ is $ FREE $ under the Creative Commons BY-NC-SA 3.0 License. Please contact the author for a commercial license tailored to your specific needs!

Instructions

Follow these easy steps to use Any+Time™ on your website!

1. Download

Any+Time™ consists of a single JavaScript source file with a single CSS stylesheet file. Both files are formatted to be human-readable, and they contain extensive comments to help you understand and modify them. Right-click on either link to save the file:

You may wish to use the compressed (unformatted, no comments) versions instead, for faster download.

Remember, you also need a compatible version of jQuery.

PROTOTYPE LIBRARY USERS:

Version 2.x uses the Prototype JavaScript Library (prototype.js) instead of jQuery. This older version is still available:

2. Save and Include

Save a copy of the JavaScript source and CSS stylesheet files on your web server, remove the last line from the JavaScript file, and reference both files in your HTML page. For example, if you install jquery.js, anytime.js and anytime.css in the document root directory, then add the following lines to the <head> section of the HTML page:

    <link rel="stylesheet" type="text/css" href="/anytime.css" />
    <script type="text/javascript" src="/jquery.js" ></script>
    <script type="text/javascript" src="/anytime.js" ></script>

For proper formatting, the <link> element must appear before the <script> elements!

3. Create HTML Input Fields

Create your date and/or time field as a simple <input type="text"> element with a unique id attribute. You should also specify a tabindex attribute.

Here are examples of a date-only field that uses a verbose format, and a time-only field with a Spanish label:

    English: <input type="text" id="foo" tabindex="2" size="50"
               value="Sunday, July 30th in the Year 1967 CE" /><br/>
    Español: <input type="text" id="bar" tabindex="3" value="12:34" />

4. Add JavaScript Code

Call AnyTime.widget() in your JavaScript code, passing it the id of the input element and any desired options. Be sure the code is executed after the text field is created, or AnyTime.Widget won't know which field you're talking about! The code to add widgets to the example fields could be:

    <script type="text/javascript">
      AnyTime.widget( "foo", 
          { format: "%W, %M %D in the Year %z %E", firstDOW: 1 } );
      AnyTime.widget( "bar", 
          { format: "%H:%i", labelTitle: "Tiempo",
            labelHour: "Hora", labelMinute: "Minuto" } );
    </script>

Want a live demonstration? Click one of the following text fields to display the corresponding popup widget! For the first field, try choosing a year in the very distant past.

English:
Español:

The first field specifies that the week begins with Monday.

The second field demonstrates a customized style, achieved by the following CSS changes:

    <style type="text/css">
      #bar {border:3px double green;color:green}
      #Atw_bar {background-color:yellow;border:3px double green}
      #Atw_bar .AtwBtn {border:1px solid yellow;color:green;
          font-style:italic}
      #Atw_bar .AtwBody {padding-left:0px}
      #Atw_bar .AtwCurrentBtn {background-color:red;
          border:1px solid yellow;color:yellow;}
      #Atw_bar .AtwDismissBtn {background-color:white;color:red}
      #Atw_bar .AtwFocusBtn {border:1px solid green}
      #Atw_bar .AtwLbl {color:green}
      #Atw_bar .AtwTitle {background-color:red;border-bottom:none;
          color:yellow;font-family:cursive;font-size:14pt;height:30px}
    </style>

The following members may be specified as part of the options object (second argument):

ajaxOptions
Options pass to jQuery's $.ajax() method whenever the user dismisses a popup widget or selects a value in an inline widget. The input's name (or id) and value are passed to the server (appended to ajaxOptions.data, if present), and the "success" handler sets the input's value to the responseText. Therefore, the text returned by the server must be valid for the input's date/time format, and the server must either echo or correct the value chosen by the user. For example, the server for the following AJAX-enabled widget always changes the day-of-the-month to 1 after the component is dismissed, no matter what day the user actually selects:
  <input type="text" id="AjaxDemo" tabindex="4" value="Apr 1, '10"/>
  <script type="text/javascript">
    AnyTime.widget( "AjaxDemo",
        { ajaxOptions: { url: "ajaxdemo.php" },
          baseYear: 2000,
          format: "%b %e, '%y" } );
  </script>


If ajaxOptions.success is specified, it is used instead of the default "success" behavior. Refer to the jQuery documentation for information about that library's Ajax options.
askEra
If true, buttons to select the era (BCE/CE) are shown on the year selector popup, even if the format specifier does not include the era. If false, buttons to select the era are NOT shown, even if the format specifier includes the era. Normally, era buttons are only shown if the format string specifies the era.
askSecond
If false, buttons for number-of-seconds are not shown on the year selector popup, even if the format specifier includes seconds. Normally, the buttons are shown if the format string specifies seconds.
baseYear
the number to add to two-digit years if the "%y" format specifier is used. By default, the MySQL convention that two-digit years are in the range 1970 to 2069 is used. The most common alternatives are 1900 and 2000.
dayAbbreviations
An array of day abbreviations to replace Sun, Mon, etc. Note that if a different first day-of-week is specified by option firstDOW, this array should nonetheless start with the desired abbreviation for Sunday.
dayNames
An array of day names to replace Sunday, Monday, etc. Note that if a different first day-of-week is specified by option firstDOW, this array should nonetheless start with the desired name for Sunday.
earliest
String or Date object representing the earliest date/time that a user can select. If a String is specified, it is expected to match the format specifier. For best results if the field is only used to specify a date, be sure to set the time to 00:00:00.
eraAbbreviations
An array of era abbreviations to replace BCE and CE. The most common replacements are the obsolete: BC and AD.
firstDOW
a value from 0 (Sunday) to 6 (Saturday) stating which day should appear at the beginning of the week. The default is 0 (Sunday). The most common substitution is 1 (Monday). Note that if custom arrays are specified for dayAbbreviations and dayNames, they should nonetheless begin with the desired value for Sunday.
format
string specifying the date/time format (refer to following table)
hideInput
if true, the <input> is "hidden" (the widget appears in its place). This actually sets the border, height, margin, padding and width of the field as small as possible, so it can still get focus. If you try to hide the field using traditional techniques (such as setting display:none), the widget will not behave correctly. This option should not used with placement:"inline", or the popup will seem to appear from nowhere if the user tabs to the hidden field.
labelDayOfMonth
HTML to replace the Day of Month label
labelDismiss
HTML to replace the dismiss popup button's X label
labelHour
HTML to replace the Hour label
labelMinute
HTML to replace the Minute label
labelMonth
HTML to replace the Month label
labelTitle
HTML for the title of the widget. If not specified, the widget automatically selects a title based on the format specifier fields.
labelYear
HTML to replace the Year label
latest
String or Date object representing the latest date/time that a user can select. If a String is specified, it is expected to match the format specifier. For best results if the field is only used to specify a date, be sure to set the time to 23:59:59.
monthAbbreviations
An array of month abbreviations to replace Jan, Feb, etc.
monthNames
An array of month names to replace January, February, etc.
placement
One of the following strings:
"popup"
the widget appears above its input when the input receives focus, and disappears when it is dismissed. This is the default behavior.
"inline"
the widget follows the <input> and remains visible at all times. When choosing this placement, you might prefer to hide the input field using the hideInput option (the correct value will still be submitted with the form).

For example, the date/time widget near the beginning of this page was created by the following HTML:
  <input type="text" id="ATWidgetDemo" tabindex="1" />
  <script type="text/javascript">
    AnyTime.widget( "ATWidgetDemo",
        { format: "%Y-%m-%d %H:%i:%s (%E)",
          hideInput: true,
          placement: "inline" } );
  </script>

The following format specifiers are recognized:

specifiermeaning
%aAbbreviated weekday name (Sun...Sat)
%BAbbreviation for Before Common Era (if year<1)*
%bAbbreviated month name (Jan...Dec)
%CAbbreviation for Common Era (if year>=1)*
%cMonth, numeric (0..12)
%DDay of the month with English suffix (1st, 2nd, ...)
%dDay of the month, numeric (00...31)
%EEra abbreviation*
%eDay of the month, numeric (0...31)
%HHour (00...23)
%hHour (01...12)
%IHour (01...12)
%iMinutes, numeric (00...59)
%kHour (0...23)
%lHour (1...12)
%MMonth name (January...December)
%mMonth, numeric (00...12)
%pAM or PM
%rTime, 12-hour (hh:mm:ss followed by AM or PM)
%SSeconds (00...59)
%sSeconds (00...59)
%TTime, 24-hour (hh:mm:ss)
%WWeekday name (Sunday...Saturday)
%wDay of the week (0=Sunday...6=Saturday)
%YYear, numeric, four digits (possibly signed)
%yYear, numeric, two digits (possibly signed)
%ZYear, numeric, four digits (no sign)*
%zYear, numeric, variable length (no sign)*
%%A literal % character

The default format is "%Y-%m-%d %T".

* Note: except for those delimited by an asterisk in the table above, these are the same format fields used by the MySQL database DATE_FORMAT() function. The default format is the one used for MySQL DATETIME and TIMESTAMP data types.

Any other character in the format string appears literally in the value. Any other sequence of percent sign ("%") followed by a character is replaced by the literal character following the percent sign, except for the following MySQL specifiers not implemented due to lack of support in JavaScript: %f (microseconds); %j (day-of-year); %U, %u, %V and %v (week-of-year); and %X and %x (year-for-week). Do not use these format specifiers.

5. Convert Strings from/to Dates

AnyTime.Converter can be used independently. The following example converts dates in ISO date/time format:

    var conv = new AnyTime.Converter({format:"%Y-%m-%dT%H:%i:%s"});
    var date = conv.parse("1990-01-06T15:00:00");
    alert( conv.format(date) );

AnyTime.Converter accepts the following options, which are the same as for AnyTime.widget(): baseYear, dayAbbreviations, dayNames, eraAbbreviations, format, monthAbbreviations and monthNames.

AnyTime.Converter supports all of the same format field specifiers as AnyTime.widget().

Check the JavaScript source code for more detailed instructions on AnyTime.Converter and AnyTime.widget().

6. Problems? No Problem!

Minor variations in Microsoft Internet Explorer are to be expected (especially in versions prior to IE8, due to its broken box model). For best results, be sure to include an appropriate <!DOCTYPE> declaration as the first line of your HTML page; for example:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">

When using placement:"inline", XHTML and a day-of-the-month format specifier ("%D", "%d" or "%e"), the <input> may only appear where a <table> element is permitted (for example, NOT within a <p> element). This is because the widget uses a <table> element to arrange the day-of-the-month (calendar) buttons. Failure to follow this advice may result in a JScript "unknown error" from Internet Explorer.

Be careful to place all <link rel="stylesheet"> and <style> elements before the <script> elements, or WebKit-based browsers (Apple Safari and Google Chrome) might not format the widget correctly (symptoms include extremely-tall widgets and mis-placed time buttons).

When specifying the "earliest" and/or "latest" option, be certain to include a time value, even if the user is only able to select the date. The time for an "earliest" date should be 00:00:00, and the time for a "latest" date should be 23:59:59. This is because the Date objects used by the widget reflect exact moments in time, regardless of which fields are specified by the format. Failure to set the time could result in incorrect enforcement if, for example, the page is loaded at 23:59 one day, but the field not changed until 00:01 the day after!

Only use the hideInput option to hide the <input> associated with a widget. Traditional techniques (such as setting display:none) will cause the widget to behave incorrectly.

It should go without saying that Any+Time™ only works in browsers with JavaScript enabled. Any server-side form processing should validate every value it receives, in case JavaScript was disabled or otherwise unavailable when the form was submitted.

Any+Time™ follows WIA-ARIA Authoring Practices 1.0 for Date Picker keyboard interaction as closely as possible, to maximize accessibility without a mouse. However, if a user reports difficulty changing a date/time value using the widget (for example, due to problems with a "screen reader" or other assistive technology), ask them to disable JavaScript and carefully type the value into the input field. Again, be sure to validate the input when it is received by the server.

Remember that two-digit years ("%y") are susceptible to the Y2K problem! For best results, use four-digit or variable-length years ("%Y", "%Z" or "%z") instead. The baseYear option can also be helpful in situations where "%y" is required.

The JavaScript source file includes an intrusive alert() call on the last line, to discourage hot-linking to this server. When you download the file, be sure to remove the last line to eliminate annoying messages when your HTML page is loaded!

If you experience any other problems, please contact the author.

7. Rate This Script

Please give this script the best rating at the following websites:

Both positive feedback and constructive criticism are also appreciated (please contact the author).

Copyright 2010 AJAX, JSON and XML Consulting and Training by Andrew M. Andrews III (SM). All Rights Reserved. "Andrew M. Andrews III", "AMA3", Andrew_M_Andrews_III, Any+Time and the Tre Design are trademarks and/or service marks of Andrew M. Andrews III. Use this site at your own risk. Use of this site for illegal or malicious purposes is prohibited.