jQuery Date/Time Entry

A jQuery plugin that sets an input field up to accept a date and/or time value using a spinner.

For date entry via a popup calendar, use the jQuery Datepicker plugin. For support of other world calendars, and a datepicker that works with them, see the jQuery Calendars plugin. This plugin combines the jQuery Date Entry and jQuery Time Entry plugins and will replace them.

The current version is 2.0.0 and is available under the MIT licence. For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.

Default Settings

The date/time entry functionality can easily be added to an input field with appropriate default settings. Also shown is the control's appearance when disabled.

Default date/time entry:    

$('#defaultEntry').datetimeEntry().change(function() {
	var log = $('#log');
	log.val(log.val() + ($('#defaultEntry').val() || 'blank') + '\n');
});

On change log:

The defaults are:

You can enable or disable date/time entry fields.

$('#enableDefault').click(function() {
	var disable = $(this).text() === 'Disable';
	$(this).text(disable ? 'Enable' : 'Disable');
	$('#defaultEntry').datetimeEntry(disable ? 'disable' : 'enable');
});

Or completely remove the date/time entry functionality.

$('#removeDefault').click(function() {
	var destroy = $(this).text() === 'Remove';
	$(this).text(destroy ? 'Re-attach' : 'Remove');
	$('#defaultEntry').datetimeEntry(destroy ? 'destroy' : {});
});

You can override the defaults globally as shown below:

$.datetimeEntry.setDefaults({spinnerImage: 'img/spinnerDefault.png'});

Processed fields are marked with a class of is-datetimeEntry and are not re-processed if targeted a second time.


A note on Date - the JavaScript Date constructor expects the year, month, and day as parameters. However, the month ranges from 0 to 11. To make explicit what date is intended (does a month of 3 mean March or April?) I specify the month from 1 to 12 and manually subtract the 1. Thus the following denotes 25 December, 2010.

$(selector).datetimeEntry({minDatetime: new Date(2010, 12-1, 25)});
Keystrokes

The date/time entry field also responds to keystrokes. You may also specify alternate separators for keyed entry. In this case you can also use '.' or '-'.

Keyboard driven:

 

$('#keyedEntry').datetimeEntry({datetimeSeparators: '.-'});

$('#tabToExit').change(function() {
	$('#keyedEntry').datetimeEntry('option', 'tabToExit', $(this).is(':checked'));
});

The relevant keystrokes are:

Date/Time Formats

You can control how the date/time is presented. The datetimeFormat setting consists of a sequence of characters indicating the order of the fields and any separators. Use 'y' for two-digit year, 'Y' for four-digit-year, 'o' for month, 'O' two-digit month, 'n' for abbreviated month name, 'N' for full month name, 'd' for day, 'D' two-digit day, 'w' for abbreviated day of the week and day, 'W' for full day of the week and day, 'h' for hours, 'H' two-digit hours, 'm' for minutes, 'M' two-digit minutes, 's' for seconds, 'S' two-digit seconds, or 'a' for AM/PM. Hours are displayed in 24-hour time if no AM/PM field is included.

European format:

$('#europeEntry').datetimeEntry({datetimeFormat: 'D/O/Y H:M'});

ISO format:

$('#isoEntry').datetimeEntry({datetimeFormat: 'Y-O-DTH:M:S'});

Short year:

$('#shortEntry').datetimeEntry({datetimeFormat: 'd/o/y h:Ma'});

Textual month:

$('#monthEntry').datetimeEntry({datetimeFormat: 'd n Y H:Ma'});

Textual day:

$('#dayEntry').datetimeEntry({datetimeFormat: 'w n Y H:Ma'});

Full day and month:

$('#fullEntry').datetimeEntry({datetimeFormat: 'W N Y H:Ma'});

Date only:

$('#dateEntry').datetimeEntry({datetimeFormat: 'D n Y'});

Day and month only:

$('#dayMonthEntry').datetimeEntry({datetimeFormat: 'd/o'});

Month and year only:

$('#monthYearEntry').datetimeEntry({datetimeFormat: 'N Y'});

Time only:

$('#timeEntry').datetimeEntry({datetimeFormat: 'H:M:Sa'});

Interact with the inputs:

When setting the date/time you can provide a Date object, or a number of seconds from now, or a string containing the period and units: 'y' for years, 'o' for months, 'w' for weeks, 'd' for days, 'h' for hours, 'm' for minutes, or 's' for seconds. Letters may be upper or lower case. Multiple offsets may be combined into the one setting.

function getTheDateTime() {
	alert('The date/time is ' + $('#' + $('#pickInput').val()).
		datetimeEntry('getDatetime'));
}

function setTheDateTime() {
	var date = ($('#abs').is(':checked') ?
		new Date(2014, 1 - 1, 26, 11, 30) : '+1o +1w +10h');
	$('#' + $('#pickInput').val()).datetimeEntry('setDatetime', date);
}

$('#getTheDateTime').click(getTheDateTime);
$('#setTheDateTime').click(setTheDateTime);
Date/Time Restrictions

You can restrict the functionality of the date/time entry fields in various ways. Such as limiting the range of dates and/or times selectable within the field. Or you can constrain the time increments, for example to only the quarter hours.

Limited date/times:

$('#restrictRange').datetimeEntry({minDatetime: new Date(2013, 10 - 1, 4, 9, 0, 0), 
	maxDatetime: new Date(2013, 10 - 1, 8, 17, 30, 0)});

Limited time range only:

$('#restrictTimes').datetimeEntry({minTime: new Date(0, 0, 0, 9, 0, 0), 
	maxTime: new Date(0, 0, 0, 17, 30, 0)});

Limited time increments:

$('#restrictIncrements').datetimeEntry({timeSteps: [1, 15, 0]});

Limited date/times by string:

$('#restrictString').datetimeEntry({
	minDatetime: '10/04/2013 09:00AM', maxDatetime: '10/08/2013 05:30PM'});

The range of selectable dates/times can also be set as relative to the current date/time. Use a number for seconds from now, or a string containing the period and units: 'y' for years, 'o' for months, 'w' for weeks, 'd' for days, 'h' for hours, 'm' for minutes, or 's' for seconds. Letters may be upper or lower case. Multiple offsets may be combined into the one setting.

Relative limited date/times:

$('#restrictRelative').datetimeEntry({minDatetime: -300, maxDatetime: '+2d +30m'});
Miscellaneous Features

To make it easier to use the spinner, you can set it to expand on hover.

Expanded spinner:  

$('#expandedSpinner').datetimeEntry(
	{spinnerBigImage: 'img/spinnerDefaultBig.png'});

$('#enableSpinner').click(function() {
	var disable = $(this).text() === 'Disable';
	$(this).text(disable ? 'Enable' : 'Disable');
	$('#expandedSpinner').datetimeEntry(disable ? 'disable' : 'enable');
});

You can set an alternate field to be kept synchronised with the date/time entry field, and it may have a different format. Use this to display more user-friendly text while passing a more easily used format to the server.

Alternate field:

$('#withAlternate').datetimeEntry({datetimeFormat: 'w n Y H:Ma',
	altField: '#alternateField', altFormat: 'Y-O-DTH:M:S'});

You can set which portion of the date/time should be initially highlighted.

Highlight second field:

$('#highlightDays').datetimeEntry({initialField: 1});

You can set a default date/time to show when nothing has been selected. If this setting is not specified, it defaults to the current date/time.

Absolute default date/time:

$('#absoluteDefault').datetimeEntry(
	{defaultDatetime: new Date(2014, 1 - 1, 26, 11, 30, 0)});

String default date/time:

$('#stringDefault').datetimeEntry(
	{defaultDatetime: '01/26/2014 11:30AM'});

Alternatively, the default date/time can be set relative to the current date/time. Use a number for seconds from now, or a string containing the period and units: 'y' for years, 'o' for months, 'w' for weeks, 'd' for days, 'h' for hours, 'm' for minutes, or 's' for seconds. Letters may be upper or lower case. Multiple offsets may be combined into the one setting.

Relative numeric default date/time:

$('#relativeNumericDefault').datetimeEntry({defaultDatetime: +600});

Relative string default date/time:

$('#relativeStringDefault').datetimeEntry({defaultDatetime: '+1w +2h'});

