Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tail.datetime

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tail.datetime - npm Package Compare versions

Comparing version 0.3.4 to 0.4.0

css/tail.datetime-default-blue.css

63

CHANGELOG.md
CHANGELOG
=========
Version 0.4.0 - Beta
--------------------
- Info: This is the first BETA version! :3
- Info: This Repository is now completely independent, due to the removal of the last original
lines of MrGuiseppes pureJSCalendar script!
- Add: Russian translation (ru).
- Add: Designs in LESS Format (I'm new at this Pre-Processing Stuff :/).
- Add: Support as Asynchronous Module Definition.
- Add: The default design has 3 new, and the "harx" design has one additional color schemes.
- Add: The new option `animate` to enable and disable the fade and tooltip animations.
- Add: The new option `dateBlacklist` to turn the `dateRange` from a blacklist to a whitelist.
- Add: The new option `dateStart` to limit the calendar.
- Add: The new option `dateEnd` to limit the calendar.
- Add: The new option `locale` to change the used locale by the calendar.
- Add: The new option `timeHours` to set the default Hours on init (pass null for current).
- Add: The new option `timeMintes` to set the default Minutes on init (pass null for current).
- Add: The new option `timeSeconds` to set the default Seconds on init (pass null for current).
- Add: The new option `today` to mark the current day within the calendar script.
- Add: The new option `tooltips` to create tooltips on specific dates.
- Add: The new option `viewDefault` to select the default view, when the calendar gets opened.
- Add: The new option `viewDecades` enables the view "Decades" (Show different Decades).
- Add: The new option `viewYears` enables the view "Years" (Show 12 Years - One Decade).
- Add: The new option `viewMonths` enables the view "Months" (January - December).
- Add: The new option `viewDays` enables the view "Days" (01 - 28|29|30|31).
- Add: The new internal event trigger method `.trigger()`.
- Add: A new custom event listener, using `.on()` and `.trigger()`.
- Add: The new internal render and view methods `.renderCalendar()`, `.renderDatePicker()`,
`.renderTimePicker()`,`.viewDecades()`, `.viewYears()`, `.viewMonths()`, `.viewDays()`,
`.handleLabel()`, `.showTooltip()` and `.hideTooltip()`.
- Add: The new public method `.config()` to get and set settings during the runtime.
- Add: The new public methods `.switchView()`, `.browseView()`, `.switchDate()` and `.fetchDate()`
to control the calendar interface and fetch the current Date.
- Add: The new public methods `.appendTooltip()` and `.appendRange()` to append tooltips and date
ranges during the runtime.
- Update: The translations itself, as well as the translation / locale system behind.
- Update: Both designs has been updated to the new structure.
- Update: The main helper methods.
- Update: The calendar render process has been re-written, now it will always show 6 rows of
dates, including days from the previous and next month!
- Update: The locale system is now usable per instance, the strings doesn't get replaced!
- Update: The option `classNames` allows now `true` to copy the class names from the main
element and false, to do nothing.
- Update: The option `position` and `static` has been merged, so use "top", "left", "right" or
or "bottom" to show the calendar on an absolute position relative to the passed element
or pass any selector, which should be used as container.
- Update: The option `weekStart` supports now also numbers (SUN = 0, MON = 1, ... SAT = 6)!
- Update: The option `dateRange` requires now a new range format, the old one is NOT supported!
- Update: The public methods `.switchMonth()` and `switchYear()` now just aliases for the main
public method `.switchDate()`.
- Update: The public methods `.open()` and `.close()` now using `setTimeout()` instead of an
interval.
- Update: The public methods `.reload()` reloads the same instance instead of creating a new one.
- Update: The public event method `.on()` has been updated and supports now a third argument.
- Remove: The option `static` has been removed (use `position` instead).
- Remove: The option `zeroSeconds` has been removed (use `timeSeconds` instead).
- Remove: The option `static` has been removed (use `position` instead).
- Remove: The `isIE11` and `tail.IE` variables.
- Remove: The old render functions `.renderDay()`, `.renderMonth()` and `.renderTime()` has been
replaced by the new `.view*()` and `.render*()` methods!
- Remove: The `.createCalendar()` method has been replaced by the new `.view*()` methods.
- Bugfix: The `tbdy` typo has been fixed.
- Bugfix: Incorrect `colspan` value on the thead element (on the Months View).
Version 0.3.4 - Alpha

@@ -5,0 +68,0 @@ ---------------------

1603

js/tail.datetime.js
/*
| tail.DateTime - A pure, vanilla JavaScript DateTime Picker
| @author SamBrishes <https://github.com/pytesNET/tail.DateTime/>
| MrGuiseppe <https://github.com/MrGuiseppe/pureJSCalendar/>
| @version 0.3.4 [0.1.0] - Alpha
| @file ./js/tail.datetime.js
| @author SamBrishes <https://github.com/pytesNET/tail.DateTime/>
| @version 0.4.0 - Alpha
|
| @license X11 / MIT License
| @copyright Copyright © 2018 - SamBrishes, pytesNET <pytes@gmx.net>
| Copyright © 2018 - MrGuiseppe <https://github.com/MrGuiseppe>
| @fork MrGuiseppe <https://github.com/MrGuiseppe/pureJSCalendar/>
| This script started as fork and is now completely independent!
|
| @license X11 / MIT License
| @copyright Copyright © 2018 - SamBrishes, pytesNET <pytes@gmx.net>
*/
;(function(window){
;(function(factory){
if(typeof(define) == "function" && define.amd){
define(function(){ return factory(window); });
} else {
if(typeof(window.tail) == "undefined"){
window.tail = {};
}
window.tail.DateTime = factory(window);
}
}(function(root){
"use strict";
var w = window, d = window.document;
var w = root, d = root.document;
/*
| HELPER METHODs
*/
var tail = {
hasClass: function(element, name){
return (new RegExp("(|\s+)" + name + "(\s+|)")).test(element.className);
},
addClass: function(element, name){
if(!(new RegExp("(|\s+)" + name + "(\s+|)")).test(element.className)){
element.className = (element.className.trim() + " " + name.trim()).trim();
}
return element;
},
removeClass: function(element, name){
var regex = new RegExp("(|\s+)(" + name + ")(\s+|)");
if(regex.test(element.className)){
element.className = (element.className.replace(regex, "$1$3")).trim();
}
return element;
},
trigger: function(element, event, options){
if(CustomEvent && CustomEvent.name){
var e = new CustomEvent(event, options);
return element.dispatchEvent(e);
}
var e = d.createEvent("CustomEvent");
e.initCustomEvent(event, ((options.bubbles)? true: false), ((options.cancelable)? true: false), options.detail);
return element.dispatchEvent(e);
},
clone: function(object, replace){
replace = (typeof(replace) == "object")? replace: {};
var clone = object.constructor();
for(var key in object){
if(replace.hasOwnProperty(key)){
clone[key] = replace[key];
} else if(object.hasOwnProperty(key)){
clone[key] = object[key];
}
}
return clone;
// Internal Helper Methods
function cHAS(e, name){
return (new RegExp("\\b" + name + "\\b")).test((e.className || ""));
}
function cADD(e, name){
if(!(new RegExp("\\b" + name + "\\b")).test(e.className || name)){
e.className += " " + name;
}
return e;
}
function cREM(e, name, regex){
if((regex = new RegExp("\\b(" + name + ")\\b")) && regex.test(e.className || "")){
e.className = e.className.replace(regex, "");
}
return e;
}
function trigger(e, event, opt){
if(CustomEvent && CustomEvent.name){
var ev = new CustomEvent(event, opt);
} else {
var ev = d.createEvent("CustomEvent");
ev.initCustomEvent(event, !!opt.bubbles, !!opt.cancelable, opt.detail);
}
return e.dispatchEvent(ev);
}
function clone(obj, rep){
if(Object.assign){
return Object.assign({}, obj, rep || {});
}
var clone = Object.constructor();
for(var key in obj){
clone[key] = (key in rep)? rep[key]: obj[key];
}
return clone;
}
function first(str){ return str.charAt(0).toUpperCase() + str.slice(1); };
function parse(str, time, reset){
var date = (str instanceof Date)? str: (str)? new Date(str): false;
if(!(date instanceof Date) || isNaN(date.getDate())){
return false;
}
(reset)? date.setHours(0, 0, 0, 0): date;
return (time === true)? date.getTime(): date;
};
tail.IE = (w.navigator.userAgent.indexOf("MSIE") > -1 || w.navigator.userAgent.indexOf("Edge") > -1);

@@ -62,3 +74,3 @@ /*

| @since 0.1.0
| @update 0.3.4
| @update 0.4.0
*/

@@ -69,13 +81,11 @@ var tailDateTime = function(element, config){

}
if(element instanceof NodeList || element instanceof HTMLCollection){
if(element.length == 0){
return false;
if(element instanceof NodeList || element instanceof HTMLCollection || element instanceof Array){
for(var _r = [], l = element.length, i = 0; i < l; i++){
_r.push(new tailDateTime(element[i], config));
}
var _return = new Array();
for(var i = 0; i < element.length; i++){
_return.push(new tailDateTime(element[i], config));
}
return (_return.length == 1)? _return[0]: _return;
return (_r.length === 1)? _r[0]: ((_r.length === 0)? false: _r);
}
if(typeof(this) == "undefined"){
if(!(element instanceof Element)){
return false;
} else if(!(this instanceof tailDateTime)){
return new tailDateTime(element, config);

@@ -85,55 +95,23 @@ }

// Check Element
if(!(element instanceof Element)){
return false;
if(tailDateTime.inst[element.getAttribute("data-tail-datetime")]){
return tailDateTime.inst[element.getAttribute("data-tail-datetime")];
}
if(element.hasAttribute("data-tail-calendar") && tailDateTime.instances[element.getAttribute("data-tail-calendar")]){
return tailDateTime.instances[element.getAttribute("data-tail-calendar")];
}
// Vaildate DateRange
if(config.dateRanges && config.dateRanges.length > 0){
for(var t, i = 0; i < config.dateRanges.length; i++){
t = config.dateRanges[i];
// Week-Day
if(typeof(t[0]) == "string" && __("shorts").indexOf(t[0]) >= 0){
t[0] = __("shorts").indexOf(t[0]);
t[1] = (t.length >= 2 && __("shorts").indexOf(t[1]) >= 0)? __("shorts").indexOf(t[1]): 6;
continue;
}
// Date Object
if(typeof(t[0]) == "string"){
t[0] = new Date(Date.parse(t[0]));
if(t.length == 2 && typeof(t[1]) == "string"){
t[1] = new Date(Date.parse(t[1]));
} else if(t.length == 1){
t[1] = new Date(t[0].getFullYear(), t[0].getMonth(), 0);
}
}
if(!(t[0] instanceof Date && !isNaN(t[0].getDate()))){
t[0] = new Date();
}
if(t.length < 2 || !(t[1] instanceof Date && !isNaN(t[1].getDate()))){
t[1] = new Date(t[0].getFullYear(), t[0].getMonth(), 0);
}
if(element.getAttribute("data-datetime")){
var test = JSON.parse(element.getAttribute("data-datetime").replace(/\'/g, '"'));
if(test instanceof Object){
config = clone(config, test);
}
}
// Init Prototype Instance
// Init Instance
this.e = element;
config = (typeof(config) == "object")? config: {};
if(Object.assign){
this.con = Object.assign({}, tailDateTime.defaults, config);
} else {
this.con = tail.clone(tailDateTime.defaults, config);
}
this.id = ++tailDateTime.count;
this.con = clone(tailDateTime.defaults, config);
tailDateTime.inst["tail-" + this.id] = this;
return this.init();
};
tailDateTime.version = "0.3.4";
tailDateTime.status = "alpha";
tailDateTime.version = "0.4.0";
tailDateTime.status = "beta";
tailDateTime.count = 0;
tailDateTime.isIE11 = !!w.MSInputMethodContext && !!d.documentMode;
tailDateTime.cache = {};
tailDateTime.instances = {};
tailDateTime.inst = {};

@@ -144,12 +122,25 @@ /*

tailDateTime.defaults = {
static: null,
position: "bottom",
classNames: "",
animate: true,
classNames: false,
dateFormat: "YYYY-mm-dd",
timeFormat: "HH:ii:ss",
dateStart: false,
dateRanges: [],
weekStart: "SUN",
dateBlacklist: true,
dateEnd: false,
locale: "en",
position: "bottom",
startOpen: false,
stayOpen: false,
zeroSeconds: false
timeFormat: "HH:ii:ss",
timeHours: null,
timeMinutes: null,
timeSeconds: 0,
today: true,
tooltips: [],
viewDefault: "days",
viewDecades: true,
viewYears: true,
viewMonths: true,
viewDays: true,
weekStart: 0
};

@@ -161,17 +152,13 @@

tailDateTime.strings = {
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
shorts: ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"],
time: ["Hours", "Minutes", "Seconds"],
header: ["Select a Month", "Select a Year", "Select a Time"],
"en": {
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
shorts: ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"],
time: ["Hours", "Minutes", "Seconds"],
header: ["Select a Month", "Select a Year", "Select a Decade", "Select a Time"]
}
};
var __ = function(string, number){
if(string in w.tail.DateTime.strings){
if(number !== undefined){
return w.tail.DateTime.strings[string][number];
}
return w.tail.DateTime.strings[string];
}
return false;
}
tailDateTime.strings.register = function(locale, object){
tailDateTime.strings[locale] = object;
};

@@ -182,254 +169,277 @@ /*

tailDateTime.prototype = {
e: null, // The Input Element
dt: null, // The DateTime Picker
con: {}, // The Configuration Object
view: {}, // The current DateTime View
select: null, // The current selected Date (Object)
/*
| HANDLE :: INIT CALENDAR
| INTERNAL :: INIT CALENDAR
| @since 0.1.0
| @update 0.3.3
| @update 0.4.0
*/
init: function(){
if(this.dt){
return this.dt;
}
var _static = d.querySelector(this.con.static);
var self = this, temp;
this.__ = tailDateTime.strings[this.con.locale] || tailDateTime.strings["en"];
// Create DateTime Picker
this.dt = d.createElement("DIV");
this.dt.id = "data-tail-calendar-" + ++tailDateTime.count;
this.dt.className = "tail-datetime-calendar calendar-close" + ((_static)? " calendar-static": "");
if(this.con.stayOpen){
this.dt.className += " calendar-stay";
// Options
this.con.dateStart = parse(this.con.dateStart, true, true) || 0;
this.con.dateEnd = parse(this.con.dateEnd, true, true) || 9999999999999;
this.con.viewDefault = (!this.con.dateFormat)? "time": this.con.viewDefault;
if(typeof(this.con.weekStart) == "string"){
this.con.weekStart = tailDateTime.strings.en.shorts.indexOf(this.con.weekStart);
}
if(this.con.classNames){
this.dt.className += " " + ((this.con.classNames instanceof Array)? this.con.classNames.join(" "): this.con.classNames);
if(this.con.weekStart < 0 && this.con.weekStart > 6){
this.con.weekStart = 0;
}
// Create Calendar Structure
if(this.con.dateFormat){
this.dt.innerHTML = '' +
'<div class="calendar-navi">' +
' <span data-tail-navi="prev" class="calendar-button button-prev"></span>' +
' <span data-tail-navi="switch" class="calendar-label"></span>' +
' <span data-tail-navi="next" class="calendar-button button-next"></span>' +
'</div>' +
'<div class="calendar-date"></div>' +
((this.con.timeFormat)? '<div class="calendar-time">' + this.renderTime() + '</div>': '');
} else {
this.dt.innerHTML = '' +
'<div class="calendar-navi">' +
' <span data-tail-navi="check" class="calendar-button button-check"></span>' +
' <span data-tail-navi="switch" class="calendar-label">' + __("header", 2) + '</span>' +
' <span data-tail-navi="close" class="calendar-button button-close"></span>' +
'</div>' +
((this.con.timeFormat)? '<div class="calendar-time">' + this.renderTime() + '</div>': '');
// Prepare Date Ranges
if(this.con.dateRanges.length > 0){
for(var r = [], e = this.con.dateRanges, l = e.length, i = 0; i < l; i++){
if(!(e[i] instanceof Object) || (!e[i].start && !e[i].days)){
continue;
}
// Prepare Dates
if((e[i].start = parse(e[i].start || false, true, true)) === false){
e[i].start = e[i].end = Infinity;
} else {
if((e[i].end = parse(e[i].end || false, true, true)) === false){
e[i].end = e[i].start;
}
e[i].start = (e[i].start > e[i].end)? [e[i].end, e[i].end = e[i].start][0]: e[i].start;
}
// Prepare Days
e[i].days = (!e[i].days)? true: e[i].days;
e[i].days = (typeof(days) !== "boolean")? (function(days){
for(var _r = [], _l = days.length, _i = 0; _i < _l; _i++){
if(typeof(days[_i]) == "string"){
days[_i] = tailDateTime.strings.en.shorts.indexOf(days[_i]);
}
if(days[_i] >= 0 && days[_i] <= 6){ _r.push(days[_i]); }
}
return _r;
}((e[i].days instanceof Array)? e[i].days: [e[i].days])): [0, 1, 2, 3, 4, 5, 6];
// Append
r.push({start: e[i].start, end: e[i].end, days: e[i].days});
}
this.con.dateRanges = r;
}
// Set Calendar Data
var select = new Date(Date.parse(this.e.getAttribute("data-tail-value") || this.e.value));
this.view = {
type: "date",
date: new Date(),
content: "",
render: function(){ return this.content.querySelector("tbody").innerHTML; }
};
if(!isNaN(select.getDate())){
this.select = select;
if(this.con.zeroSeconds){
this.select.setSeconds(0);
// Prepare Tooltips
if(this.con.tooltips.length > 0){
for(var r = [], t = this.con.tooltips, l = t.length, i = 0, s, e; i < l; i++){
if(!(t[i] instanceof Object) || !t[i].date){
continue;
}
// Prepare Dates
if(t[i].date instanceof Array){
s = parse(t[i].date[0] || false, true, true);
e = parse(t[i].date[0] || false, true, true) || s;
} else {
s = e = parse(t[i].date || false, true, true);
}
if(!s){ continue; }
// Append
r.push({
date: (s !== e)? [s, e]: s,
text: t[i].text || "Tooltip",
color: t[i].color || "#202428",
element: t[i].element || (function(tooltip){
tooltip.className = "calendar-tooltip";
tooltip.innerHTML = '<div class="tooltip-inner">' + t[i].text || "Tooltip" + '</div>';
return tooltip;
}(d.createElement("DIV")))
});
}
this.view.date = new Date(this.select.getTime());
this.con.tooltips = r;
}
if(this.con.timeFormat){
this.dt.querySelector(".calendar-field-h > input").value = this.view.date.getHours();
this.dt.querySelector(".calendar-field-m > input").value = this.view.date.getMinutes();
this.dt.querySelector(".calendar-field-s > input").value = this.view.date.getSeconds();
// Prepare WeekDays
var week = this.__["shorts"].slice(this.con.weekStart).concat(this.__["shorts"].slice(0, this.con.weekStart));
this.weekdays = "<thead>\n<tr>\n";
for(var i = 0; i < 7; i++){
this.weekdays += '<th class="calendar-week">' + week[i] + '</th>';
}
this.weekdays += "\n</tr>\n</thead>"
this.switchMonth(this.view.date.getMonth(), this.view.date.getFullYear());
if(this.e.hasAttribute("data-tail-value")){
this.selectDate();
} else {
this.e.setAttribute("data-tail-value", this.convertDate(this.view.date, "YYYY-mm-dd HH:ii:ss"));
// Set Main Data and Render
this.select = parse(this.e.getAttribute("data-value") || this.e.value);
if(!this.select || this.select < this.con.dateStart || this.select > this.con.dateEnd){
this.select = null;
}
if(this.view == undefined){
this.view = {
type: this.con.viewDefault,
date: this.select || new Date()
};
}
for(var l = ["Hours", "Minutes", "Seconds"], i = 0; i < 3; i++){
if(typeof(this.con["time" + l[i]]) == "number"){
this.view.date["set" + l[i]](this.con["time" + l[i]]);
}
}
this.events = {};
this.dt = this.renderCalendar();
// Configure Calendar Widget
this.dt.style.top = 0;
this.dt.style.left = 0;
this.dt.style.zIndex = 99;
this.dt.style.position = (_static)? "static": "absolute";
this.dt.style.visibility = (_static)? "visible": "hidden";
if(_static){
_static.appendChild(this.dt);
} else {
d.getElementsByTagName("body")[0].appendChild(this.dt);
// Hook Events
if(this._bind == undefined){
var e = "addEventListener";
this.e[e]("focusin", function(event){
self.open.call(self);
});
this.e[e]("keyup", function(event){
self.bind.call(self, event);
});
d[e]("keyup", function(event){
self.bind.call(self, event);
});
d[e]("click", function(event){
if(self.dt.contains(event.target)){
self.bind.call(self, event);
} else if(!self.e.contains(event.target) && cHAS(self.dt, "calendar-open")){
if(event.target != self.dt && event.target != self.e && !self.con.stayOpen){
self.close.call(self);
}
}
});
d[e]("mouseover", function(event){
if(self.dt.contains(event.target)){
self.bind.call(self, event);
}
});
this._bind = true;
}
// Listen Header
var self = this, navi = this.dt.querySelectorAll("[data-tail-navi]");
if(navi.length > 0){
for(var i = 0; i < navi.length; i++){
navi[i].addEventListener("click", function(event){
var action = this.getAttribute("data-tail-navi");
// Store Instance and Return
this.e.setAttribute("data-tail-datetime", "tail-" + this.id);
if(this.con.startOpen){
this.open();
}
if(this.select){
this.selectDate(this.select);
}
return this;
},
if(self.con.dateFormat){
if(self.view.type == "month"){
if(action == "prev" || action == "next"){
self.switchYear.call(self, action);
} else {
self.switchView.call(self, "day");
}
} else {
if(action == "prev" || action == "next"){
self.switchMonth.call(self, action);
} else {
self.switchView.call(self, "month");
}
}
} else if(self.con.timeFormat){
if(action == "check"){
self.selectTime.call(self,
parseInt(self.dt.querySelector(".calendar-field-h > input").value),
parseInt(self.dt.querySelector(".calendar-field-m > input").value),
parseInt(self.dt.querySelector(".calendar-field-s > input").value)
);
}
if(!self.con.stayOpen){
self.close.call(self);
}
}
});
/*
| INTERNAL :: EVENT LISTENER
| @since 0.4.0
*/
bind: function(event){
var self = event.target, a = "getAttribute", d = "data-action", v = "data-view",
elem = self[a](d)? self: self.parentElement[a](d)? self.parentElement: self;
// Hover Events
var t = "data-tooltip", tip;
if(event.type == "mouseover"){
if((tip = self[a](t)? self: elem[a](t)? elem: false) !== false){
if(!this.dt.querySelector("#tooltip-" + tip[a](t) + "-" + tip[a](t + "-time"))){
this.showTooltip(tip[a](t), tip, tip[a](t + "-time"));
}
} else if(this.dt.querySelector(".calendar-tooltip:not(.remove)")){
this.hideTooltip(this.dt.querySelector(".calendar-tooltip").id.slice(8));
}
}
// Listen Input
this.e.addEventListener("focusin", function(event){
self.open.call(self);
});
this.e.addEventListener("focusout", function(event){
var select = new Date(Date.parse(this.value));
if(!isNaN(select.getDate())){
self.selectDate.call(self,
select.getFullYear(), select.getMonth(), select.getDate(),
select.getHours(), select.getMinutes(), select.getSeconds()
);
self.switchMonth.call(self, select.getMonth(), select.getFullYear());
// Click Events
if(event.type == "click"){
if(!elem || (event.buttons != 1 && (event.which || event.button) != 1)){
return;
}
});
this.e.addEventListener("keyup", function(event){
if(event.keyCode == 13){
var select = new Date(Date.parse(this.value));
if(!isNaN(select.getDate())){
self.selectDate.call(self,
select.getFullYear(), select.getMonth(), select.getDate(),
select.getHours(), select.getMinutes(), select.getSeconds()
);
self.switchMonth.call(self, select.getMonth(), select.getFullYear());
}
event.stopPropagation();
switch(elem[a](d)){
case "prev":
return this.browseView("prev");
case "next":
return this.browseView("next");
case "submit":
return this.selectDate(this.fetchDate(elem[a]("data-date")));
case "cancel":
if(!this.con.stayOpen){
this.close();
}
break;
case "view":
this.switchDate(elem[a]("data-year") || null, elem[a]("data-month") || null, elem[a]("data-day") || null);
return this.switchView(elem[a](v));
}
});
d.addEventListener("keyup", function(event){
if(tail.hasClass(self.dt, "calendar-open") && event.keyCode == 27){
if(!self.con.stayOpen){
self.close.call(self);
}
// KeyEvents
if(event.type == "keyup"){
if(event.target !== this.e){
if(/calendar-(static|close)/i.test(this.dt.className)){
return false;
}
self.e.blur();
}
if(tail.hasClass(self.dt, "calendar-open") && event.keyCode == 13){
if(self.con.dateFormat){
var day = self.dt.children[1].querySelector("td.today") || self.dt.children[1].querySelector("td:not(.empty)"),
time = !!self.con.timeFormat;
if(!tail.hasClass(day, "disabled")){
self.selectDate.call(self,
self.view.year, self.view.month, parseInt(day.value),
(time)? parseInt(self.dt.querySelector(".calendar-field-h > input").value): 0,
(time)? parseInt(self.dt.querySelector(".calendar-field-m > input").value): 0,
(time)? parseInt(self.dt.querySelector(".calendar-field-s > input").value): 0
);
}
} else {
self.selectTime.call(self,
parseInt(self.dt.querySelector(".calendar-field-h > input").value),
parseInt(self.dt.querySelector(".calendar-field-m > input").value),
parseInt(self.dt.querySelector(".calendar-field-s > input").value)
);
}
if(!self.con.stayOpen){
self.close.call(self);
}
self.e.blur();
if((event.keyCode || event.which) == 13){ // Enter || Return
this.selectDate(this.fetchDate());
event.stopPropagation();
if(!this.con.stayOpen){ this.close(); }
}
});
d.addEventListener("click", function(event){
if(!tail.hasClass(self.dt, "calendar-open")){
return;
if((event.keyCode || event.which) == 27){ // ESC
if(!this.con.stayOpen){ this.close(); }
}
if(!self.dt.contains(event.target) && !self.e.contains(event.target)){
if(event.target != self.dt && event.target != self.e){
if(!self.con.stayOpen){
self.close.call(self);
}
}
}
});
}
},
// Store Instance and Return
this.e.setAttribute("data-tail-calendar", "tail-" + tailDateTime.count);
if(this.con.startOpen){
this.open();
/*
| INTERNAL :: EVENT TRIGGER
| @since 0.4.0
*/
trigger: function(event){
var obj = {bubbles: false, cancelable: true, detail: {args: arguments, self: this}};
if(event == "change"){
trigger(this.e, "input", obj);
trigger(this.e, "change", obj);
}
tailDateTime.instances["tail-" + tailDateTime.count] = this;
return this;
trigger(this.dt, "tail::" + event, obj);
for(var l = (this.events[event] || []).length, i = 0; i < l; i++){
this.events[event][i].cb.apply(this, (function(args, a, b){
for(var l = a.length, i = 0; i < l; ++i){
args[i-1] = a[i];
}
args[i] = b;
return args;
}(new Array(arguments.length), arguments, this.events[event][i].args)));
}
},
/*
| HANDLE :: CALCULATE POSITION
| HELPER :: CALCULATE POSITION
| @since 0.3.1
| @update 0.4.0
*/
calcPosition: function(){
if(tail.hasClass(this.dt, "calendar-static")){
return this;
}
var style = w.getComputedStyle(this.dt),
marginX = parseInt(style.marginLeft)+parseInt(style.marginRight),
marginY = parseInt(style.marginTop)+parseInt(style.marginBottom),
position = (function(element){
var position = {
top: element.offsetTop || 0,
left: element.offsetLeft || 0,
width: element.offsetWidth || 0,
height: element.offsetHeight || 0
};
while(element = element.offsetParent){
position.top += element.offsetTop;
position.left += element.offsetLeft;
}
return position;
})(this.e);
var a = this.dt.style, b = w.getComputedStyle(this.dt),
x = parseInt(b.marginLeft)+parseInt(b.marginRight),
y = parseInt(b.marginTop) +parseInt(b.marginBottom),
p = (function(e, r){
r = {
top: e.offsetTop || 0, left: e.offsetLeft || 0,
width: e.offsetWidth || 0, height: e.offsetHeight || 0
};
while(e = e.offsetParent){ r.top += e.offsetTop; r.left += e.offsetLeft; }
return r;
})(this.e, {});
// Set Position
this.dt.style.visibility = "hidden";
a.visibility = "hidden";
switch(this.con.position){
case "top":
this.dt.style.top = position.top - (this.dt.offsetHeight + marginY) + "px";
this.dt.style.left = (position.left + (position.width / 2)) - (this.dt.offsetWidth / 2 + marginX / 2) + "px";
a.top = p.top - (this.dt.offsetHeight + y) + "px";
a.left = (p.left + (p.width / 2)) - (this.dt.offsetWidth / 2 + x / 2) + "px";
break;
case "left":
this.dt.style.top = (position.top + position.height/2) - (this.dt.offsetHeight / 2 + marginY) + "px";
this.dt.style.left = position.left - (this.dt.offsetWidth + marginX) + "px";
a.top = (p.top + p.height/2) - (this.dt.offsetHeight / 2 + y) + "px";
a.left = p.left - (this.dt.offsetWidth + x) + "px";
break;
case "right":
this.dt.style.top = (position.top + position.height/2) - (this.dt.offsetHeight / 2 + marginY) + "px";
this.dt.style.left = position.left + position.width + "px";
a.top = (p.top + p.height/2) - (this.dt.offsetHeight / 2 + y) + "px";
a.left = p.left + p.width + "px";
break;
default:
this.dt.style.top = position.top + position.height + "px";
this.dt.style.left = (position.left + (position.width / 2)) - (this.dt.offsetWidth / 2 + marginX / 2) + "px";
case "bottom":
a.top = p.top + p.height + "px";
a.left = (p.left + (p.width / 2)) - (this.dt.offsetWidth / 2 + x / 2) + "px";
break;
}
this.dt.style.visibility = "visible";
a.visibility = "visible";
return this;

@@ -439,485 +449,658 @@ },

/*
| HANDLE :: SWITCH VIEW
| HELPER :: CONVERT DATE
| @since 0.1.0
| @update 0.3.3
| @update 0.4.0
*/
switchView: function(view){
if(!this.con.dateFormat){
return false;
}
convertDate: function(inDate, format){
var dateObject = {
H: String("00" + inDate.getHours()).toString().slice(-2),
G: function(hours){ return (hours % 12)? hours % 12: 12; }(inDate.getHours()),
A: inDate.getHours() >= 12? "PM": "AM",
a: inDate.getHours() >= 12? "pm": "am",
i: String("00" + inDate.getMinutes()).toString().slice(-2),
s: String("00" + inDate.getSeconds()).toString().slice(-2),
Y: inDate.getFullYear(),
y: parseInt(inDate.getFullYear().toString().slice(2)),
m: String("00" + (inDate.getMonth() + 1)).toString().slice(-2),
M: this.__["months"][inDate.getMonth()].slice(0, 3),
F: this.__["months"][inDate.getMonth()],
d: String("00" + inDate.getDate()).toString().slice(-2),
D: this.__["days"][inDate.getDay()],
l: this.__["shorts"][inDate.getDay()].toLowerCase()
};
return format.replace(/([HGismd]{1,2}|[Y]{2,4}|y{2})/g, function(token){
if(token.length == 4 || token.length == 2){
return dateObject[token.slice(-1)].toString().slice(-Math.abs(token.length));
} else if(token.length == 1 && datePart[0] == "0"){
return dateObject[token.slice(-1)].toString().slice(-1)
}
return dateObject[token.slice(-1)].toString();
}).replace(/(A|a|M|F|D|l)/g, function(token){ return dateObject[token]; });
},
// Render View
this.view.type = view;
if(view == "month"){
this.dt.children[1].innerHTML = "";
this.dt.children[1].insertAdjacentHTML("afterbegin", this.renderMonth());
this.dt.querySelector(".calendar-label").innerText = this.view.date.getFullYear();
} else {
this.dt.children[1].innerHTML = this.renderDay();
this.dt.querySelector(".calendar-label").innerText = __("months", this.view.date.getMonth()) + " " + this.view.date.getFullYear();
/*
| RENDER :: CALENDAR
| @since 0.4.0
*/
renderCalendar: function(){
var _s, _c = ["tail-datetime-calendar", "calendar-close"], dt = d.createElement("DIV"),
_t = (this.con.classNames === true)? this.e.className: this.con.classNames;
// Disable on Ranges
var ranges = this.con.dateRanges, current = this.view.date,
fields = this.dt.querySelectorAll("tbody td:not(.empty)"),
compare = new Date(current.getFullYear(), current.getMonth(), current.getDate(), 0, 0, 0);
if(ranges.length > 0){
for(var enable = [], i = 0; i < ranges.length; i++){
if(ranges[i][0] instanceof Date){
if(current.getYear() >= ranges[i][0].getYear() && current.getYear() <= ranges[i][1].getYear()){
if(current.getMonth() >= ranges[i][0].getMonth() && current.getMonth() <= ranges[i][1].getMonth()){
for(var f = 0; f < fields.length; f++){
compare.setDate(parseInt(fields[f].innerText));
if(compare >= ranges[i][0] && compare <= ranges[i][1]){
enable.push(fields[f].innerText);
}
}
}
}
} else {
for(var f = 0; f < fields.length; f++){
compare.setDate(parseInt(fields[f].innerText));
if(ranges[i].length == 3 && ranges[i][3] == true){
if(compare.getDay() >= ranges[i][0] && compare.getDay() <= ranges[i][1]){
if(enable.indexOf(fields[f].innerText) == -1){
enable.push(fields[f].innerText);
}
}
}
if(compare.getDay() < ranges[i][0] || compare.getDay() > ranges[i][1]){
if(enable.indexOf(fields[f].innerText) >= 0){
enable.splice(enable.indexOf(fields[f].innerText), 1);
}
}
}
}
}
for(var f = 0; f < fields.length; f++){
if(enable.indexOf(fields[f].innerText) == -1){
tail.addClass(fields[f], "disable");
}
}
}
// Configure Calendar
if(["top", "left", "right", "bottom"].indexOf(this.con.position) < 0){
_s = d.querySelector(this.con.position);
_c.push("calendar-static");
}
if(typeof(_t) == "string" || _t instanceof Array){
_c = _c.concat(((typeof(_t) == "string")? _t.split(" "): _t));
}
if(this.con.stayOpen){
_c.push("calendar-stay");
}
dt.id = "tail-datetime-" + this.id;
dt.className = _c.join(" ");
// Select Current
if(this.select instanceof Date && this.select.getYear() == this.view.date.getYear() && this.select.getMonth() == this.view.date.getMonth()){
tail.addClass(this.dt.querySelectorAll("tbody td:not(.empty)")[this.select.getDate()-1], "current");
} else {
if(this.dt.querySelector("tbody td.current")){
tail.removeClass(this.dt.querySelector("tbody td.current"), "current");
}
}
// Render Action
if(this.con.dateFormat){
var _a = '<span class="action action-prev" data-action="prev"></span>'
+ '<span class="label" data-action="view" data-view="up"></span>'
+ '<span class="action action-next" data-action="next"></span>'
} else if(this.con.timeFormat){
var _a = '<span class="action action-submit" data-action="submit"></span>'
+ '<span class="label"></span>'
+ '<span class="action action-cancel" data-action="cancel"></span>'
}
if(typeof(_a) != "undefined"){
dt.innerHTML = '<div class="calendar-actions">' + _a + '</div>';
}
// Handle View
var self = this;
// Render Date and Time Picker
if(this.con.dateFormat){
var listen = this.dt.querySelectorAll("tbody td:not(.empty)");
for(var i = 0; i < listen.length; i++){
listen[i].addEventListener("click", function(event){
event.preventDefault();
event.stopPropagation();
this.renderDatePicker(dt, this.con.viewDefault);
}
if(this.con.timeFormat){
this.renderTimePicker(dt);
}
if(tail.hasClass(this, "disable")){
return false;
}
var time = !!self.con.timeFormat;
// Append Calendar
if(_s){
dt.style.cssText = 'position:static;visibility:visible;';
} else {
dt.style.cssText = 'top:0;left:0;z-index:999;position:absolute;visibility:hidden;';
}
(_s || document.body).appendChild(dt);
return dt;
},
if(self.view.type == "month"){
self.switchMonth.call(self, parseInt(this.getAttribute("data-tail-month")), self.view.date.getFullYear());
} else {
self.selectDate.call(self,
self.view.date.getFullYear(), self.view.date.getMonth(), parseInt(this.innerText),
(time)? parseInt(self.dt.querySelector(".calendar-field-h > input").value): 0,
(time)? parseInt(self.dt.querySelector(".calendar-field-m > input").value): 0,
(time)? parseInt(self.dt.querySelector(".calendar-field-s > input").value): 0
);
if(!self.con.stayOpen){
self.close.call(self);
}
}
});
}
/*
| RENDER :: DATE PICKER
| @since 0.4.0
*/
renderDatePicker: function(dt, view){
if(!view || ["decades", "years", "months", "days"].indexOf(view) < 0){
view = this.con.viewDays? "days": this.con.viewMonths? "months":
this.con.viewYears? "years": this.con.viewDecades? "decades": false;
}
if(!view || !this.con["view" + first(view)] || !this.con.dateFormat){ return false; }
// Render View
var content = d.createElement("DIV");
content.className = "calendar-datepicker calendar-view-" + view;
content.innerHTML = this["view" + first(view)]();
// Append Element
if(dt.querySelector(".calendar-datepicker")){
dt.replaceChild(content, dt.querySelector(".calendar-datepicker"));
} else {
dt.appendChild(content);
}
this.view.type = view;
return this.handleLabel(dt);
},
/*
| RENDER :: DAY VIEW
| @since 0.1.0
| @update 0.3.3
| RENDER :: TIME PICKER
| @since 0.4.0
*/
renderDay: function(){
var start = __("shorts").indexOf(this.con.weekStart),
week = __("shorts").slice(start);
week = week.concat(__("shorts").slice(0, start));
renderTimePicker: function(dt){
if(!this.con.timeFormat){ return false; }
var content = '<table class="calendar-day"><thead><tr>';
for(var i = 0; i < 7; i++){
content += '<th data-tail-day="' + __("shorts").indexOf(week[i]) + '">' + week[i] + '</th>';
// Render View
var div = d.createElement("DIV"), inp;
div.className = "calendar-timepicker";
div.innerHTML = '<div class="timepicker-field timepicker-hours">'
+ '<input type="number" name="dt[h]" value="" min="00" max="23" step="1" />'
+ '<label>' + this.__["time"][0] + '</label>'
+ '</div>'
+ '<div class="timepicker-field timepicker-minutes">'
+ '<input type="number" name="dt[m]" value="" min="00" max="59" step="5" />'
+ '<label>' + this.__["time"][1] + '</label>'
+ '</div>'
+ '<div class="timepicker-field timepicker-seconds">'
+ '<input type="number" name="dt[s]" value="" min="00" max="59" step="5" />'
+ '<label>' + this.__["time"][2] + '</label>'
+ '</div>',
// Set Data
inp = div.querySelectorAll("input");
inp[0].value = this.view.date.getHours(),
inp[1].value = this.view.date.getMinutes();
inp[2].value = this.view.date.getSeconds();
// Append Element
if(dt.querySelector(".calendar-timepicker")){
dt.replaceChild(div, dt.querySelector(".calendar-timepicker"));
} else {
dt.appendChild(div);
}
content += "</tr></thead><tbody>";
content += this.createCalendar(this.view.date.getMonth(), this.view.date.getFullYear()).render();
content += "</tbody></table>";
return content;
return this.handleLabel(dt);
},
/*
| RENDER :: MONTH VIEW
| @since 0.1.0
| @update 0.3.3
| VIEW :: HANDLE LABEL
| @since 0.4.0
*/
renderMonth: function(){
var strings = __("months");
var content = '<table class="calendar-month"><thead><tr><th colspan="4">' + __("header", 0) + '</th></tr></thead><tbody>';
for(var i = 0; i < 12; i++){
content += '<tr>';
content += '<td class="calendar-month" data-tail-month="0"><span>' + strings[i++] + '</span></td>';
content += '<td class="calendar-month" data-tail-month="1"><span>' + strings[i++] + '</span></td>';
content += '<td class="calendar-month" data-tail-month="2"><span>' + strings[i] + '</span></td>';
content += '</tr>';
handleLabel: function(dt){
var label = dt.querySelector(".label"), text, year;
switch(this.view.type){
case "days":
text = this.__["months"][this.view.date.getMonth()] + ", " + this.view.date.getFullYear(); break;
case "months":
text = this.view.date.getFullYear(); break;
case "years":
year = parseInt((this.view.date.getFullYear()).toString().slice(0, 3) + "0");
text = year + " - " + (year+10); break;
case "decades":
year = parseInt((this.view.date.getFullYear()).toString().slice(0, 2) + "00");
text = year + " - " + (year+100); break;
}
content += "</tbody></table>";
return content;
label.innerText = text;
return dt;
},
/*
| RENDER :: TIME VIEW
| @since 0.1.0
| @update 0.3.3
| VIEW :: SHOW DECADEs
| @since 0.4.0
*/
renderTime: function(){
return '' +
'<div class="calendar-field calendar-field-h">' +
' <input type="number" value="' + new Date().getHours() + '" min="00" max="23" step="1" />' +
' <label>' + __("time", 0) + '</label>' +
'</div>' +
'<div class="calendar-field calendar-field-m">' +
' <input type="number" value="' + new Date().getMinutes() + '" min="00" max="59" step="1" />' +
' <label>' + __("time", 1) + '</label>' +
'</div>' +
'<div class="calendar-field calendar-field-s">' +
' <input type="number" value="' + new Date().getSeconds() + '" min="00" max="59" step="1" />' +
' <label>' + __("time", 2) + '</label>' +
'</div>';
viewDecades: function(){
var year = this.view.date.getFullYear(),
date = new Date(this.view.date.getTime()),
today = this.con.today? (new Date()).getYear(): 0;
date.setFullYear(year-parseInt(year.toString()[3])-30);
for(var c, a, t = [], r = [], i = 1; i <= 16; i++){
c = 'calendar-decade' + (today >= date.getYear() && today <= (date.getYear()+10)? ' date-today': '');
a = 'data-action="view" data-view="down" data-year="' + date.getFullYear() + '"';
t.push('<td class="' + c + '" ' + a + '><span class="inner">' + date.getFullYear() + " - " + (date.getFullYear()+10) + '</span></td>');
if(i >= 4 && i%4 == 0){
r.push("<tr>\n" + t.join("\n") + "\n</tr>"); t = [];
}
date.setFullYear(date.getFullYear() + 10);
}
return '<table class="calendar-decades">'
+ '<thead><tr><th colspan="4">' + this.__["header"][2] + '</th></tr></thead>'
+ '<tbody>' + r.join("\n") + '</tbody></table>';
},
/*
| ACTION :: ADD EVENT LISTENER
| @since 0.3.0
| VIEW :: SHOW YEARs
| @since 0.4.0
*/
on: function(event, func){
this.dt.addEventListener(event, func);
viewYears: function(){
var year = this.view.date.getFullYear(),
date = new Date(this.view.date.getTime()),
today = this.con.today? (new Date()).getYear(): 0;
date.setFullYear(year-parseInt(year.toString()[3])-2);
for(var c, a, t = [], r = [], i = 1; i <= 16; i++){
c = 'calendar-year' + ((date.getYear() == today)? ' date-today': '');
a = 'data-action="view" data-view="down" data-year="' + date.getFullYear() + '"';
t.push('<td class="' + c + '" ' + a + '><span class="inner">' + date.getFullYear() + '</span></td>');
if(i >= 4 && i%4 == 0){
r.push("<tr>\n" + t.join("\n") + "\n</tr>"); t = [];
}
date.setFullYear(date.getFullYear() + 1);
}
return '<table class="calendar-years">'
+ '<thead><tr><th colspan="4">' + this.__["header"][1] + '</th></tr></thead>'
+ '<tbody>' + r.join("\n") + '</tbody></table>';
},
/*
| ACTION :: OPEN CALENDAR
| @since 0.1.0
| @update 0.3.4
| VIEW :: SHOW MONTHs
| @since 0.4.0
*/
open: function(){
if(!tail.hasClass(this.dt, "calendar-close")){
return this;
viewMonths: function(){
var strings = this.__["months"], today = this.con.today? (new Date()).getMonth(): -1;
today = (this.view.date.getYear() == (new Date()).getYear())? today: -1;
for(var c, a, t = [], r = [], i = 0; i < 12; i++){
c = 'calendar-month' + ((today == i)? ' date-today': '');
a = 'data-action="view" data-view="down" data-month="' + i + '"';
t.push('<td class="' + c + '" ' + a + '><span class="inner">' + strings[i] + '</span></td>');
if(t.length == 3){
r.push("<tr>\n" + t.join("\n") + "\n</tr>"); t = [];
}
}
tail.removeClass(this.dt, "calendar-close");
tail.addClass(this.dt, "calendar-idle");
return '<table class="calendar-months">'
+ '<thead><tr><th colspan="3">' + this.__["header"][0] + '</th></tr></thead>'
+ '<tbody>' + r.join("\n") + '</tbody></table>';
},
this.dt.style.opacity = 0;
this.dt.style.display = "block";
this.calcPosition();
(function(self){
self.animate = setInterval(function(){
self.dt.style.opacity = parseFloat(self.dt.style.opacity) + 0.1;
if(parseFloat(self.dt.style.opacity) >= 1){
tail.removeClass(self.dt, "calendar-idle");
tail.addClass(self.dt, "calendar-open");
tail.trigger(self.dt, "tail.DateTime::open", {
bubbles: false,
cancelable: true,
detail: self
});
clearInterval(self.animate);
}
}, 10);
})(this);
return this;
/*
| VIEW :: SHOW DAYs
| @since 0.4.0
*/
viewDays: function(){
var date = new Date(this.view.date.getTime()), time,
today = new Date().toDateString(),
month = date.getMonth(), c, a, t = [], r = [], i,
disabled = [0, []], check, ranges = [].concat(this.con.dateRanges),
tooltips = [].concat(this.con.tooltips), tooltip = [0, 0];
// Reset Date
date.setHours(0, 0, 0, 0);
date.setDate(1);
date.setDate((1 - (date.getDay() - this.con.weekStart)));
// Create Table
while(r.length < 6){
time = date.getTime();
// Attributes and ClassNames
a = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
a = 'data-action="submit" data-date="' + a + '"';
c = 'calendar-day date-' + ((date.getMonth() > month)? 'next':
(date.getMonth() < month)? 'previous': 'current');
if(this.con.today && today == date.toDateString()){
c += ' date-today';
}
// Calc Disabled
if(this.con.dateBlacklist && ((time) < this.con.dateStart || time > this.con.dateEnd)){
disabled = [(time < this.con.dateStart)? this.con.dateStart: Infinity, [0, 1, 2, 3, 4, 5, 6], true];
} else if(disabled[0] == 0){
ranges = ranges.filter(function(obj){
if(obj.start == Infinity || (time >= obj.start && time <= obj.end)){
disabled = [obj.end, obj.days];
return false;
}
return obj.start > time;
}, this);
} else if(disabled.length == 3){
disabled = [0, [0, 1, 2, 3, 4, 5, 6]];
}
// Calc Tooltips
if(this.con.tooltips.length > 0){
tooltips = this.con.tooltips.filter(function(obj, index){
if(obj.date instanceof Array){
if(obj.date[0] <= time && obj.date[1] >= time){
tooltip = [obj.date[1], index, obj.color];
}
} else if(obj.date == time){
tooltip = [obj.date, index, obj.color]
}
}, this);
}
if(tooltip[0] < time){
tooltip = [0, 0];
}
// Disabled
check = disabled[0] >= time && disabled[1].indexOf(date.getDay()) >= 0;
if((check && this.con.dateBlacklist) || (!check && !this.con.dateBlacklist)){
c += ' date-disabled';
a += ' data-disabled="true"';
} else if(disabled[0] !== 0 && disabled[0] <= time){
disabled = [0, []];
}
// Curent
if(this.select && this.select.toDateString() == date.toDateString()){
c += ' date-select';
}
// Create Calendar Item
i = '<span class="inner">' + date.getDate() + '</span>';
if(tooltip[0] > 0){
c += ' date-tooltip';
a += ' data-tooltip="' + tooltip[1] + '" data-tooltip-time="' + time + '"';
i += '<span class="tooltip-tick" style="background:' + tooltip[2] + ';"></span>';
}
t.push('<td class="' + c + '" ' + a + '>' + i + '</td>')
// Next
if(t.length == 7){
r.push("<tr>\n" + t.join("\n") + "\n</tr>"); t = [];
}
date.setDate(date.getDate()+1);
}
r = "<tbody>" + r.join("\n") + "</tbody>";
// Create Table Header
return '<table class="calendar-days">' + this.weekdays + r + '</table>';
},
/*
| ACTION :: CLOSE CALENDAR
| @since 0.1.0
| @update 0.3.4
| VIEW :: SHOW TOOLTIP
| @since 0.4.0
*/
close: function(){
if(!tail.hasClass(this.dt, "calendar-open")){
return this;
showTooltip: function(id, field, time){
var t = this.con.tooltips[id].element, e = t.style, w, h,
d = this.dt.querySelector(".calendar-datepicker");
// Calc Tooltip Rect
e.cssText = "opacity:0;visibility:hidden;";
t.id = "tooltip-" + id + "-" + time;
d.appendChild(t);
w = t.offsetWidth; h = t.offsetHeight;
// Set Tooltip Rect
e.top = field.offsetTop + field.offsetHeight + "px";
e.left = (field.offsetLeft + (field.offsetWidth/2)) - (w/2) + "px"
e.visibility = "visible";
// Animate Tooltip
if(this.con.animate){
t.setAttribute("data-top", parseInt(e.top));
e.top = (parseInt(e.top) + 5) + "px";
(function fade(){
if(parseFloat(e.top) > t.getAttribute("data-top")){
e.top = (parseFloat(e.top) - 0.5) + "px";
}
if((e.opacity = parseFloat(e.opacity)+0.125) < 1){
setTimeout(fade, 20);
}
})();
} else {
e.opacity = 1;
}
tail.removeClass(this.dt, "calendar-open");
tail.addClass(this.dt, "calendar-idle");
(function(self){
self.animate = setInterval(function(){
self.dt.style.opacity = parseFloat(self.dt.style.opacity) - 0.1;
if(parseFloat(self.dt.style.opacity) <= 0){
tail.removeClass(self.dt, "calendar-idle");
tail.addClass(self.dt, "calendar-close");
tail.trigger(self.dt, "tail.DateTime::close", {
bubbles: false,
cancelable: true,
detail: self
});
self.dt.style.display = "none";
clearInterval(self.animate);
}
}, 10);
})(this);
return this;
},
/*
| ACTION :: CLOSE CALENDAR
| @since 0.1.0
| @update 0.3.0
| VIEW :: HIDE TOOLTIP
| @since 0.4.0
*/
toggle: function(){
if(tail.hasClass(this.dt, "calendar-open")){
return this.close();
} else if(tail.hasClass(this.dt, "calendar-close")){
return this.open();
hideTooltip: function(id){
var t = this.dt.querySelector("#tooltip-" + id), e = t.style;
// Animate Tooltip
if(this.con.animate){
t.className += " remove";
(function fade(){
if(parseFloat(e.top) < (parseInt(t.getAttribute("data-top"))+5)){
e.top = (parseFloat(e.top) + 0.5) + "px";
}
if((e.opacity -= 0.125) < 0){
return (t.className = "calendar-tooltip")? t.parentElement.removeChild(t): "";
}
setTimeout(fade, 20);
})();
} else {
t.parentElement.removeChild(t);
}
return this;
},
/*
| ACTION :: REMOVE CALENDAR
| @since 0.3.0
| PUBLIC :: SWITCH VIEW
| @since 0.1.0
| @update 0.4.0
*/
remove: function(){
this.e.removeAttribute("data-tail-calendar");
this.e.removeAttribute("data-tail-value");
this.dt.parentElement.removeChild(this.dt);
return null;
switchView: function(view){
var order = [null, "days", "months", "years", "decades", null];
if(order.indexOf(view) == -1){
if(view == "up"){
view = order[(order.indexOf(this.view.type) || 5)+1] || null;
} else if(view == "down"){
view = order[(order.indexOf(this.view.type) || 1)-1] || null;
}
if(!(view && this.con["view" + first(view)])){
view = false;
}
}
return (!view)? false: !!this.renderDatePicker(this.dt, view);
},
/*
| ACTION :: REMOVE CALENDAR
| @since 0.3.3
| PUBLIC :: SWITCH DATE
| @since 0.4.0
*/
reload: function(){
this.remove();
return new tailDateTime(this.e, this.con);
switchDate: function(year, month, day, none){
this.view.date.setFullYear(year || this.view.date.getFullYear());
this.view.date.setMonth(month || this.view.date.getMonth());
if(day == "auto"){
var test = this.view.date, now = new Date();
if(test.getMonth() == now.getMonth() && test.getYear() == now.getYear()){
day = now.getDate();
} else {
day = 1;
}
}
this.view.date.setDate(day || this.view.date.getDate());
return (none === true)? true: this.switchView(this.view.type);
},
/*
| ACTION :: SWITCH MONTH
| PUBLIC :: SWITCH MONTH
| @since 0.1.0
| @update 0.1.2
| @update 0.4.0 - Alias for `.switchDate()`
*/
switchMonth: function(month, year){
if(month == "prev"){
this.view.date.setMonth(this.view.date.getMonth()-1)
} else if(month == "next"){
this.view.date.setMonth(this.view.date.getMonth()+1);
} else {
this.view.date.setMonth(month);
this.view.date.setFullYear(year);
if(typeof(month) == "string"){
month = ["previous", "prev"].indexOf(month) >= 0? -1: 1;
month = this.view.date.getMonth() + type;
}
this.switchView("day");
return this;
return this.switchDate(year || this.getFullYear(), month);
},
/*
| ACTION :: SWITCH YEAR
| PUBLIC :: SWITCH YEAR
| @since 0.1.0
| @update 0.1.2
| @update 0.4.0 - Alias for `.switchDate()`
*/
switchYear: function(year){
if(year == "prev"){
this.view.date.setFullYear(this.view.date.getFullYear()-1);
} else if(year == "next"){
this.view.date.setFullYear(this.view.date.getFullYear()+1);
} else {
this.view.date.setFullYear(year);
if(typeof(year) == "string"){
year = ["previous", "prev"].indexOf(year) >= 0? -1: 1;
year = this.view.date.getFullYear() + type;
}
this.switchView("month");
return this;
return this.switchDate(year);
},
/*
| ACTION :: SELECT A DATE
| PUBLIC :: BROWSE VIEW
| @since 0.4.0 - Helper for `switchDate()`
*/
browseView: function(type){
type = (["previous", "prev"].indexOf(type) >= 0)? -1: 1;
switch(this.view.type){
case "days":
return this.switchDate(null, this.view.date.getMonth() + type, "auto");
case "months":
return this.switchDate(this.view.date.getFullYear() + type, null, "auto");
case "years":
return this.switchDate(this.view.date.getFullYear() + (type*10), null, "auto");
case "decades":
return this.switchDate(this.view.date.getFullYear() + (type*100), null, "auto");
}
return false;
},
/*
| PUBLIC :: FETCH DATE / DTIME
| @since 0.4.0
*/
fetchDate: function(date){
date = parse(date || false) || this.view.date;
var inp = this.dt.querySelectorAll("input[type=number]");
if(inp && inp.length == 3){
date.setHours(inp[0].value || 0, inp[1].value || 0, inp[2].value || 0, 0);
}
return date;
},
/*
| PUBLIC :: SELECT DATE / TIME
| @since 0.1.0
| @update 0.3.0
| @update 0.4.0
*/
selectDate: function(Y, M, D, h, i, s){
var n = new Date();
selectDate: function(Y, M, D, H, I, S){
var n = new Date(), f = [];
(this.con.dateFormat)? f.push(this.con.dateFormat): null;
(this.con.timeFormat)? f.push(this.con.timeFormat): null;
// Format
var f = [
(this.con.dateFormat)? this.con.dateFormat: "",
(this.con.timeFormat)? this.con.timeFormat: "",
].join(" ").trim();
// Date
this.select = new Date(
((Y)? Y: ((Y == undefined)? this.view.date.getFullYear(): n.getFullYear())),
((M)? M: ((M == undefined)? this.view.date.getMonth(): n.getMonth())),
((D)? D: ((D == undefined)? this.view.date.getDate(): n.getDate())),
((h)? h: ((h == undefined)? this.view.date.getHours(): 0)),
((i)? i: ((i == undefined)? this.view.date.getMinutes(): 0)),
((s)? s: ((s == undefined)? this.view.date.getSeconds(): 0))
// Set Value
this.select = (Y instanceof Date)? Y: new Date(
Y? Y: (Y == undefined)? this.view.date.getFullYear(): n.getFullYear(),
M? M: (M == undefined)? this.view.date.getMonth(): n.getMonth(),
D? D: (D == undefined)? this.view.date.getDate(): n.getDate(),
H? H: (H == undefined)? this.view.date.getHours(): 0,
I? I: (I == undefined)? this.view.date.getMinutes(): 0,
S? S: (S == undefined)? this.view.date.getSeconds(): 0
);
// Trigger
tail.trigger(this.dt, "tail.DateTime::select", {
bubbles: false,
cancelable: true,
detail: self
});
// Value
this.e.value = this.convertDate(this.select, f);
this.e.setAttribute("data-tail-value", this.convertDate(this.select, "YYYY-mm-dd HH:ii:ss"));
return this.switchView(this.view.type);
this.e.value = this.convertDate(this.select, f.join(" "));
this.e.setAttribute("data-value", this.select.getTime());
this.trigger("change");
return this.switchView("days");
},
selectTime: function(h, i, s){
return this.selectDate(false, false, false, h, i, s);
selectTime: function(H, I, S){
return this.selectDate(false, false, false, H, I, S);
},
/*
| ACTION :: SELECT CALENDAR
| PUBLIC :: OPEN CALENDAR
| @since 0.1.0
| @update 0.3.4
| @update 0.4.0
*/
createCalendar: function(month, year){
var day = 1, haveDays = true,
startDay = new Date(year, month, day).getDay(),
daysInMonths = [31, (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
calendar = [];
// Calc start Day
startDay = startDay-__("shorts").indexOf(this.con.weekStart);
if(startDay < 0){
startDay = 7 + startDay;
open: function(){
if(!cHAS(this.dt, "calendar-close")){
return this;
}
var self = this, e = this.dt.style;
// Cache
if(tailDateTime.cache[this.con.weekStart + "_" + year] && !tailDateTime.isIE11){
if(tailDateTime.cache[this.con.weekStart + "_" + year][month]){
return tailDateTime.cache[this.con.weekStart + "_" + year][month];
// Animate
e.opacity = this.con.animate? 0: 1; e.display = "block";
cADD(cREM(this.dt, "calendar-close"), "calender-idle");
cHAS(this.dt, "calendar-static")? null: this.calcPosition();
(function fade(){
if((e.opacity = parseFloat(e.opacity)+0.125) >= 1){
cADD(cREM(self.dt, "calendar-idle"), "calendar-open");
return self.trigger("open");
}
} else {
tailDateTime.cache[this.con.weekStart + "_" + year] = {};
setTimeout(fade, 20);
})();
return this;
},
/*
| PUBLIC :: CLOSE CALENDAR
| @since 0.1.0
| @update 0.4.0
*/
close: function(){
if(!cHAS(this.dt, "calendar-open")){
return this;
}
var self = this, e = this.dt.style;
// Calculate
var i = 0;
while(haveDays){
calendar[i] = [];
for(var j = 0; j < 7; j++){
if(i === 0){
if(j === startDay){
calendar[i][j] = '<span>' + day++ + '</span>';
startDay++;
}
} else if(day <= daysInMonths[month]){
calendar[i][j] = '<span>' + day++ + '</span>';
} else {
calendar[i][j] = "";
haveDays = false;
}
if(day > daysInMonths[month]){
haveDays = false;
}
// Animate
cADD(cREM(this.dt, "calendar-open"), "calender-idle");
e.opacity = this.con.animate? 1: 0; e.display = "block";
(function fade(){
if((e.opacity -= 0.125) <= 0){
cADD(cREM(self.dt, "calendar-idle"), "calendar-close");
e.display = "none";
return self.trigger("close");
}
i++;
}
setTimeout(fade, 20);
})();
return this;
},
// Render
for(var i = 0; i < calendar.length; i++){
calendar[i] = '<tr>\n<td class="calendar-day">' + calendar[i].join('</td>\n<td class="calendar-day">') + '</td>\n</tr>';
/*
| PUBLIC :: CLOSE CALENDAR
| @since 0.1.0
| @update 0.4.0
*/
toggle: function(){
if(cHAS(this.dt, "calendar-open")){
return this.close();
}
if(tail.IE){
var inner = "<table><tbdy>" + calendar.join("") + "</tbody></table>";
var render = d.createElement("div");
render.innerHTML = inner;
render = render.getElementsByTagName("table")[0];
} else {
var render = d.createElement("table");
render.className = "calendar-current";
render.innerHTML = calendar.join("");
}
return cHAS(this.dt, "calendar-close")? this.open(): this;
},
// Empty Fields
var empty = render.querySelectorAll("td:empty");
for(var i = 0; i < empty.length; ++i){
empty[i].className += " empty";
/*
| PUBLIC :: ADD EVENT LISTENER
| @since 0.3.0
| @update 0.4.0
*/
on: function(event, func, args){
if(["open", "close", "change"].indexOf(event) < 0 || typeof(func) != "function"){
return false;
}
// Today Field
if(month == new Date().getMonth() && year == new Date().getFullYear()){
var today = Array.prototype.slice.call(render.querySelectorAll("td"));
today.forEach(function(current, index, array){
if(current.innerText === new Date().getDate().toString()){
current.className += " today";
}
});
if(!(event in this.events)){
this.events[event] = [];
}
this.events[event].push({cb: func, args: (args instanceof Array)? args: []});
return this;
},
// Return
this.view.date.setMonth(month);
this.view.date.setFullYear(year);
this.view = tail.clone(this.view, {content: render});
tailDateTime.cache[this.con.weekStart + "_" + year][month] = this.view;
return tailDateTime.cache[this.con.weekStart + "_" + year][month];
/*
| PUBLIC :: REMOVE CALENDAR
| @since 0.3.0
| @update 0.4.0
*/
remove: function(){
this.e.removeAttribute("data-tail-datetime");
this.e.removeAttribute("data-value");
this.dt.parentElement.removeChild(this.dt);
return this;
},
/*
| CONVERT DATE
| @since 0.1.0
| @update 0.3.3
| PUBLIC :: REMOVE CALENDAR
| @since 0.3.3
| @update 0.4.0
*/
convertDate: function(inDate, format){
var dateObject = {
H: String("00" + inDate.getHours()).toString().slice(-2),
G: function(hours){
return (hours % 12)? hours % 12: 12;
}(inDate.getHours()),
A: inDate.getHours() >= 12? "PM": "AM",
a: inDate.getHours() >= 12? "pm": "am",
i: String("00" + inDate.getMinutes()).toString().slice(-2),
s: String("00" + inDate.getSeconds()).toString().slice(-2),
reload: function(){
this.remove();
return this.init();
},
Y: inDate.getFullYear(),
y: parseInt(inDate.getFullYear().toString().slice(2)),
m: String("00" + (inDate.getMonth() + 1)).toString().slice(-2),
M: __("months", [inDate.getMonth()]).slice(0, 3),
F: __("months", [inDate.getMonth()]),
d: String("00" + inDate.getDate()).toString().slice(-2),
D: __("days", [inDate.getDay()]),
l: __("shorts", [inDate.getDay()]).toLowerCase()
};
/*
| PUBLIC :: (G|S)ET OPOTION
| @since 0.4.0
*/
config: function(key, value, rebuild){
if(key instanceof Object){
for(var k in key){
this.config(k, key[k], false);
}
this.reload();
return this.con;
}
if(typeof(key) == "undefined"){
return this.con;
} else if(!(key in this.con)){
return false;
}
var regex = new RegExp("(H{1,2}|G{1,2}|i{1,2}|s{1,2}|Y{2,4}|y{2}|m{1,2}|d{1,2})", "g");
format = format.replace(regex, function(token){
var datePart = dateObject[token.slice(-1)].toString(),
tokenlen = token.length, zeroPad
if(tokenlen == 4 || tokenlen == 2){
return datePart.slice(-Math.abs(tokenlen));
}
if(tokenlen == 1 && datePart[0] == "0"){
return datePart.slice(-1)
}
return datePart;
});
format = format.replace(/(A|a|M|F|D|l)/g, function(token){
return dateObject[token];
});
return format;
// Set | Return
if(typeof(value) == "undefined"){
return this.con[key];
}
this.con[key] = value;
if(this.rebuild !== false){
this.reload();
}
return this;
}
}
// Assign to Window
if(typeof(w.tail) == "undefined"){
w.tail = {};
}
w.tail.DateTime = tailDateTime;
return w.tail.DateTime
})(this);
// Return
return tailDateTime;
}));

@@ -1,2 +0,2 @@

/* tail.DateTime 0.3.4 @ https://github.com/pytesNET/tail.DateTime */
!function(t){"use strict";var n=t,u=t.document,g={hasClass:function(t,e){return new RegExp("(|s+)"+e+"(s+|)").test(t.className)},addClass:function(t,e){return new RegExp("(|s+)"+e+"(s+|)").test(t.className)||(t.className=(t.className.trim()+" "+e.trim()).trim()),t},removeClass:function(t,e){var a=new RegExp("(|s+)("+e+")(s+|)");return a.test(t.className)&&(t.className=t.className.replace(a,"$1$3").trim()),t},trigger:function(t,e,a){if(CustomEvent&&CustomEvent.name){var s=new CustomEvent(e,a);return t.dispatchEvent(s)}return(s=u.createEvent("CustomEvent")).initCustomEvent(e,!!a.bubbles,!!a.cancelable,a.detail),t.dispatchEvent(s)},clone:function(t,e){e="object"==typeof e?e:{};var a=t.constructor();for(var s in t)e.hasOwnProperty(s)?a[s]=e[s]:t.hasOwnProperty(s)&&(a[s]=t[s]);return a}};g.IE=-1<n.navigator.userAgent.indexOf("MSIE")||-1<n.navigator.userAgent.indexOf("Edge");var v=function(t,e){if("string"==typeof t&&(t=u.querySelectorAll(t)),t instanceof NodeList||t instanceof HTMLCollection){if(0==t.length)return!1;for(var a=new Array,s=0;s<t.length;s++)a.push(new v(t[s],e));return 1==a.length?a[0]:a}if(void 0===this)return new v(t,e);if(!(t instanceof Element))return!1;if(t.hasAttribute("data-tail-calendar")&&v.instances[t.getAttribute("data-tail-calendar")])return v.instances[t.getAttribute("data-tail-calendar")];if(e.dateRanges&&0<e.dateRanges.length){var n;for(s=0;s<e.dateRanges.length;s++)"string"==typeof(n=e.dateRanges[s])[0]&&0<=p("shorts").indexOf(n[0])?(n[0]=p("shorts").indexOf(n[0]),n[1]=2<=n.length&&0<=p("shorts").indexOf(n[1])?p("shorts").indexOf(n[1]):6):("string"==typeof n[0]&&(n[0]=new Date(Date.parse(n[0])),2==n.length&&"string"==typeof n[1]?n[1]=new Date(Date.parse(n[1])):1==n.length&&(n[1]=new Date(n[0].getFullYear(),n[0].getMonth(),0))),n[0]instanceof Date&&!isNaN(n[0].getDate())||(n[0]=new Date),(n.length<2||!(n[1]instanceof Date)||isNaN(n[1].getDate()))&&(n[1]=new Date(n[0].getFullYear(),n[0].getMonth(),0)))}return this.e=t,e="object"==typeof e?e:{},Object.assign?this.con=Object.assign({},v.defaults,e):this.con=g.clone(v.defaults,e),this.init()};v.version="0.3.4",v.status="alpha",v.count=0,v.isIE11=!!n.MSInputMethodContext&&!!u.documentMode,v.cache={},v.instances={},v.defaults={static:null,position:"bottom",classNames:"",dateFormat:"YYYY-mm-dd",timeFormat:"HH:ii:ss",dateRanges:[],weekStart:"SUN",startOpen:!1,stayOpen:!1,zeroSeconds:!1},v.strings={months:["January","February","March","April","May","June","July","August","September","October","November","December"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shorts:["SUN","MON","TUE","WED","THU","FRI","SAT"],time:["Hours","Minutes","Seconds"],header:["Select a Month","Select a Year","Select a Time"]};var p=function(t,e){return t in n.tail.DateTime.strings&&(void 0!==e?n.tail.DateTime.strings[t][e]:n.tail.DateTime.strings[t])};v.prototype={e:null,dt:null,con:{},view:{},select:null,init:function(){if(this.dt)return this.dt;var t=u.querySelector(this.con.static);this.dt=u.createElement("DIV"),this.dt.id="data-tail-calendar-"+ ++v.count,this.dt.className="tail-datetime-calendar calendar-close"+(t?" calendar-static":""),this.con.stayOpen&&(this.dt.className+=" calendar-stay"),this.con.classNames&&(this.dt.className+=" "+(this.con.classNames instanceof Array?this.con.classNames.join(" "):this.con.classNames)),this.con.dateFormat?this.dt.innerHTML='<div class="calendar-navi"> <span data-tail-navi="prev" class="calendar-button button-prev"></span> <span data-tail-navi="switch" class="calendar-label"></span> <span data-tail-navi="next" class="calendar-button button-next"></span></div><div class="calendar-date"></div>'+(this.con.timeFormat?'<div class="calendar-time">'+this.renderTime()+"</div>":""):this.dt.innerHTML='<div class="calendar-navi"> <span data-tail-navi="check" class="calendar-button button-check"></span> <span data-tail-navi="switch" class="calendar-label">'+p("header",2)+'</span> <span data-tail-navi="close" class="calendar-button button-close"></span></div>'+(this.con.timeFormat?'<div class="calendar-time">'+this.renderTime()+"</div>":"");var e=new Date(Date.parse(this.e.getAttribute("data-tail-value")||this.e.value));this.view={type:"date",date:new Date,content:"",render:function(){return this.content.querySelector("tbody").innerHTML}},isNaN(e.getDate())||(this.select=e,this.con.zeroSeconds&&this.select.setSeconds(0),this.view.date=new Date(this.select.getTime())),this.con.timeFormat&&(this.dt.querySelector(".calendar-field-h > input").value=this.view.date.getHours(),this.dt.querySelector(".calendar-field-m > input").value=this.view.date.getMinutes(),this.dt.querySelector(".calendar-field-s > input").value=this.view.date.getSeconds()),this.switchMonth(this.view.date.getMonth(),this.view.date.getFullYear()),this.e.hasAttribute("data-tail-value")?this.selectDate():this.e.setAttribute("data-tail-value",this.convertDate(this.view.date,"YYYY-mm-dd HH:ii:ss")),this.dt.style.top=0,this.dt.style.left=0,this.dt.style.zIndex=99,this.dt.style.position=t?"static":"absolute",this.dt.style.visibility=t?"visible":"hidden",t?t.appendChild(this.dt):u.getElementsByTagName("body")[0].appendChild(this.dt);var s=this,a=this.dt.querySelectorAll("[data-tail-navi]");if(0<a.length)for(var n=0;n<a.length;n++)a[n].addEventListener("click",function(t){var e=this.getAttribute("data-tail-navi");s.con.dateFormat?"month"==s.view.type?"prev"==e||"next"==e?s.switchYear.call(s,e):s.switchView.call(s,"day"):"prev"==e||"next"==e?s.switchMonth.call(s,e):s.switchView.call(s,"month"):s.con.timeFormat&&("check"==e&&s.selectTime.call(s,parseInt(s.dt.querySelector(".calendar-field-h > input").value),parseInt(s.dt.querySelector(".calendar-field-m > input").value),parseInt(s.dt.querySelector(".calendar-field-s > input").value)),s.con.stayOpen||s.close.call(s))});return this.e.addEventListener("focusin",function(t){s.open.call(s)}),this.e.addEventListener("focusout",function(t){var e=new Date(Date.parse(this.value));isNaN(e.getDate())||(s.selectDate.call(s,e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds()),s.switchMonth.call(s,e.getMonth(),e.getFullYear()))}),this.e.addEventListener("keyup",function(t){if(13==t.keyCode){var e=new Date(Date.parse(this.value));isNaN(e.getDate())||(s.selectDate.call(s,e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds()),s.switchMonth.call(s,e.getMonth(),e.getFullYear())),t.stopPropagation()}}),u.addEventListener("keyup",function(t){if(g.hasClass(s.dt,"calendar-open")&&27==t.keyCode&&(s.con.stayOpen||s.close.call(s),s.e.blur()),g.hasClass(s.dt,"calendar-open")&&13==t.keyCode){if(s.con.dateFormat){var e=s.dt.children[1].querySelector("td.today")||s.dt.children[1].querySelector("td:not(.empty)"),a=!!s.con.timeFormat;g.hasClass(e,"disabled")||s.selectDate.call(s,s.view.year,s.view.month,parseInt(e.value),a?parseInt(s.dt.querySelector(".calendar-field-h > input").value):0,a?parseInt(s.dt.querySelector(".calendar-field-m > input").value):0,a?parseInt(s.dt.querySelector(".calendar-field-s > input").value):0)}else s.selectTime.call(s,parseInt(s.dt.querySelector(".calendar-field-h > input").value),parseInt(s.dt.querySelector(".calendar-field-m > input").value),parseInt(s.dt.querySelector(".calendar-field-s > input").value));s.con.stayOpen||s.close.call(s),s.e.blur()}}),u.addEventListener("click",function(t){g.hasClass(s.dt,"calendar-open")&&(s.dt.contains(t.target)||s.e.contains(t.target)||t.target!=s.dt&&t.target!=s.e&&(s.con.stayOpen||s.close.call(s)))}),this.e.setAttribute("data-tail-calendar","tail-"+v.count),this.con.startOpen&&this.open(),v.instances["tail-"+v.count]=this},calcPosition:function(){if(g.hasClass(this.dt,"calendar-static"))return this;var t=n.getComputedStyle(this.dt),e=parseInt(t.marginLeft)+parseInt(t.marginRight),a=parseInt(t.marginTop)+parseInt(t.marginBottom),s=function(t){for(var e={top:t.offsetTop||0,left:t.offsetLeft||0,width:t.offsetWidth||0,height:t.offsetHeight||0};t=t.offsetParent;)e.top+=t.offsetTop,e.left+=t.offsetLeft;return e}(this.e);switch(this.dt.style.visibility="hidden",this.con.position){case"top":this.dt.style.top=s.top-(this.dt.offsetHeight+a)+"px",this.dt.style.left=s.left+s.width/2-(this.dt.offsetWidth/2+e/2)+"px";break;case"left":this.dt.style.top=s.top+s.height/2-(this.dt.offsetHeight/2+a)+"px",this.dt.style.left=s.left-(this.dt.offsetWidth+e)+"px";break;case"right":this.dt.style.top=s.top+s.height/2-(this.dt.offsetHeight/2+a)+"px",this.dt.style.left=s.left+s.width+"px";break;default:this.dt.style.top=s.top+s.height+"px",this.dt.style.left=s.left+s.width/2-(this.dt.offsetWidth/2+e/2)+"px"}return this.dt.style.visibility="visible",this},switchView:function(t){if(!this.con.dateFormat)return!1;if("month"==(this.view.type=t))this.dt.children[1].innerHTML="",this.dt.children[1].insertAdjacentHTML("afterbegin",this.renderMonth()),this.dt.querySelector(".calendar-label").innerText=this.view.date.getFullYear();else{this.dt.children[1].innerHTML=this.renderDay(),this.dt.querySelector(".calendar-label").innerText=p("months",this.view.date.getMonth())+" "+this.view.date.getFullYear();var e=this.con.dateRanges,a=this.view.date,s=this.dt.querySelectorAll("tbody td:not(.empty)"),n=new Date(a.getFullYear(),a.getMonth(),a.getDate(),0,0,0);if(0<e.length){for(var i=[],l=0;l<e.length;l++)if(e[l][0]instanceof Date){if(a.getYear()>=e[l][0].getYear()&&a.getYear()<=e[l][1].getYear()&&a.getMonth()>=e[l][0].getMonth()&&a.getMonth()<=e[l][1].getMonth())for(var r=0;r<s.length;r++)n.setDate(parseInt(s[r].innerText)),n>=e[l][0]&&n<=e[l][1]&&i.push(s[r].innerText)}else for(r=0;r<s.length;r++)n.setDate(parseInt(s[r].innerText)),3==e[l].length&&1==e[l][3]&&n.getDay()>=e[l][0]&&n.getDay()<=e[l][1]&&-1==i.indexOf(s[r].innerText)&&i.push(s[r].innerText),(n.getDay()<e[l][0]||n.getDay()>e[l][1])&&0<=i.indexOf(s[r].innerText)&&i.splice(i.indexOf(s[r].innerText),1);for(r=0;r<s.length;r++)-1==i.indexOf(s[r].innerText)&&g.addClass(s[r],"disable")}this.select instanceof Date&&this.select.getYear()==this.view.date.getYear()&&this.select.getMonth()==this.view.date.getMonth()?g.addClass(this.dt.querySelectorAll("tbody td:not(.empty)")[this.select.getDate()-1],"current"):this.dt.querySelector("tbody td.current")&&g.removeClass(this.dt.querySelector("tbody td.current"),"current")}var d=this;if(this.con.dateFormat){var o=this.dt.querySelectorAll("tbody td:not(.empty)");for(l=0;l<o.length;l++)o[l].addEventListener("click",function(t){if(t.preventDefault(),t.stopPropagation(),g.hasClass(this,"disable"))return!1;var e=!!d.con.timeFormat;"month"==d.view.type?d.switchMonth.call(d,parseInt(this.getAttribute("data-tail-month")),d.view.date.getFullYear()):(d.selectDate.call(d,d.view.date.getFullYear(),d.view.date.getMonth(),parseInt(this.innerText),e?parseInt(d.dt.querySelector(".calendar-field-h > input").value):0,e?parseInt(d.dt.querySelector(".calendar-field-m > input").value):0,e?parseInt(d.dt.querySelector(".calendar-field-s > input").value):0),d.con.stayOpen||d.close.call(d))})}},renderDay:function(){var t=p("shorts").indexOf(this.con.weekStart),e=p("shorts").slice(t);e=e.concat(p("shorts").slice(0,t));for(var a='<table class="calendar-day"><thead><tr>',s=0;s<7;s++)a+='<th data-tail-day="'+p("shorts").indexOf(e[s])+'">'+e[s]+"</th>";return a+="</tr></thead><tbody>",a+=this.createCalendar(this.view.date.getMonth(),this.view.date.getFullYear()).render(),a+="</tbody></table>"},renderMonth:function(){for(var t=p("months"),e='<table class="calendar-month"><thead><tr><th colspan="4">'+p("header",0)+"</th></tr></thead><tbody>",a=0;a<12;a++)e+="<tr>",e+='<td class="calendar-month" data-tail-month="0"><span>'+t[a++]+"</span></td>",e+='<td class="calendar-month" data-tail-month="1"><span>'+t[a++]+"</span></td>",e+='<td class="calendar-month" data-tail-month="2"><span>'+t[a]+"</span></td>",e+="</tr>";return e+="</tbody></table>"},renderTime:function(){return'<div class="calendar-field calendar-field-h"> <input type="number" value="'+(new Date).getHours()+'" min="00" max="23" step="1" /> <label>'+p("time",0)+'</label></div><div class="calendar-field calendar-field-m"> <input type="number" value="'+(new Date).getMinutes()+'" min="00" max="59" step="1" /> <label>'+p("time",1)+'</label></div><div class="calendar-field calendar-field-s"> <input type="number" value="'+(new Date).getSeconds()+'" min="00" max="59" step="1" /> <label>'+p("time",2)+"</label></div>"},on:function(t,e){this.dt.addEventListener(t,e)},open:function(){return g.hasClass(this.dt,"calendar-close")&&(g.removeClass(this.dt,"calendar-close"),g.addClass(this.dt,"calendar-idle"),this.dt.style.opacity=0,this.dt.style.display="block",this.calcPosition(),(t=this).animate=setInterval(function(){t.dt.style.opacity=parseFloat(t.dt.style.opacity)+.1,1<=parseFloat(t.dt.style.opacity)&&(g.removeClass(t.dt,"calendar-idle"),g.addClass(t.dt,"calendar-open"),g.trigger(t.dt,"tail.DateTime::open",{bubbles:!1,cancelable:!0,detail:t}),clearInterval(t.animate))},10)),this;var t},close:function(){return g.hasClass(this.dt,"calendar-open")&&(g.removeClass(this.dt,"calendar-open"),g.addClass(this.dt,"calendar-idle"),(t=this).animate=setInterval(function(){t.dt.style.opacity=parseFloat(t.dt.style.opacity)-.1,parseFloat(t.dt.style.opacity)<=0&&(g.removeClass(t.dt,"calendar-idle"),g.addClass(t.dt,"calendar-close"),g.trigger(t.dt,"tail.DateTime::close",{bubbles:!1,cancelable:!0,detail:t}),t.dt.style.display="none",clearInterval(t.animate))},10)),this;var t},toggle:function(){return g.hasClass(this.dt,"calendar-open")?this.close():g.hasClass(this.dt,"calendar-close")?this.open():this},remove:function(){return this.e.removeAttribute("data-tail-calendar"),this.e.removeAttribute("data-tail-value"),this.dt.parentElement.removeChild(this.dt),null},reload:function(){return this.remove(),new v(this.e,this.con)},switchMonth:function(t,e){return"prev"==t?this.view.date.setMonth(this.view.date.getMonth()-1):"next"==t?this.view.date.setMonth(this.view.date.getMonth()+1):(this.view.date.setMonth(t),this.view.date.setFullYear(e)),this.switchView("day"),this},switchYear:function(t){return"prev"==t?this.view.date.setFullYear(this.view.date.getFullYear()-1):"next"==t?this.view.date.setFullYear(this.view.date.getFullYear()+1):this.view.date.setFullYear(t),this.switchView("month"),this},selectDate:function(t,e,a,s,n,i){var l=new Date,r=[this.con.dateFormat?this.con.dateFormat:"",this.con.timeFormat?this.con.timeFormat:""].join(" ").trim();return this.select=new Date(t||(null==t?this.view.date.getFullYear():l.getFullYear()),e||(null==e?this.view.date.getMonth():l.getMonth()),a||(null==a?this.view.date.getDate():l.getDate()),s||(null==s?this.view.date.getHours():0),n||(null==n?this.view.date.getMinutes():0),i||(null==i?this.view.date.getSeconds():0)),g.trigger(this.dt,"tail.DateTime::select",{bubbles:!1,cancelable:!0,detail:self}),this.e.value=this.convertDate(this.select,r),this.e.setAttribute("data-tail-value",this.convertDate(this.select,"YYYY-mm-dd HH:ii:ss")),this.switchView(this.view.type)},selectTime:function(t,e,a){return this.selectDate(!1,!1,!1,t,e,a)},createCalendar:function(t,e){var a=1,s=!0,n=new Date(e,t,a).getDay(),i=[31,e%4==0&&e%100!=0||e%400==0?29:28,31,30,31,30,31,31,30,31,30,31],l=[];if((n-=p("shorts").indexOf(this.con.weekStart))<0&&(n=7+n),v.cache[this.con.weekStart+"_"+e]&&!v.isIE11){if(v.cache[this.con.weekStart+"_"+e][t])return v.cache[this.con.weekStart+"_"+e][t]}else v.cache[this.con.weekStart+"_"+e]={};for(var r=0;s;){l[r]=[];for(var d=0;d<7;d++)0===r?d===n&&(l[r][d]="<span>"+a+++"</span>",n++):a<=i[t]?l[r][d]="<span>"+a+++"</span>":(l[r][d]="",s=!1),i[t]<a&&(s=!1);r++}for(r=0;r<l.length;r++)l[r]='<tr>\n<td class="calendar-day">'+l[r].join('</td>\n<td class="calendar-day">')+"</td>\n</tr>";if(g.IE){var o="<table><tbdy>"+l.join("")+"</tbody></table>";(c=u.createElement("div")).innerHTML=o,c=c.getElementsByTagName("table")[0]}else{var c;(c=u.createElement("table")).className="calendar-current",c.innerHTML=l.join("")}var h=c.querySelectorAll("td:empty");for(r=0;r<h.length;++r)h[r].className+=" empty";t==(new Date).getMonth()&&e==(new Date).getFullYear()&&Array.prototype.slice.call(c.querySelectorAll("td")).forEach(function(t,e,a){t.innerText===(new Date).getDate().toString()&&(t.className+=" today")});return this.view.date.setMonth(t),this.view.date.setFullYear(e),this.view=g.clone(this.view,{content:c}),v.cache[this.con.weekStart+"_"+e][t]=this.view,v.cache[this.con.weekStart+"_"+e][t]},convertDate:function(t,e){var a,s={H:String("00"+t.getHours()).toString().slice(-2),G:(a=t.getHours(),a%12?a%12:12),A:12<=t.getHours()?"PM":"AM",a:12<=t.getHours()?"pm":"am",i:String("00"+t.getMinutes()).toString().slice(-2),s:String("00"+t.getSeconds()).toString().slice(-2),Y:t.getFullYear(),y:parseInt(t.getFullYear().toString().slice(2)),m:String("00"+(t.getMonth()+1)).toString().slice(-2),M:p("months",[t.getMonth()]).slice(0,3),F:p("months",[t.getMonth()]),d:String("00"+t.getDate()).toString().slice(-2),D:p("days",[t.getDay()]),l:p("shorts",[t.getDay()]).toLowerCase()},n=new RegExp("(H{1,2}|G{1,2}|i{1,2}|s{1,2}|Y{2,4}|y{2}|m{1,2}|d{1,2})","g");return e=(e=e.replace(n,function(t){var e=s[t.slice(-1)].toString(),a=t.length;return 4==a||2==a?e.slice(-Math.abs(a)):1==a&&"0"==e[0]?e.slice(-1):e})).replace(/(A|a|M|F|D|l)/g,function(t){return s[t]})}},void 0===n.tail&&(n.tail={}),n.tail.DateTime=v,n.tail.DateTime}(this);
/* tail.DateTime 0.4.0 @ https://github.com/pytesNET/tail.DateTime */
!function(t){"function"==typeof define&&define.amd?define(function(){return t(window)}):(void 0===window.tail&&(window.tail={}),window.tail.DateTime=t(window))}(function(t){"use strict";var n=t,c=t.document;function d(t,e){return new RegExp("\\b"+e+"\\b").test(t.className||"")}function a(t,e){return new RegExp("\\b"+e+"\\b").test(t.className||e)||(t.className+=" "+e),t}function s(t,e,i){return(i=new RegExp("\\b("+e+")\\b"))&&i.test(t.className||"")&&(t.className=t.className.replace(i,"")),t}function r(t,e,i){if(CustomEvent&&CustomEvent.name)var a=new CustomEvent(e,i);else(a=c.createEvent("CustomEvent")).initCustomEvent(e,!!i.bubbles,!!i.cancelable,i.detail);return t.dispatchEvent(a)}function o(t,e){if(Object.assign)return Object.assign({},t,e||{});var i=Object.constructor();for(var a in t)i[a]=a in e?e[a]:t[a];return i}function l(t){return t.charAt(0).toUpperCase()+t.slice(1)}function h(t,e,i){var a=t instanceof Date?t:!!t&&new Date(t);return a instanceof Date&&!isNaN(a.getDate())&&(i&&a.setHours(0,0,0,0),!0===e?a.getTime():a)}var u=function(t,e){if("string"==typeof t&&(t=c.querySelectorAll(t)),t instanceof NodeList||t instanceof HTMLCollection||t instanceof Array){for(var i=[],a=t.length,s=0;s<a;s++)i.push(new u(t[s],e));return 1===i.length?i[0]:0!==i.length&&i}if(!(t instanceof Element))return!1;if(!(this instanceof u))return new u(t,e);if(u.inst[t.getAttribute("data-tail-datetime")])return u.inst[t.getAttribute("data-tail-datetime")];if(t.getAttribute("data-datetime")){var n=JSON.parse(t.getAttribute("data-datetime").replace(/\'/g,'"'));n instanceof Object&&(e=o(e,n))}return this.e=t,this.id=++u.count,this.con=o(u.defaults,e),(u.inst["tail-"+this.id]=this).init()};return u.version="0.4.0",u.status="beta",u.count=0,u.inst={},u.defaults={animate:!0,classNames:!1,dateFormat:"YYYY-mm-dd",dateStart:!1,dateRanges:[],dateBlacklist:!0,dateEnd:!1,locale:"en",position:"bottom",startOpen:!1,stayOpen:!1,timeFormat:"HH:ii:ss",timeHours:null,timeMinutes:null,timeSeconds:0,today:!0,tooltips:[],viewDefault:"days",viewDecades:!0,viewYears:!0,viewMonths:!0,viewDays:!0,weekStart:0},u.strings={en:{months:["January","February","March","April","May","June","July","August","September","October","November","December"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shorts:["SUN","MON","TUE","WED","THU","FRI","SAT"],time:["Hours","Minutes","Seconds"],header:["Select a Month","Select a Year","Select a Decade","Select a Time"]}},u.strings.register=function(t,e){u.strings[t]=e},u.prototype={init:function(){var t,e=this;if(this.__=u.strings[this.con.locale]||u.strings.en,this.con.dateStart=h(this.con.dateStart,!0,!0)||0,this.con.dateEnd=h(this.con.dateEnd,!0,!0)||9999999999999,this.con.viewDefault=this.con.dateFormat?this.con.viewDefault:"time","string"==typeof this.con.weekStart&&(this.con.weekStart=u.strings.en.shorts.indexOf(this.con.weekStart)),this.con.weekStart<0&&6<this.con.weekStart&&(this.con.weekStart=0),0<this.con.dateRanges.length){for(var i=[],a=(l=this.con.dateRanges).length,s=0;s<a;s++)l[s]instanceof Object&&(l[s].start||l[s].days)&&(!1===(l[s].start=h(l[s].start||!1,!0,!0))?l[s].start=l[s].end=1/0:(!1===(l[s].end=h(l[s].end||!1,!0,!0))&&(l[s].end=l[s].start),l[s].start=l[s].start>l[s].end?[l[s].end,l[s].end=l[s].start][0]:l[s].start),l[s].days=!l[s].days||l[s].days,l[s].days="boolean"!=typeof days?function(t){for(var e=[],i=t.length,a=0;a<i;a++)"string"==typeof t[a]&&(t[a]=u.strings.en.shorts.indexOf(t[a])),0<=t[a]&&t[a]<=6&&e.push(t[a]);return e}(l[s].days instanceof Array?l[s].days:[l[s].days]):[0,1,2,3,4,5,6],i.push({start:l[s].start,end:l[s].end,days:l[s].days}));this.con.dateRanges=i}if(0<this.con.tooltips.length){i=[];var n,r=this.con.tooltips;for(a=r.length,s=0;s<a;s++)r[s]instanceof Object&&r[s].date&&(r[s].date instanceof Array?(n=h(r[s].date[0]||!1,!0,!0),l=h(r[s].date[0]||!1,!0,!0)||n):n=l=h(r[s].date||!1,!0,!0),n&&i.push({date:n!==l?[n,l]:n,text:r[s].text||"Tooltip",color:r[s].color||"#202428",element:r[s].element||(t=c.createElement("DIV"),t.className="calendar-tooltip",t.innerHTML='<div class="tooltip-inner">'+r[s].text||"Tooltip</div>",t)}));this.con.tooltips=i}var o=this.__.shorts.slice(this.con.weekStart).concat(this.__.shorts.slice(0,this.con.weekStart));this.weekdays="<thead>\n<tr>\n";for(s=0;s<7;s++)this.weekdays+='<th class="calendar-week">'+o[s]+"</th>";this.weekdays+="\n</tr>\n</thead>",this.select=h(this.e.getAttribute("data-value")||this.e.value),(!this.select||this.select<this.con.dateStart||this.select>this.con.dateEnd)&&(this.select=null),null==this.view&&(this.view={type:this.con.viewDefault,date:this.select||new Date});for(a=["Hours","Minutes","Seconds"],s=0;s<3;s++)"number"==typeof this.con["time"+a[s]]&&this.view.date["set"+a[s]](this.con["time"+a[s]]);if(this.events={},this.dt=this.renderCalendar(),null==this._bind){var l="addEventListener";this.e[l]("focusin",function(t){e.open.call(e)}),this.e[l]("keyup",function(t){e.bind.call(e,t)}),c[l]("keyup",function(t){e.bind.call(e,t)}),c[l]("click",function(t){e.dt.contains(t.target)?e.bind.call(e,t):!e.e.contains(t.target)&&d(e.dt,"calendar-open")&&(t.target==e.dt||t.target==e.e||e.con.stayOpen||e.close.call(e))}),c[l]("mouseover",function(t){e.dt.contains(t.target)&&e.bind.call(e,t)}),this._bind=!0}return this.e.setAttribute("data-tail-datetime","tail-"+this.id),this.con.startOpen&&this.open(),this.select&&this.selectDate(this.select),this},bind:function(t){var e,i=t.target,a="getAttribute",s="data-action",n=i[a](s)?i:i.parentElement[a](s)?i.parentElement:i,r="data-tooltip";if("mouseover"==t.type&&(!1!==(e=i[a](r)?i:!!n[a](r)&&n)?this.dt.querySelector("#tooltip-"+e[a](r)+"-"+e[a](r+"-time"))||this.showTooltip(e[a](r),e,e[a](r+"-time")):this.dt.querySelector(".calendar-tooltip:not(.remove)")&&this.hideTooltip(this.dt.querySelector(".calendar-tooltip").id.slice(8))),"click"==t.type){if(!n||1!=t.buttons&&1!=(t.which||t.button))return;switch(n[a](s)){case"prev":return this.browseView("prev");case"next":return this.browseView("next");case"submit":return this.selectDate(this.fetchDate(n[a]("data-date")));case"cancel":this.con.stayOpen||this.close();break;case"view":return this.switchDate(n[a]("data-year")||null,n[a]("data-month")||null,n[a]("data-day")||null),this.switchView(n[a]("data-view"))}}if("keyup"==t.type){if(t.target!==this.e&&/calendar-(static|close)/i.test(this.dt.className))return!1;13==(t.keyCode||t.which)&&(this.selectDate(this.fetchDate()),t.stopPropagation(),this.con.stayOpen||this.close()),27==(t.keyCode||t.which)&&(this.con.stayOpen||this.close())}},trigger:function(t){var e={bubbles:!1,cancelable:!0,detail:{args:arguments,self:this}};"change"==t&&(r(this.e,"input",e),r(this.e,"change",e)),r(this.dt,"tail::"+t,e);for(var i=(this.events[t]||[]).length,a=0;a<i;a++)this.events[t][a].cb.apply(this,function(t,e,i){for(var a=e.length,s=0;s<a;++s)t[s-1]=e[s];return t[s]=i,t}(new Array(arguments.length),arguments,this.events[t][a].args))},calcPosition:function(){var t=this.dt.style,e=n.getComputedStyle(this.dt),i=parseInt(e.marginLeft)+parseInt(e.marginRight),a=parseInt(e.marginTop)+parseInt(e.marginBottom),s=function(t,e){for(e={top:t.offsetTop||0,left:t.offsetLeft||0,width:t.offsetWidth||0,height:t.offsetHeight||0};t=t.offsetParent;)e.top+=t.offsetTop,e.left+=t.offsetLeft;return e}(this.e,{});switch(t.visibility="hidden",this.con.position){case"top":t.top=s.top-(this.dt.offsetHeight+a)+"px",t.left=s.left+s.width/2-(this.dt.offsetWidth/2+i/2)+"px";break;case"left":t.top=s.top+s.height/2-(this.dt.offsetHeight/2+a)+"px",t.left=s.left-(this.dt.offsetWidth+i)+"px";break;case"right":t.top=s.top+s.height/2-(this.dt.offsetHeight/2+a)+"px",t.left=s.left+s.width+"px";break;case"bottom":t.top=s.top+s.height+"px",t.left=s.left+s.width/2-(this.dt.offsetWidth/2+i/2)+"px"}return t.visibility="visible",this},convertDate:function(t,e){var i,a={H:String("00"+t.getHours()).toString().slice(-2),G:(i=t.getHours(),i%12?i%12:12),A:12<=t.getHours()?"PM":"AM",a:12<=t.getHours()?"pm":"am",i:String("00"+t.getMinutes()).toString().slice(-2),s:String("00"+t.getSeconds()).toString().slice(-2),Y:t.getFullYear(),y:parseInt(t.getFullYear().toString().slice(2)),m:String("00"+(t.getMonth()+1)).toString().slice(-2),M:this.__.months[t.getMonth()].slice(0,3),F:this.__.months[t.getMonth()],d:String("00"+t.getDate()).toString().slice(-2),D:this.__.days[t.getDay()],l:this.__.shorts[t.getDay()].toLowerCase()};return e.replace(/([HGismd]{1,2}|[Y]{2,4}|y{2})/g,function(t){return 4==t.length||2==t.length?a[t.slice(-1)].toString().slice(-Math.abs(t.length)):1==t.length&&"0"==datePart[0]?a[t.slice(-1)].toString().slice(-1):a[t.slice(-1)].toString()}).replace(/(A|a|M|F|D|l)/g,function(t){return a[t]})},renderCalendar:function(){var t,e=["tail-datetime-calendar","calendar-close"],i=c.createElement("DIV"),a=!0===this.con.classNames?this.e.className:this.con.classNames;if(["top","left","right","bottom"].indexOf(this.con.position)<0&&(t=c.querySelector(this.con.position),e.push("calendar-static")),("string"==typeof a||a instanceof Array)&&(e=e.concat("string"==typeof a?a.split(" "):a)),this.con.stayOpen&&e.push("calendar-stay"),i.id="tail-datetime-"+this.id,i.className=e.join(" "),this.con.dateFormat)var s='<span class="action action-prev" data-action="prev"></span><span class="label" data-action="view" data-view="up"></span><span class="action action-next" data-action="next"></span>';else if(this.con.timeFormat)s='<span class="action action-submit" data-action="submit"></span><span class="label"></span><span class="action action-cancel" data-action="cancel"></span>';return void 0!==s&&(i.innerHTML='<div class="calendar-actions">'+s+"</div>"),this.con.dateFormat&&this.renderDatePicker(i,this.con.viewDefault),this.con.timeFormat&&this.renderTimePicker(i),i.style.cssText=t?"position:static;visibility:visible;":"top:0;left:0;z-index:999;position:absolute;visibility:hidden;",(t||document.body).appendChild(i),i},renderDatePicker:function(t,e){if((!e||["decades","years","months","days"].indexOf(e)<0)&&(e=this.con.viewDays?"days":this.con.viewMonths?"months":this.con.viewYears?"years":!!this.con.viewDecades&&"decades"),!e||!this.con["view"+l(e)]||!this.con.dateFormat)return!1;var i=c.createElement("DIV");return i.className="calendar-datepicker calendar-view-"+e,i.innerHTML=this["view"+l(e)](),t.querySelector(".calendar-datepicker")?t.replaceChild(i,t.querySelector(".calendar-datepicker")):t.appendChild(i),this.view.type=e,this.handleLabel(t)},renderTimePicker:function(t){if(!this.con.timeFormat)return!1;var e,i=c.createElement("DIV");return i.className="calendar-timepicker",i.innerHTML='<div class="timepicker-field timepicker-hours"><input type="number" name="dt[h]" value="" min="00" max="23" step="1" /><label>'+this.__.time[0]+'</label></div><div class="timepicker-field timepicker-minutes"><input type="number" name="dt[m]" value="" min="00" max="59" step="5" /><label>'+this.__.time[1]+'</label></div><div class="timepicker-field timepicker-seconds"><input type="number" name="dt[s]" value="" min="00" max="59" step="5" /><label>'+this.__.time[2]+"</label></div>",(e=i.querySelectorAll("input"))[0].value=this.view.date.getHours(),e[1].value=this.view.date.getMinutes(),e[2].value=this.view.date.getSeconds(),t.querySelector(".calendar-timepicker")?t.replaceChild(i,t.querySelector(".calendar-timepicker")):t.appendChild(i),this.handleLabel(t)},handleLabel:function(t){var e,i,a=t.querySelector(".label");switch(this.view.type){case"days":e=this.__.months[this.view.date.getMonth()]+", "+this.view.date.getFullYear();break;case"months":e=this.view.date.getFullYear();break;case"years":e=(i=parseInt(this.view.date.getFullYear().toString().slice(0,3)+"0"))+" - "+(i+10);break;case"decades":e=(i=parseInt(this.view.date.getFullYear().toString().slice(0,2)+"00"))+" - "+(i+100)}return a.innerText=e,t},viewDecades:function(){var t=this.view.date.getFullYear(),e=new Date(this.view.date.getTime()),i=this.con.today?(new Date).getYear():0;e.setFullYear(t-parseInt(t.toString()[3])-30);for(var a,s,n=[],r=[],o=1;o<=16;o++)a="calendar-decade"+(i>=e.getYear()&&i<=e.getYear()+10?" date-today":""),s='data-action="view" data-view="down" data-year="'+e.getFullYear()+'"',n.push('<td class="'+a+'" '+s+'><span class="inner">'+e.getFullYear()+" - "+(e.getFullYear()+10)+"</span></td>"),4<=o&&o%4==0&&(r.push("<tr>\n"+n.join("\n")+"\n</tr>"),n=[]),e.setFullYear(e.getFullYear()+10);return'<table class="calendar-decades"><thead><tr><th colspan="4">'+this.__.header[2]+"</th></tr></thead><tbody>"+r.join("\n")+"</tbody></table>"},viewYears:function(){var t=this.view.date.getFullYear(),e=new Date(this.view.date.getTime()),i=this.con.today?(new Date).getYear():0;e.setFullYear(t-parseInt(t.toString()[3])-2);for(var a,s,n=[],r=[],o=1;o<=16;o++)a="calendar-year"+(e.getYear()==i?" date-today":""),s='data-action="view" data-view="down" data-year="'+e.getFullYear()+'"',n.push('<td class="'+a+'" '+s+'><span class="inner">'+e.getFullYear()+"</span></td>"),4<=o&&o%4==0&&(r.push("<tr>\n"+n.join("\n")+"\n</tr>"),n=[]),e.setFullYear(e.getFullYear()+1);return'<table class="calendar-years"><thead><tr><th colspan="4">'+this.__.header[1]+"</th></tr></thead><tbody>"+r.join("\n")+"</tbody></table>"},viewMonths:function(){var t=this.__.months,e=this.con.today?(new Date).getMonth():-1;e=this.view.date.getYear()==(new Date).getYear()?e:-1;for(var i,a,s=[],n=[],r=0;r<12;r++)i="calendar-month"+(e==r?" date-today":""),a='data-action="view" data-view="down" data-month="'+r+'"',s.push('<td class="'+i+'" '+a+'><span class="inner">'+t[r]+"</span></td>"),3==s.length&&(n.push("<tr>\n"+s.join("\n")+"\n</tr>"),s=[]);return'<table class="calendar-months"><thead><tr><th colspan="3">'+this.__.header[0]+"</th></tr></thead><tbody>"+n.join("\n")+"</tbody></table>"},viewDays:function(){var i,t,e,a,s,n=new Date(this.view.date.getTime()),r=(new Date).toDateString(),o=n.getMonth(),l=[],c=[],d=[0,[]],h=[].concat(this.con.dateRanges),u=([].concat(this.con.tooltips),[0,0]);for(n.setHours(0,0,0,0),n.setDate(1),n.setDate(1-(n.getDay()-this.con.weekStart));c.length<6;)i=n.getTime(),e='data-action="submit" data-date="'+(e=n.getFullYear()+"-"+(n.getMonth()+1)+"-"+n.getDate())+'"',t="calendar-day date-"+(n.getMonth()>o?"next":n.getMonth()<o?"previous":"current"),this.con.today&&r==n.toDateString()&&(t+=" date-today"),this.con.dateBlacklist&&(i<this.con.dateStart||i>this.con.dateEnd)?d=[i<this.con.dateStart?this.con.dateStart:1/0,[0,1,2,3,4,5,6],!0]:0==d[0]?h=h.filter(function(t){return t.start==1/0||i>=t.start&&i<=t.end?!(d=[t.end,t.days]):t.start>i},this):3==d.length&&(d=[0,[0,1,2,3,4,5,6]]),0<this.con.tooltips.length&&this.con.tooltips.filter(function(t,e){t.date instanceof Array?t.date[0]<=i&&t.date[1]>=i&&(u=[t.date[1],e,t.color]):t.date==i&&(u=[t.date,e,t.color])},this),u[0]<i&&(u=[0,0]),(s=d[0]>=i&&0<=d[1].indexOf(n.getDay()))&&this.con.dateBlacklist||!s&&!this.con.dateBlacklist?(t+=" date-disabled",e+=' data-disabled="true"'):0!==d[0]&&d[0]<=i&&(d=[0,[]]),this.select&&this.select.toDateString()==n.toDateString()&&(t+=" date-select"),a='<span class="inner">'+n.getDate()+"</span>",0<u[0]&&(t+=" date-tooltip",e+=' data-tooltip="'+u[1]+'" data-tooltip-time="'+i+'"',a+='<span class="tooltip-tick" style="background:'+u[2]+';"></span>'),l.push('<td class="'+t+'" '+e+">"+a+"</td>"),7==l.length&&(c.push("<tr>\n"+l.join("\n")+"\n</tr>"),l=[]),n.setDate(n.getDate()+1);return c="<tbody>"+c.join("\n")+"</tbody>",'<table class="calendar-days">'+this.weekdays+c+"</table>"},showTooltip:function(t,e,i){var a,s=this.con.tooltips[t].element,n=s.style,r=this.dt.querySelector(".calendar-datepicker");n.cssText="opacity:0;visibility:hidden;",s.id="tooltip-"+t+"-"+i,r.appendChild(s),a=s.offsetWidth,s.offsetHeight,n.top=e.offsetTop+e.offsetHeight+"px",n.left=e.offsetLeft+e.offsetWidth/2-a/2+"px",n.visibility="visible",this.con.animate?(s.setAttribute("data-top",parseInt(n.top)),n.top=parseInt(n.top)+5+"px",function t(){parseFloat(n.top)>s.getAttribute("data-top")&&(n.top=parseFloat(n.top)-.5+"px"),(n.opacity=parseFloat(n.opacity)+.125)<1&&setTimeout(t,20)}()):n.opacity=1},hideTooltip:function(t){var e=this.dt.querySelector("#tooltip-"+t),i=e.style;this.con.animate?(e.className+=" remove",function t(){if(parseFloat(i.top)<parseInt(e.getAttribute("data-top"))+5&&(i.top=parseFloat(i.top)+.5+"px"),(i.opacity-=.125)<0)return(e.className="calendar-tooltip")?e.parentElement.removeChild(e):"";setTimeout(t,20)}()):e.parentElement.removeChild(e)},switchView:function(t){var e=[null,"days","months","years","decades",null];return-1==e.indexOf(t)&&("up"==t?t=e[(e.indexOf(this.view.type)||5)+1]||null:"down"==t&&(t=e[(e.indexOf(this.view.type)||1)-1]||null),t&&this.con["view"+l(t)]||(t=!1)),!!t&&!!this.renderDatePicker(this.dt,t)},switchDate:function(t,e,i,a){if(this.view.date.setFullYear(t||this.view.date.getFullYear()),this.view.date.setMonth(e||this.view.date.getMonth()),"auto"==i){var s=this.view.date,n=new Date;i=s.getMonth()==n.getMonth()&&s.getYear()==n.getYear()?n.getDate():1}return this.view.date.setDate(i||this.view.date.getDate()),!0===a||this.switchView(this.view.type)},switchMonth:function(t,e){return"string"==typeof t&&(t=0<=["previous","prev"].indexOf(t)?-1:1,t=this.view.date.getMonth()+type),this.switchDate(e||this.getFullYear(),t)},switchYear:function(t){return"string"==typeof t&&(t=0<=["previous","prev"].indexOf(t)?-1:1,t=this.view.date.getFullYear()+type),this.switchDate(t)},browseView:function(t){switch(t=0<=["previous","prev"].indexOf(t)?-1:1,this.view.type){case"days":return this.switchDate(null,this.view.date.getMonth()+t,"auto");case"months":return this.switchDate(this.view.date.getFullYear()+t,null,"auto");case"years":return this.switchDate(this.view.date.getFullYear()+10*t,null,"auto");case"decades":return this.switchDate(this.view.date.getFullYear()+100*t,null,"auto")}return!1},fetchDate:function(t){t=h(t||!1)||this.view.date;var e=this.dt.querySelectorAll("input[type=number]");return e&&3==e.length&&t.setHours(e[0].value||0,e[1].value||0,e[2].value||0,0),t},selectDate:function(t,e,i,a,s,n){var r=new Date,o=[];return this.con.dateFormat&&o.push(this.con.dateFormat),this.con.timeFormat&&o.push(this.con.timeFormat),this.select=t instanceof Date?t:new Date(t||(null==t?this.view.date.getFullYear():r.getFullYear()),e||(null==e?this.view.date.getMonth():r.getMonth()),i||(null==i?this.view.date.getDate():r.getDate()),a||(null==a?this.view.date.getHours():0),s||(null==s?this.view.date.getMinutes():0),n||(null==n?this.view.date.getSeconds():0)),this.e.value=this.convertDate(this.select,o.join(" ")),this.e.setAttribute("data-value",this.select.getTime()),this.trigger("change"),this.switchView("days")},selectTime:function(t,e,i){return this.selectDate(!1,!1,!1,t,e,i)},open:function(){if(!d(this.dt,"calendar-close"))return this;var e=this,i=this.dt.style;return i.opacity=this.con.animate?0:1,i.display="block",a(s(this.dt,"calendar-close"),"calender-idle"),!d(this.dt,"calendar-static")&&this.calcPosition(),function t(){if(1<=(i.opacity=parseFloat(i.opacity)+.125))return a(s(e.dt,"calendar-idle"),"calendar-open"),e.trigger("open");setTimeout(t,20)}(),this},close:function(){if(!d(this.dt,"calendar-open"))return this;var e=this,i=this.dt.style;return a(s(this.dt,"calendar-open"),"calender-idle"),i.opacity=this.con.animate?1:0,i.display="block",function t(){if((i.opacity-=.125)<=0)return a(s(e.dt,"calendar-idle"),"calendar-close"),i.display="none",e.trigger("close");setTimeout(t,20)}(),this},toggle:function(){return d(this.dt,"calendar-open")?this.close():d(this.dt,"calendar-close")?this.open():this},on:function(t,e,i){return!(["open","close","change"].indexOf(t)<0||"function"!=typeof e)&&(t in this.events||(this.events[t]=[]),this.events[t].push({cb:e,args:i instanceof Array?i:[]}),this)},remove:function(){return this.e.removeAttribute("data-tail-datetime"),this.e.removeAttribute("data-value"),this.dt.parentElement.removeChild(this.dt),this},reload:function(){return this.remove(),this.init()},config:function(t,e,i){if(t instanceof Object){for(var a in t)this.config(a,t[a],!1);return this.reload(),this.con}return void 0===t?this.con:t in this.con&&(void 0===e?this.con[t]:(this.con[t]=e,!1!==this.rebuild&&this.reload(),this))}},u});

@@ -1,3 +0,25 @@

;(function(w){
w.tail.DateTime.strings = {
/*
| tail.DateTime - A pure, vanilla JavaScript DateTime Picker
| @file ./langs/tail.datetime-de_AT.js
| @author SamBrishes <https://github.com/pytesNET/tail.DateTime/>
| @version 0.4.0 - Alpha
|
| @fork MrGuiseppe <https://github.com/MrGuiseppe/pureJSCalendar/>
| This script started as fork and is now completely independent!
|
| @license X11 / MIT License
| @copyright Copyright © 2018 - SamBrishes, pytesNET <pytes@gmx.net>
*/
;(function(factory){
if(typeof(define) == "function" && define.amd){
define(function(){
return function(datetime){ factory(datetime); };
});
} else {
if(typeof(window.tail) != "undefined" && window.tail.DateTime){
factory(window.tail.DateTime);
}
}
}(function(datetime){
datetime.strings.register("de_AT", {
months: ["Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],

@@ -7,4 +29,5 @@ days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],

time: ["Stunden", "Minuten", "Sekunden"],
header: ["Wähle einen Monat", "Wähle ein Jahr", "Wähle eine Uhrzeit"],
};
})(this);
header: ["Wähle einen Monat", "Wähle ein Jahr", "Wähle ein Jahrzehnt", "Wähle eine Uhrzeit"]
});
return datetime;
}));

@@ -1,3 +0,25 @@

;(function(w){
w.tail.DateTime.strings = {
/*
| tail.DateTime - A pure, vanilla JavaScript DateTime Picker
| @file ./langs/tail.datetime-de.js
| @author SamBrishes <https://github.com/pytesNET/tail.DateTime/>
| @version 0.4.0 - Alpha
|
| @fork MrGuiseppe <https://github.com/MrGuiseppe/pureJSCalendar/>
| This script started as fork and is now completely independent!
|
| @license X11 / MIT License
| @copyright Copyright © 2018 - SamBrishes, pytesNET <pytes@gmx.net>
*/
;(function(factory){
if(typeof(define) == "function" && define.amd){
define(function(){
return function(datetime){ factory(datetime); };
});
} else {
if(typeof(window.tail) != "undefined" && window.tail.DateTime){
factory(window.tail.DateTime);
}
}
}(function(datetime){
datetime.strings.register("de", {
months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],

@@ -7,4 +29,5 @@ days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],

time: ["Stunden", "Minuten", "Sekunden"],
header: ["Wähle einen Monat", "Wähle ein Jahr", "Wähle eine Uhrzeit"],
};
})(this);
header: ["Wähle einen Monat", "Wähle ein Jahr", "Wähle ein Jahrzehnt", "Wähle eine Uhrzeit"]
});
return datetime;
}));

@@ -1,3 +0,25 @@

;(function(w){
w.tail.DateTime.strings = {
/*
| tail.DateTime - A pure, vanilla JavaScript DateTime Picker
| @file ./langs/tail.datetime-es.js
| @author SamBrishes <https://github.com/pytesNET/tail.DateTime/>
| @version 0.4.0 - Alpha
|
| @fork MrGuiseppe <https://github.com/MrGuiseppe/pureJSCalendar/>
| This script started as fork and is now completely independent!
|
| @license X11 / MIT License
| @copyright Copyright © 2018 - SamBrishes, pytesNET <pytes@gmx.net>
*/
;(function(factory){
if(typeof(define) == "function" && define.amd){
define(function(){
return function(datetime){ factory(datetime); };
});
} else {
if(typeof(window.tail) != "undefined" && window.tail.DateTime){
factory(window.tail.DateTime);
}
}
}(function(datetime){
datetime.strings.register("es", {
months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],

@@ -7,4 +29,5 @@ days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],

time: ["Horas", "Minutos", "Segundos"],
header: ["Selecciona un mes", "Seleccione un año", "Seleccione una hora"],
};
})(this);
header: ["Selecciona un mes", "Seleccione un año", "Seleccione un década", "Seleccione una hora"]
});
return datetime;
}));
{
"name": "tail.datetime",
"version": "0.3.4",
"version": "0.4.0",
"description": "A light-weight, translat- and configurable Open Source DateTime Picker, written in pure vanilla JavaScript!",

@@ -12,3 +12,3 @@ "main": "js/tail.datetime.js",

"keywords": [
"datetime-picker", "datetime", "date", "time", "picker", "calendar", "form", "tail"
"datetime-picker", "datetime", "date", "time", "picker", "calendar", "tail"
],

@@ -15,0 +15,0 @@ "author": "SamBrishes, pytesNET",

tail.DateTime
=============
[![npm](https://img.shields.io/npm/v/tail.datetime.svg?style=flat-square)](https://www.npmjs.com/package/tail.datetime)
[![npm](https://img.shields.io/npm/dt/tail.datetime.svg?style=flat-square)](https://www.npmjs.com/package/tail.datetime)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Author](https://img.shields.io/badge/Author-SamBrishes@pytesNET-lightgrey.svg?style=flat-square)](https://www.github.com/pytesNET)
[![npm](https://s.pytes.net/4afcd19c)](https://s.pytes.net/64a7f3a3)
[![npm](https://s.pytes.net/2f3f75c4)](https://s.pytes.net/64a7f3a3)
[![Software License](https://s.pytes.net/8257ac72)](LICENSE.md)
[![Author](https://s.pytes.net/5542d1fa)](https://www.github.com/pytesNET)
**The tail.DateTime script is a fork of the [Pure JS Calendar](https://github.com/MrGuiseppe/pureJSCalendar), written by [MrGuiseppe](https://github.com/MrGuiseppe).** It is specially designed for the new, yet unpublished, backend theme for the FoxCMS. The tail.DateTime script offers the following changes compared to the Pure JS Calendar:
The **tail.DateTime** Calendar Interface is written in pure vanilla JavaScript and doesn't require
any additional dependencies. It was originally a fork of MrGuiseppes [Pure JS Calendar](https://github.com/MrGuiseppe/pureJSCalendar),
however version 0.4.0 has separated from the last origin lines and is now completely independent.
- A Time Picker (Hours, Minutes, Seconds)
- A Month-Based browse view
- A slightly different date/time output format
- A slightly different HTML class/id layout
- A different JS structure / implementation / constructur (Prototyping)
- Key Listener for 'Escape' (Close) and 'Enter' (Use Today / First Day of the month)
- Auto-Close on click outside of the calendar popup / input element
- Instance Caching + Calendar Caching with the first day in the week
- Default value depending on the input field
- "Translatable" Strings through the global variable
- And many more... Check out the Changelog for details.
[Wanna see **tail.DateTime** in action?](https://github.pytes.net/tail.DateTime)
[Demonstration](https://github.pytes.net/tail.DateTime)
[Wanna translate **tail.DateTime** in your language?](https://github.com/pytesNET/tail.DateTime/wiki/Help-Translating)
Work in Progress
----------------
The script is still **Work in Progress** and hasn't been tested much!
Features
--------
- A beautiful Date/Time Picker (in 2 Designs + 6 Color Schemes)
- Definable ranges of selectable dates (Blacklist / Whitelist)
- Colorable Tooltips with an cute animation
- Different Views to navigate quickly: Days, Months, Years & Decades
- Completely Translatable and available in 5 languages (de, de_AT, en, es, ru)
- Extendable and Bindable through different Events
- Compatible with AMD, tested with requireJS
- Many Settings to adapt and configure the design and behavior
- Compatible with all modern browsers **(including IE 9+)**
- No Dependencies, just embed and use
- Free/To/Use - MIT Licensed
Thanks to [MrGuiseppe](https://github.com/MrGuiseppe) and to [Octicons](https://octicons.github.com/) for the Vector Graphics.
Install & Embed
---------------
The master branch will always contain the latest Release, which you can download directly here
as [.tar](https://github.com/pytesNET/tail.DateTime/tarball/master) or as [.zip](https://github.com/pytesNET/tail.DateTime/zipball/master)
archive, or just visit the [Releases](https://github.com/pytesNET/tail.DateTime/releases) Page
on GitHub directly. You can also be cool and using NPM (or YARN):
Options
-------
```javascript
tail.DateTime(document.getElementById("my-input-field"), {
static: null,
position: "bottom",
classNames: "",
dateFormat: "YYYY-mm-dd",
timeFormat: "HH:ii:ss",
dateRanges: [],
weekStart: "SUN",
startOpen: false,
stayOpen: false,
zeroSeconds: false
});
```markup
npm install tail.DateTime --save
```
### static
`string`<br />
Pass an valid selector of an element where the Calendar Popup should be append to, leave it on
null to use the absolute position calculation.
```markup
yarn add tail.DateTime --save
```
### position
`string`<br />
Sets the position of the DateTime popup field to `"top"`, `"left"`, `"right"` or `"bottom"`. This
option **does not** work if you pass an valid selector on `static`!
```markup
bower install tail.DateTime --save
```
### classNames
`string` or `array`<br />
Adds custom class names to the main DateTime container element, pass and array or an space-separated
list!
### Using a CDN
You can also use the awesome CDN services from jsDelivr or UNPKG.
### dateFormat
`string` or `false`<br />
Pass an valid Date/Time Format (see below) or pass `false` to disable the Date picker.
```markup
https://cdn.jsdelivr.net/npm/tail.DateTime@latest/
```
### timeFormat
`string` or `false`<br />
Pass an valid Date/Time Format (see below) or pass `false` to disable the Time picker.
```markup
https://unpkg.com/tail.DateTime/
```
### dateRanges
`array`<br />
This option allows you to create one or more selectable periods of time. Each period defines itself
through an array, where the first value if the start-point and the last one the end-point (which is
also optional). You can use a `Date` object as value, a string as `YYYY-MM-DD` or the (translated)
name of a weekday (See `tailDateTime.strings.shorts`).
Thanks To
---------
- [MrGuiseppe](https://github.com/MrGuiseppe) for the Inspiration
- [Octicons](https://octicons.github.com/) for the cute Icons
- [jsCompress](https://jscompress.com/) for the Compressor
- [prismJS](https://prismjs.com) for the Syntax highlighting library
- [MenuSpy](https://github.com/lcdsantos/menuspy) for the Menu Navigation
#### Example:
The following Example limits the selectable area to:
Documentation
-------------
The Documentation has been moved to [GitHubs Wiki Pages](https://github.com/pytesNET/tail.DateTime/wiki),
but I will keep a table of contents list here and some basic instructions.
- From 2018-10-12 up to 2018-10-26
- From 2018-11-04 up to 2018-11-30
- From 2018-12-01 up to 2018-12-31
- **In all cases only from Monday up to Friday** (Sunday and Saturday are not selectable)
- [Instructions]()
- [Default Usage]()
- [Public Options]()
- [Public Methods]()
- [Events & Callbacks]()
- [Help Translating]()
- [Internal]()
The last array `["MON", "FRI"]` limits **only** all selections before! If you want to just use a
selection between Monday and Friday in general, add a third parameters with `true`.
### Basic Instructions
You can pass up to 2 arguments to the **tail.DateTime** constructor, the first parameter is required
and need to be an `Element`, a `NodeList`, a `HTMLCollection`, an Array with `Element` objects or
just a single selector as `string`, which calls the `querySelectorAll()` method on its own. The
second parameter is optional and, if set, MUST be an object with your *tail.DateTime* options.
```javascript
tail.DateTime("#datetime", {
dateRanges: [
[new Date(2018, 9, 12), new Date(2018, 9, 26)],
["2018-11-4", "2018-11-30"],
[new Date(2018, 11, 1), new Date(2018, 11, 31)],
["MON", "FRI"]
]
});
```
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
### weekStart
`string`<br />
Pass the (translated) string of the global variable `tailDateTime.strings.shorts` to change the
shown first day in the week. (If no translation has been made, you can choose between: "SUN", "MON",
"TUE", "WED", "THU", "FRI" and "SAT")
<link type="text/css" rel="stylesheet" href="css/tail.datetime-default.css" />
<!-- Additional Stylesheets -->
</head>
<body>
<script type="text/javascript" src="js/tail.datetime.min.js"></script>
<!-- <script type="text/javascript" src="langs/tail.datetime-{lang}.js"></script> -->
### startOpen
`boolean`<br />
Use true to show the DateTime Picker directly after the initialization.
<input type="text" class="tail-datetime-field" />
### stayOpen
`boolean`<br />
Use true to keep the DateTime Picker open, even if an selection has been made or any other closing
event has been triggered! (You can still close the DateTime Picker with the `close()` method!)
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(){
tail.DateTime(".tail-datetime-field", { /* Your Options */ });
});
</script>
</body>
</html>
```
### zeroSeconds
`boolean`<br />
Use true to set the seconds to `00`. This would be happen once, during the initialization.
### Default Settings
Please check out [GitHubs Wiki Pages](https://github.com/pytesNET/tail.DateTime/wiki) to read more
about each single option!
Date/Time Format
----------------
<table>
<tr>
<th>Code</th>
<th>Description</th>
</tr>
<tr>
<th>H</th>
<td>24-hour format of an hour, use `HH` for leading zeros!</td>
</tr>
<tr>
<th>G</th>
<td>12-hour format of an hour, use `GG` for leading zeros!</td>
</tr>
<tr>
<th>A</th>
<td>Uppercase Ante meridiem and Post meridiem (AM or PM).</td>
</tr>
<tr>
<th>a</th>
<td>Lowercase Ante meridiem and Post meridiem (am or om).</td>
</tr>
<tr>
<th>i</th>
<td>Minutes, use `ii` for leading zeros.</td>
</tr>
<tr>
<th>s</th>
<td>Seconds, use `ss` for leading zeros.</td>
</tr>
<tr>
<th>Y</th>
<td>A (4-digit) numeric representation of a year, used as `YY` or `YYYY`.</td>
</tr>
<tr>
<th>y</th>
<td>A (2-digit) numeric representation of a year, used as `yy`.</td>
</tr>
<tr>
<th>m</th>
<td>Numeric representation of a month, use `mm` for leading zeros.</td>
</tr>
<tr>
<th>M</th>
<td>A short textual representation of a month, three letters.</td>
</tr>
<tr>
<th>F</th>
<td>A full textual representation of a month, such as March.</td>
</tr>
<tr>
<th>d</th>
<td>Day of the month, use `dd` for leading zeros.</td>
</tr>
<tr>
<th>D</th>
<td>A textual representation of a day, three letters.</td>
</tr>
<tr>
<th>l</th>
<td>(Lower `L`) A full textual representation of the day of the week.</td>
</tr>
</table>
Methods
-------
```javascript
tail.DateTime(".tail-datetime-field", {
animate: true, // New in 0.4.0
classNames: false,
dateFormat: "YYYY-mm-dd",
dateStart: false, // New in 0.4.0
dateRanges: [], // New Syntax in 0.4.0
dateBlacklist: true, // New in 0.4.0
dateEnd: false, // New in 0.4.0
locale: "en", // New in 0.4.0
position: "bottom",
startOpen: false,
stayOpen: false,
timeFormat: "HH:ii:ss",
timeHours: null, // New in 0.4.0
timeMinutes: null, // New in 0.4.0
timeSeconds: 0, // New in 0.4.0
today: true, // New in 0.4.0
tooltips: [], // New in 0.4.0
viewDefault: "days", // New in 0.4.0
viewDecades: true, // New in 0.4.0
viewYears: true, // New in 0.4.0
viewMonths: true, // New in 0.4.0
viewDays: true, // New in 0.4.0
weekStart: 0
});
```
var calendar = tail.DateTime(document.getElementById("my-input-field"));
calendar.<method>();
```
### on(event, callback)
This method hooks an event with an respective callback function to the DateTime object. Available
Events:
- `tail.DateTime::open`, when the DateTime Picker opens.
- `tail.DateTime::close`, when the DateTime Picker closes.
- `tail.DateTime::select`, the a selection has been made.
### open()
This method opens the calendar popup, if it isn't already open!
### close()
This method closes the calendar popup, if it is still open!
### toggle()
This method toggles the open/close option of the calendar popup.
### remove()
This method removes the DateTime Picker elments and destroys the tail.DateTime picker instance.
### switchMonth(monthNum, year)
This method changes the shown month (monthNum starts with 0). You can also use "prev" or "next" to just browse forward and back.
### switchYear(year)
This method changes the year within the month view. You can also use "prev" or "next" to just browse forward and back.
### selectDate(Y, M, D, H, i, s)
Select a date with year, month, day, hours, minutes and seconds.
### selectTime(H, i, s)
Select a time (alias for `selectDate`) with hours, minutes and seconds.
Copyright & License
-------------------
Licensed under the MIT-License; Copyright &copy; 2018 SamBrishes, pytesNET
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc