Skip to content

arashdalir/datetimepicker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DateTimePicker

A customizable date-time-picker using jQuery + jQuery-ui and moment.js.

Table of Contents

Features

  1. Date+Time picker: Picker allows selecting both date and time values. Time input is only available if 'time' is options.allowed and will be shown in day-level selection view.
  2. Day/Week/Month/Year selection: options.allow define what can be selected using plugin.
  3. Inline Display: Picker can be used as an inline object.

⬆ back to top

Installation

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

⬆ back to top

Usage

Refer to examples/index.html for some examples.

Usage Notes

  1. see this note about setting options.allow.
  2. see this note about selecting/displaying weeks.
  3. see this note about defining options.template.

⬆ back to top

Dependencies

  1. jQuery
  2. jQuery-UI (position, uniqueId, today symbol comes from a jquery-ui theme image)
  3. moment.js

⬆ back to top

Internal Parameters

$.DateTimePicker.views

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

Options

List:

allow

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.

Setting allow Value

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

buttons

an array containing buttons ready to be appended to the placeholder - default: null

⬆ back to top or ⬅ back to options

classes

a list of classes (in string form, space separated) to be assigned to the placeholder - default: null

⬆ back to top or ⬅ back to options

debug

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

displayWeeks

Defines if plugin should show week numbers.

Showing/Selecting weeks

if weeks is set in options.allow, then displayWeeks 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

hooks

a list of hooks to be assigned to the instance - default: null

⬆ back to top or ⬅ back to options

inline

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

locale

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

max

maximum selectable date - default: null (no maximum)

⬆ back to top or ⬅ back to options

min

minimum selectable date - default null (no minimum)

⬆ back to top or ⬅ back to options

position

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

sticky

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

timeouts

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.

blur Timeout

sets the time in ms between clicking outside the widget / changing focus of input-field and hiding of the widget - default: 200

valueInputChange Timeout

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

timeInputChange Timeout

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

template

HTML template for the plugin view - default is null

Setting Template

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

trigger

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

view

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

Functions

callHook(hookName, arg1, arg2, ...)

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

isDisabled($target)

$target is a DOM element, which when clicked, 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

getPlaceholder()

returns the widget placeholder. if none is defined for the instance, then it will first create it.

⬆ back to top or ⬅ back to functions

getFormat(view)

it returns the allowed format for a given view or undefined.

⬆ back to top or ⬅ back to functions

allows(view, checkTime)

it returns a boolean view indicting if the given view is defined as allowed.

  • checkTime is only useful if view === 'days', and it will check if either days or time is allowed.

⬆ back to top or ⬅ back to functions

matchValueView(datetime)

checks if the provided datetime value matches any of the allowed formats.

⬆ back to top or ⬅ back to functions

getDateTime()

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

showCalendar(datetime, view)

shows the widget opened with view as view-point, set to datetime

⬆ back to top or ⬅ back to functions

drawButtons()

creates buttons defined in options.buttons.

⬆ back to top or ⬅ back to functions

getNextAllowed(view, offset)

to be documented

⬆ back to top or ⬅ back to functions

isBetweenRange(datetime, view)

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

setOptions(options)

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 triggers

⬆ back to top or ⬅ back to functions

Plugin Hooks

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
*/

init

executed at the end of initiation process - prototype:

/**
*/
function init(){}

⬆ back to top or ⬅ back to hooks

hide

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

set

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

show

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

showCalendar

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

Manipulators

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});

disableHooks

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

maxDrillDown

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

Defining Buttons

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)

$.DateTimePicker.Button

accepts following options:

Button 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>

button.show()

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.

button.setOptions()

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() and onClick() have access to button's properties using this. each button option as accessible via this[{optionName}], like for example base.className, base.name, etc.

⬆ back to top or ⬅ back to Defining Buttons

$.DateTimePicker.DefaultButtons

currently, 2 default buttons are defined in this class:

  1. now button will set date/time values to current moment.
  2. dayBegin button will set the time to 0:00:00.000 of selected day. by default it's only available (i.e. shown) if time selection is allowed.
  3. dayEnd button will set the time to 23:59:59.99999999 of selected day. by default it's only available (i.e. shown) if time 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

ToDos

  • Better Options Validation: invalid formats (for example DD/Y or H: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.

Finished / Abandoned ToDos

Refer to Plugins Section of Moment.js for more information.

⬆ back to top

License

Licensed under MIT.

⬆ back to top