Retrieve the millisecond offset for the selected time. This value could be added to a midnight Date to set its time.

Millisecond offset:

$('#offsetEntry').datetimeEntry({datetimeFormat: 'H:M:S'});
$('#offsetButton').click(function() {
	alert('Milliseconds = ' + $('#offsetEntry').datetimeEntry('getOffset'));
});
Date/time Range

Use a custom field settings function to create a date/time range control: two date/time fields, each restricting the other. The function takes an input field as an argument and returns a settings object.

Date/time range: to

$('input.datetimeRange').datetimeEntry({beforeShow: datetimeRange});

function datetimeRange(input) {
	return {minDatetime: (input.id === 'dtTo' ?
		$('#dtFrom').datetimeEntry('getDatetime') : null), 
		maxDatetime: (input.id === 'dtFrom' ?
		$('#dtTo').datetimeEntry('getDatetime') : null)};
}

Date only range: to

$('input.dateRange').datetimeEntry({datetimeFormat: 'Y-O-D'}).
	change(function() {
		$('#' + (this.id === 'dFrom' ? 'dTo' : 'dFrom')).datetimeEntry(
			'option', (this.id === 'dFrom' ? 'minDatetime' : 'maxDatetime'),
			$(this).datetimeEntry('getDatetime'));
	});

Time only range: to

$('input.timeRange').datetimeEntry({datetimeFormat: 'H:M:S'}).
	change(function() {
		$('#' + (this.id === 'tFrom' ? 'tTo' : 'tFrom')).datetimeEntry(
			'option', (this.id === 'tFrom' ? 'minTime' : 'maxTime'),
			$(this).datetimeEntry('getDatetime'));
	});
Spinner Settings

Change the spinner. The first one has no central "Now" button, while the last has only the increment and decrement buttons.

Alternate spinners:  

 

 

 

 

 

Specify the size of the new spinner image (width and height) along with the size of the central button (0 for none) so that the location of the individual "buttons" can be determined. Suppress the previous/next buttons with spinnerIncDecOnly.

$('#spinnerSquare').datetimeEntry({spinnerImage: 'img/spinnerSquare.png',
	spinnerSize: [20, 20, 0], spinnerBigSize: [40, 40, 0]});
$('#spinnerOrange').datetimeEntry({spinnerImage: 'img/spinnerOrange.png'});
$('#spinnerText').datetimeEntry({spinnerImage: 'img/spinnerText.png',
	spinnerSize: [30, 20, 8], spinnerBigSize: [60, 40, 16]});
$('#spinnerGem').datetimeEntry({spinnerImage: 'img/spinnerGem.png'});
$('#spinnerUpDown').datetimeEntry({spinnerImage: 'img/spinnerUpDown.png',
	spinnerSize: [15, 16, 0], spinnerBigSize: [30, 32, 0],
	spinnerIncDecOnly: true});
	
$('#expand').change(function() {
	var expanded = $(this).is(':checked');
	$('.spinners').each(function() {
		$(this).datetimeEntry('option', {spinnerBigImage:
			(expanded ? 'img/' + this.id + 'Big.png' : '')});
	});
});

$('#disableSpinners').click(function() {
	var disable = $(this).text() === 'Disable';
	$(this).text(disable ? 'Enable' : 'Disable');
	$('input.spinners').datetimeEntry(disable ? 'disable' : 'enable');
});

Disable auto-repeat:

$('#disableRepeat').datetimeEntry({spinnerRepeat: [0, 0]});

No mouse wheel support:

$('#noMouseWheel').datetimeEntry({useMouseWheel: false});

No spinner image:

$('#noSpinnerEntry').datetimeEntry({spinnerImage: ''});
Inline Configuration

Instead of configuring date/time entry fields via parameters to the instantiation call, you can specify many of them inline in the data-datetimeEntry attribute.

Inline configuration 1:

Inline configuration 2:

<input type="text" size="20" class="inlineConfig"
	data-datetimeEntry="useMouseWheel: false, datetimeFormat: 'D-O-Y H:Ma', appendText: ' (see below)'">
	
