A customizable date-time-picker using jQuery + jQuery-ui and moment.js.
- Features
- Installation
- Dependencies
- Internal Parameters
- Options
- Functions
- Hooks
- Manipulators
- Defining Buttons
- ToDos
- License
- Date+Time picker: Picker allows selecting both date and time values. Time input is only available if
'time'
isoptions.allow
ed and will be shown in day-level selection view. - Day/Week/Month/Year selection:
options.allow
define what can be selected using plugin. - Inline Display: Picker can be used as an inline object.
Please download the latest release from Releases Section, unzip it into your project and then take a look at the next section (Usage) for more information on how to use the plugin
Refer to
examples/index.html
for some examples.
- see this note about setting
options.allow
. - see this note about selecting/displaying
weeks
. - see this note about defining
options.template
.
- jQuery
- jQuery-UI (position, uniqueId, today symbol comes from a jquery-ui theme image)
- moment.js
can be any of 'time'
, 'days'
, 'weeks'
, 'months'
, 'years'
, 'decades'
respectively to begin the selection from day, month, year or decade level.
⬆ back to top or ⬅ back to internal parameters
List:
allow
buttons
classes
debug
displayWeeks
hooks
inline
locale
max
min
position
sticky
timeouts
template
trigger
view
if set, it should be an object with $.DateTimePicker.views
values as keys, and acceptable moment.js
formats as values, which will then allow setting output on different views - default = null
Refer to this note for more information about selecting/displaying
weeks
.
This option MUST be set for each instance in order to tell it which views are allowed and which values can be selected. IF no value is set (is with default value), no date/time can be picked and the picker will not drill down. (read more notes)
⬆ back to top or ⬅ back to options
an array containing buttons ready to be appended to the placeholder - default: null
⬆ back to top or ⬅ back to options
a list of classes (in string form, space separated) to be assigned to the placeholder - default: null
⬆ back to top or ⬅ back to options
will force the placeholder to stay open after a blur or click outside the picker is detected - default: false
,
⬆ back to top or ⬅ back to options
Defines if plugin should show week numbers.
if
weeks
is set inoptions.allow
, thendisplayWeeks
is automatically turned on, as selecting weeks is made possible by allowing users to click on the week numbers. (read more notes)
⬆ back to top or ⬅ back to options
a list of hooks to be assigned to the instance - default: null
⬆ back to top or ⬅ back to options
automatically appends a <div class="datetimepicker-inline"></div>
after the element and shows the placeholder in that div
- default: false
⬆ back to top or ⬅ back to options
tells moment.js
which locale should be used when formatting values and outputs - default: 'default'
(delivered in dep\locale\default.js
)
⬆ back to top or ⬅ back to options
maximum selectable date - default: null
(no maximum)
⬆ back to top or ⬅ back to options
minimum selectable date - default null
(no minimum)
⬆ back to top or ⬅ back to options
a valid jQuery-Ui position() value - default: null
which will tell the system to use the following position:
position = {
my: 'center top',
at: 'center bottom+5',
of: base.$el,
collision: 'flipfit'
}
Refer to jQueryUi#position for more information.
⬆ back to top or ⬅ back to options
if set to true, the placeholder will not be automatically hidden when a click/blur-event outside of placeholder or input field is detected - default: false
⬆ back to top or ⬅ back to options
defines the timeouts for different activities in the plugin:
Note: Changing these values might drastically affect the usability as these values are responsible for disappearance of the widget and updating it after values in input fields are changed. it might also result in inconsistencies in usability and input-data-loss, as it will cause the values in input fields to change after given time on inactivity in another field.
sets the time in ms
between clicking outside the widget / changing focus of input-field and hiding of the widget - default: 200
sets the time in ms
between changing the value in the input-field (defined by the selector) and it affecting the widget's look - prevents constant refreshes when manually changing the date-time value - default: 500
sets the time in ms
between changing the value in time
field and it affecting time portion of input-field - prevents constant changing of input-value; which in return would refresh the widget - default: 500
⬆ back to top or ⬅ back to options
HTML template for the plugin view - default is null
This value MUST be set for each instance or else the plugin will show nothing. As the plugin can be installed on any path, the option cannot have a working default value. Nevertheless, the value can be globally set using something like:
$.DateTimePicker.defaultOptions.template = $.DateTimePicker.getTemplate('../src/html/datetimepicker.html');
There is a working template available in src/html folder. Users can calculate its path and use the method mentioned above to set the option value. The example page shows this in action. (read more notes)
⬆ back to top or ⬅ back to options
if defined, show
action will be executed on click
-event of the defined trigger(s). The value can be either a selector, which defines a trigger to open options.view
, but it can also be an object with keys defining the selectors and values defining their viewpoint
- default: null
, acceptable values:
// define a single trigger with default to `options.view`
let example1 = {
trigger: '#button-id'
};
let example2 = {
trigger: {
'#button-id1': 'days', // #button-id1 opens `days` view
'#button-id2': 'months' // #button-id2 opens `months` view
}
};
⬆ back to top or ⬅ back to options
sets the view-level which is used when the picker is shown. default: 'days'
can be any of $.DateTimePicker.views
⬆ back to top or ⬅ back to options
callHook
isDisabled
getPlaceholder
getFormat
allows
matchValueView
getDateTime
showCalendar
drawButtons
getNextAllowed
isBetweenRange
setOptions
it checks whether disableHooks
manipulator is set or not. if not, then looks for defined hooks
and executes it using given parameters.
Note: called functions have access to the instance using
this
$target
is a DOM element, which when click
ed, will set the day, month or year in input field. this function checks if the given $target
is disabled, which usually means it's outside the allowed date-range (defined using min and max)
⬆ back to top or ⬅ back to functions
returns the widget placeholder. if none is defined for the instance, then it will first create it.
⬆ back to top or ⬅ back to functions
it returns the allow
ed format for a given view
or undefined
.
⬆ back to top or ⬅ back to functions
it returns a boolean
view indicting if the given view
is defined as allow
ed.
checkTime
is only useful ifview === 'days'
, and it will check if eitherdays
ortime
isallow
ed.
⬆ back to top or ⬅ back to functions
checks if the provided datetime
value matches any of the allow
ed formats.
⬆ back to top or ⬅ back to functions
returns a moment.js
object containing either the value of input-field or if not set, current date-time.
⬆ back to top or ⬅ back to functions
shows the widget opened with view
as view-point, set to datetime
⬆ back to top or ⬅ back to functions
creates buttons defined in options.buttons
.
⬆ back to top or ⬅ back to functions
to be documented
⬆ back to top or ⬅ back to functions
checks whether the value provided in datetime
is between min
and max
value. to do so, it adjusts the precision of datetime
and current set value to view
level, i.e. if for example view === 'months'
, it only checks the dates in months level and day
and time
values won't be considered while checking.
⬆ back to top or ⬅ back to functions
merges events
and options provided in options
into current instance. it activates new hooks
(if any defined) and attaches default event handlers to the instance. it also prepares and initiates the trigger
s
⬆ back to top or ⬅ back to functions
Are used to extend the functionality of the plugin without the need to write parts of the code completely from the scratch.
All the hook callbacks have the value "this" referring to the DateTimePicker object of that instance:
/**
* @internal this - refers to the DateTimePicker object, allows access to DateTimePicker functions
*/
executed at the end of initiation process - prototype:
/**
*/
function init(){}
⬆ back to top or ⬅ back to hooks
executed after hide()
event is executed. please note that hide()
event doesn't necessarily hide the $placehoder
, as hiding it is dependent on this.options.inline
value; nevertheless, the hook is executed regardless.
/**
*/
function hide(){}
⬆ back to top or ⬅ back to hooks
executed after the plugin has set the value - prototype:
/**
* @param datetime - value to be set in the input field - to be formatted according to view
* @param view - the view which has caused the set action
*/
function set(datetime, view){}
NOTE: this function is not executed on "change" events. to run it on change, please use an event-listener like:
$('#example').DateTimePicker().on(
"change",
function (){
let $this = $(this);
let base = $this.data('DateTimePicker');
base.callHook("set", $this);
}
);
⬆ back to top or ⬅ back to hooks
executed after placeholder's show() event is finished. can be used to adjust view
/**
* @param view - which view is used for the preparation of widget
*/
function show(view){}
⬆ back to top or ⬅ back to hooks
executed before showing the calender widget - prototype:
/**
* @param $placeholder - the jquery-ready HTML of the calender-widget for current instance
* @param view - which view is used for the preparation of widget
*/
function showCalendar($placeholder, view){}
⬆ back to top or ⬅ back to hooks
In order to ease temporary runtime manipulation of plugin behavior, a new parameter-set is defined. Following parameters can be set to affect plugin's behavior:
To use the manipulators, their values can be set as following:
let $picker = $('#date-picker');
$picker.DateTimePicker('manipulate', {disableHooks: true});
// do your thing
$picker.DateTimePicker('manipulate', {disableHooks: false});
if set to true
, hooks will not be executed. can be used to stop recursive call of hooks if they (in)directly cause each other to be triggered.
let $picker = $('#date-picker');
$picker.DateTimePicker('manipulate', {disableHooks: true});
$picker.data("DateTimePicker").show(); // `hooks.show` won't be executed.
$picker.DateTimePicker('manipulate', {disableHooks: false});
⬆ back to top or ⬅ back to manipulators
can be any of $.DateTimePicker.views
. the views allowing a more accurate value selection will not be shown. Setting value directly is not affected. this can be used, for example, to define view-triggers
.
$picker = $('#date-picker');
$picker.on('focus', function(){
$picker.DateTimePicker('manipulate', {maxDrillDown: null});
});
$('#month_picker_trigger').on('click', function(){
$picker.DateTimePicker('manipulate', {maxDrillDown: 'months'});
});
$('#day_picker_trigger').on('click', function(){
$picker.DateTimePicker('manipulate', {maxDrillDown: 'days'});
});
⬆ back to top or ⬅ back to manipulators
In order to facilitate defining buttons, a new class $.DateTimePicker.Button
was defined. its properties will be used to create buttons automatically. in addition, $.DateTimePicker.DefaultButtons
defines a few handy predefined functionalities (at the moment now
-button, midnight
-button)
accepts following options:
var options = {
name: '',
label: '',
className: '',
title:'',
placeholder: null,
onClick: function(dateTimePickerInstance){},
show: function(dateTimePickerInstance){} // can also be true or false
};
these options will translate into: <button class='{options.className}' name='{options.name}' onClick='{options.onClick([Date-Time-Picker-Instance])}'>{options.label}</button>
will be evaluated before putting the button on the page. it can be any value which could be interpreted as boolean, or it could define a function, which should return true
or false
. if the value is evaluated to false
, then the button will not appear in the widget.
it's possible to change a button's settings using this function. but they won't take effect if they buttons are already drawn, unless buttons are redrawn with drawButtons()
.
Note: functions
show()
andonClick()
have access to button's properties usingthis
. each button option as accessible viathis[{optionName}]
, like for examplebase.className
,base.name
, etc.
⬆ back to top or ⬅ back to Defining Buttons
currently, 2 default buttons are defined in this class:
now
button will set date/time values to current moment.dayBegin
button will set the time to0:00:00.000
of selected day. by default it's only available (i.e.show
n) iftime
selection is allowed.dayEnd
button will set the time to23:59:59.99999999
of selected day. by default it's only available (i.e.show
n) iftime
selection is allowed.
$.DateTimePicker.DefaultButtons = {
now: new $.DateTimePicker.Button({
name: 'now',
label: 'Now',
onClick: function (picker){
if(picker instanceof $.DateTimePicker)
{
let current = moment();
picker.events.set.call(picker, current, null);
picker.$el.change();
}
}
}),
dayBegin: new $.DateTimePicker.Button({
name: 'day_begin',
label: 'Day Begin',
onClick: function (picker){
if(picker instanceof $.DateTimePicker)
{
let current = moment(picker.$el.val());
current.set({
hour: 0,
minute: 0,
second: 0,
millisecond: 0
});
picker.events.set.call(picker, current, null);
picker.$el.change();
}
},
show: function(picker){
if (picker instanceof $.DateTimePicker)
{
return (picker.allows("time") && picker.viewpoint === 'days');
}
else
{
return false;
}
}
}),
dayEnd: new $.DateTimePicker.Button({
name: 'day_end',
label: 'Day End',
onClick: function (picker){
if(picker instanceof $.DateTimePicker)
{
let current = moment(picker.$el.val());
current.set({
hour: 23,
minute: 59,
second: 59,
millisecond: 999
});
picker.events.set.call(picker, current, null);
picker.$el.change();
}
},
show: function(picker){
if (picker instanceof $.DateTimePicker)
{
return (picker.allows("time") && picker.viewpoint === 'days');
}
else
{
return false;
}
}
})
};
⬆ back to top or ⬅ back to Defining Buttons
-
Better
Options
Validation: invalid formats (for exampleDD/Y
orH:ss
should be detected and reported) -
Better Separation of View/Controller: the template and the controlling code are tightly coupled at the moment but using constant values for placeholders and selectors will make it possible to customize the view even more.
- Other Calendars' Support: for the time being, gregorian calendar is fully supported. Support of other calendars is provided by plugins like Jalaali Calendar Plugin or Hijri Calendar Plugin, but has not been tested.
Refer to Plugins Section of Moment.js for more information.
Licensed under MIT.