<input type="text" size="10" class="inlineConfig"
	data-datetimeEntry="minDatetime: 'new Date(2013, 1 - 1, 26, 11, 30, 0)',
	maxDatetime: 'new Date(2014, 1 - 1, 26, 12, 45, 0)'">
$('.inlineConfig').datetimeEntry();

Or reconfigure on the fly.

Reconfiguration:

$('#reConfig').datetimeEntry({datetimeFormat: 'O/D/Y H:Ma'});
$('#switchButton').click(function() {
	var format = $('#reConfig').datetimeEntry('option', 'datetimeFormat') === 'O/D/Y H:Ma' ?
		'Y-O-D H:M' : 'O/D/Y H:Ma';
	$('#reConfig').datetimeEntry('option', {datetimeFormat: format});
});
Localisation

You can localise the date/time entry fields for other languages and regional differences. The date/time entry defaults to English with a date/time format of mm/dd/yyyy hh:mmap. Select a language to change the date/time format and spinner tooltips.

:

 

 

You need to load the appropriate language package (see list below), which adds a language set ($.datetimeEntry.regionalOptions[langCode]) and automatically sets this language as the default for all date/time entry fields.

<script type="text/javascript" src="jquery.datetimeentry-fr.js"></script>

Thereafter, if desired, you can restore the original language settings.

$.datetimeEntry.setDefaults($.datetimeEntry.regionalOptions['']);

And then configure the language per date/time entry field.

$('#l10nDatetime').datetimeEntry($.datetimeEntry.regionalOptions['fr']);
$('#l10n2Datetime').datetimeEntry($.extend({},
	$.datetimeEntry.regionalOptions['fr'], {datetimeFormat: 'w n Y H:Ma'}));
$('#l10n3Datetime').datetimeEntry($.extend({},
	$.datetimeEntry.regionalOptions['fr'], {datetimeFormat: 'W N Y H:Ma'}));
$('#language').change(localise);
In the Wild

This tab highlights examples of this plugin in use "in the wild".

To add another example, please contact me (wood.keith{at}optusnet.com.au) and provide the plugin name, the URL of your site, its title, and a short description of its purpose and where/how the plugin is used.

Quick Reference

A full list of all possible settings is shown below. Note that not all would apply in all cases. For more detail see the documentation reference page.

$(selector).datetimeEntry({
	datetimeFormat: 'O/D/Y H:Ma', // The format of the date text:
		// 'y' for short year, 'Y' for full year, 'o' for month, 'O' for two-digit month,
		// 'n' for abbreviated month name, 'N' for full month name,
		// 'd' for day, 'D' for two-digit day, 'w' for abbreviated day name and number,
		// 'W' for full day name and number), 'h' for hour, 'H' for two-digit hour,
		// 'm' for minute, 'M' for two-digit minutes, 's' for seconds,
		// 'S' for two-digit seconds, 'a' for AM/PM indicator (omit for 24-hour)
	datetimeSeparators: '.', // Additional separators between datetime portions
	monthNames: ['January', 'February', 'March', 'April', 'May', 'June',
		'July', 'August', 'September', 'October', 'November', 'December'], // Names of the months
	monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // Abbreviated names of the months
	// Names of the days
	dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
	dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // Abbreviated names of the days
	ampmNames: ['AM', 'PM'], // Names of morning/evening markers
	// The popup texts for the spinner image areas
	spinnerTexts: ['Today', 'Previous field', 'Next field', 'Increment', 'Decrement'],

	appendText: '', // Display text following the input box, e.g. showing the format
	initialField: null, // The field to highlight initially,
		// use 0 for the first field, or null for user selection
	tabToExit: false, // True for tab key to go to next element,
		// false for tab key to step through internal fields
	useMouseWheel: true, // True to use mouse wheel for increment/decrement if possible,
		// false to never use it
	shortYearCutoff: '+10', // The century cutoff for two-digit years,
		// absolute (numeric) or relative (string)
	defaultDatetime: null, // The date to use if none has been set, leave at null for now
	minDatetime: null, // The earliest selectable datetime, or null for no limit
	maxDatetime: null, // The latest selectable datetime, or null for no limit
	minTime: null, // The earliest selectable time regardless of date, or null for no limit
	maxTime: null, // The latest selectable time regardless of date, or null for no limit
	timeSteps: [1, 1, 1], // Steps for each of hours/minutes/seconds when incrementing/decrementing
	spinnerImage: 'spinnerDefault.png', // The URL of the images to use for the date spinner
		// Seven images packed horizontally for normal, each button pressed, and disabled
	spinnerSize: [20, 20, 8], // The width and height of the spinner image,
		// and size of centre button for current date
	spinnerBigImage: '', // The URL of the images to use for the expanded date spinner
		// Seven images packed horizontally for normal, each button pressed, and disabled
	spinnerBigSize: [40, 40, 16], // The width and height of the expanded spinner image,
		// and size of centre button for current date
	spinnerIncDecOnly: false, // True for increment/decrement buttons only, false for all
	spinnerRepeat: [500, 250], // Initial and subsequent waits in milliseconds
		// for repeats on the spinner buttons
	beforeShow: null, // Function that takes an input field and
		// returns a set of custom settings for the date entry
	altField: null, // Selector, element or jQuery object for an alternate field to keep synchronised
	altFormat: null // A separate format for the alternate field
});

$.datetimeEntry.regionalOptions[] // Language/country-specific localisations

$.datetimeEntry.setDefaults(settings) // Set default values for all instances

$(selector).datetimeEntry('option', settings) // Change the settings for selected instances
$(selector).datetimeEntry('option', name, value) // Change a single setting for selected instances
$(selector).datetimeEntry('option', name) // Retrieve a setting value

$(selector).datetimeEntry('destroy') // Remove the date entry functionality

$(selector).datetimeEntry('disable') // Disable date entry

$(selector).datetimeEntry('enable') // Enable date entry

$(selector).datetimeEntry('isDisabled') // Determine if field is disabled

$(selector).datetimeEntry('setDatetime', datetime) // Set the date/time for the instance

$(selector).datetimeEntry('getDatetime') // Retrieve the currently selected date/time

$(selector).datetimeEntry('getOffset') // Retrieve time only offset
Usage
  1. Include the jQuery library (1.7+) in the head section of your page.
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  2. Download and include the jQuery Date/Time Entry CSS and JavaScript in the head section of your page.
    <link rel="stylesheet" type="text/css" href="css/jquery.datetimeentry.css">
    <script type="text/javascript" src="js/jquery.plugin.js"></script>
    <script type="text/javascript" src="js/jquery.datetimeentry.js"></script>
    Alternately, you can use the minified version jquery.datetimeentry.min.js (19.5K vs 47.5K, 6.1K after zipping).
  3. Connect the date entry functionality to your input controls.
    $(selector).datetimeEntry();
    You can include custom settings as part of this process.
    $(selector).datetimeEntry({datetimeFormat: 'D/O/Y H:Ma'});

For more detail see the documentation reference page. Or see a minimal page that you could use as a basis for your own investigations.

Localisations

Localisation packages are available for download and should be loaded after the main date entry code. These packages automatically apply their settings as global default values.

Other translations are welcomed.

Comments

Finding your site was a godsend! I've been looking for a user friendly way to enter times for an age, and you jquery plugin was exactly what I needed.

Steve Coleman

Contact Keith Wood at wood.keith{at}optusnet.com.au with comments or suggestions.

Change History
VersionDateChanges
2.0.001 Mar 2014
  • Updated underlying plugin framework
  • Marker class changed from hasDatetimeEntry to is-datetimeEntry
  • Added tabToExit option to control tabbing
  • Changed regional to regionalOptions
  • Allowed day/month and month/year only combinations
  • Defaulted initialField to null for user selection (Thanks to Jesse Rosenberg)
  • Reset character input on changing fields
  • Added Arabic localisation
1.1.109 Mar 2013
  • Updated for jQuery 1.9
  • Removed input wrapper
  • Corrected metadata usage
1.1.010 Nov 2012
  • Changed change command to option
  • Added option retrieval
  • Updated underlying plugin framework
  • Keydown processing returns true for unhandled keystrokes
1.0.104 Jun 2011
  • Using setDatetime command with null or '' clears the date/time
  • disable command prevents the spinner expanding
1.0.023 Oct 2010
  • Initial release