You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
521 lines
14 KiB
521 lines
14 KiB
/*! UIkit 2.3.1 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
|
|
|
|
/*
|
|
* Based on https://github.com/jdewit/bootstrap-timepicker
|
|
*/
|
|
|
|
(function(global, $, UI){
|
|
|
|
// Timepicker
|
|
|
|
var TimePicker = function(element, options) {
|
|
|
|
var $this = this, $element = $(element);
|
|
|
|
if($element.data("timepicker")) return;
|
|
|
|
this.$element = $element;
|
|
this.element = this.$element[0];
|
|
this.options = $.extend({}, TimePicker.defaults, options);
|
|
|
|
this.$element.on({
|
|
'focus.timepicker.uikit' : $.proxy(this.highlightUnit, this),
|
|
'click.timepicker.uikit' : $.proxy(this.highlightUnit, this),
|
|
'keydown.timepicker.uikit': $.proxy(this.onKeydown, this),
|
|
'blur.timepicker.uikit' : $.proxy(this.blurElement, this)
|
|
});
|
|
|
|
this.setDefaultTime(this.options.defaultTime);
|
|
|
|
this.element.data("timepicker", this);
|
|
};
|
|
|
|
TimePicker.defaults = {
|
|
defaultTime: 'current',
|
|
disableFocus: false,
|
|
minuteStep: 15,
|
|
secondStep: 15,
|
|
showSeconds: false,
|
|
showMeridian: false
|
|
};
|
|
|
|
$.extend(TimePicker.prototype, {
|
|
|
|
setDefaultTime: function(defaultTime){
|
|
|
|
if (!this.element.value) {
|
|
|
|
if (defaultTime === 'current') {
|
|
|
|
var d = new Date();
|
|
|
|
this.hour = d.getHours(),
|
|
this.minute = Math.floor(d.getMinutes() / this.options.minuteStep) * this.options.minuteStep,
|
|
this.second = Math.floor(d.getSeconds() / this.options.secondStep) * this.options.secondStep,
|
|
this.meridian = 'AM';
|
|
|
|
if (this.options.showMeridian) {
|
|
if (this.hour === 0) {
|
|
this.hour = 12;
|
|
} else if (this.hour >= 12) {
|
|
if (this.hour > 12) this.hour = this.hour - 12;
|
|
this.meridian = 'PM';
|
|
} else {
|
|
this.meridian = 'AM';
|
|
}
|
|
}
|
|
|
|
this.update();
|
|
|
|
} else if (defaultTime === false) {
|
|
this.hour = 0;
|
|
this.minute = 0;
|
|
this.second = 0;
|
|
this.meridian = 'AM';
|
|
} else {
|
|
this.setTime(defaultTime);
|
|
}
|
|
|
|
} else {
|
|
this.updateFromElementVal();
|
|
}
|
|
},
|
|
|
|
setTime: function(time) {
|
|
var arr, timeArray;
|
|
|
|
if (this.options.showMeridian) {
|
|
arr = time.split(' ');
|
|
timeArray = arr[0].split(':');
|
|
this.meridian = arr[1];
|
|
} else {
|
|
timeArray = time.split(':');
|
|
}
|
|
|
|
this.hour = parseInt(timeArray[0], 10);
|
|
this.minute = parseInt(timeArray[1], 10);
|
|
this.second = parseInt(timeArray[2], 10);
|
|
|
|
if (isNaN(this.hour)) this.hour = 0;
|
|
if (isNaN(this.minute)) this.minute = 0;
|
|
|
|
if (this.options.showMeridian) {
|
|
if (this.hour > 12) {
|
|
this.hour = 12;
|
|
} else if (this.hour < 1) {
|
|
this.hour = 12;
|
|
}
|
|
|
|
if (this.meridian === 'am' || this.meridian === 'a') {
|
|
this.meridian = 'AM';
|
|
} else if (this.meridian === 'pm' || this.meridian === 'p') {
|
|
this.meridian = 'PM';
|
|
}
|
|
|
|
if (this.meridian !== 'AM' && this.meridian !== 'PM') {
|
|
this.meridian = 'AM';
|
|
}
|
|
|
|
} else {
|
|
|
|
if (this.hour >= 24) {
|
|
this.hour = 23;
|
|
} else if (this.hour < 0) {
|
|
this.hour = 0;
|
|
}
|
|
}
|
|
|
|
if (this.minute < 0) {
|
|
this.minute = 0;
|
|
} else if (this.minute >= 60) {
|
|
this.minute = 59;
|
|
}
|
|
|
|
if (this.options.showSeconds) {
|
|
if (isNaN(this.second)) {
|
|
this.second = 0;
|
|
} else if (this.second < 0) {
|
|
this.second = 0;
|
|
} else if (this.second >= 60) {
|
|
this.second = 59;
|
|
}
|
|
}
|
|
|
|
this.update();
|
|
},
|
|
|
|
blurElement: function() {
|
|
this.highlightedUnit = undefined;
|
|
this.updateFromElementVal();
|
|
},
|
|
|
|
decrementHour: function() {
|
|
if (this.options.showMeridian) {
|
|
if (this.hour === 1) {
|
|
this.hour = 12;
|
|
} else if (this.hour === 12) {
|
|
this.hour--;
|
|
|
|
return this.toggleMeridian();
|
|
} else if (this.hour === 0) {
|
|
this.hour = 11;
|
|
|
|
return this.toggleMeridian();
|
|
} else {
|
|
this.hour--;
|
|
}
|
|
} else {
|
|
if (this.hour === 0) {
|
|
this.hour = 23;
|
|
} else {
|
|
this.hour--;
|
|
}
|
|
}
|
|
this.update();
|
|
},
|
|
|
|
decrementMinute: function(step) {
|
|
|
|
var newVal = (step) ? this.minute - step : this.minute - this.options.minuteStep;
|
|
|
|
if (newVal < 0) {
|
|
this.decrementHour();
|
|
this.minute = newVal + 60;
|
|
} else {
|
|
this.minute = newVal;
|
|
}
|
|
this.update();
|
|
},
|
|
|
|
decrementSecond: function() {
|
|
var newVal = this.second - this.options.secondStep;
|
|
|
|
if (newVal < 0) {
|
|
this.decrementMinute(true);
|
|
this.second = newVal + 60;
|
|
} else {
|
|
this.second = newVal;
|
|
}
|
|
this.update();
|
|
},
|
|
|
|
onKeydown: function(e) {
|
|
switch (e.keyCode) {
|
|
case 9: //tab
|
|
this.updateFromElementVal();
|
|
|
|
switch (this.highlightedUnit) {
|
|
case 'hour':
|
|
e.preventDefault();
|
|
this.highlightNextUnit();
|
|
break;
|
|
case 'minute':
|
|
if (this.options.showMeridian || this.options.showSeconds) {
|
|
e.preventDefault();
|
|
this.highlightNextUnit();
|
|
}
|
|
break;
|
|
case 'second':
|
|
if (this.options.showMeridian) {
|
|
e.preventDefault();
|
|
this.highlightNextUnit();
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case 27: // escape
|
|
this.updateFromElementVal();
|
|
break;
|
|
case 37: // left arrow
|
|
e.preventDefault();
|
|
this.highlightPrevUnit();
|
|
this.updateFromElementVal();
|
|
break;
|
|
case 38: // up arrow
|
|
e.preventDefault();
|
|
switch (this.highlightedUnit) {
|
|
case 'hour':
|
|
this.incrementHour();
|
|
this.highlightHour();
|
|
break;
|
|
case 'minute':
|
|
this.incrementMinute();
|
|
this.highlightMinute();
|
|
break;
|
|
case 'second':
|
|
this.incrementSecond();
|
|
this.highlightSecond();
|
|
break;
|
|
case 'meridian':
|
|
this.toggleMeridian();
|
|
this.highlightMeridian();
|
|
break;
|
|
}
|
|
break;
|
|
case 39: // right arrow
|
|
e.preventDefault();
|
|
this.updateFromElementVal();
|
|
this.highlightNextUnit();
|
|
break;
|
|
case 40: // down arrow
|
|
e.preventDefault();
|
|
switch (this.highlightedUnit) {
|
|
case 'hour':
|
|
this.decrementHour();
|
|
this.highlightHour();
|
|
break;
|
|
case 'minute':
|
|
this.decrementMinute();
|
|
this.highlightMinute();
|
|
break;
|
|
case 'second':
|
|
this.decrementSecond();
|
|
this.highlightSecond();
|
|
break;
|
|
case 'meridian':
|
|
this.toggleMeridian();
|
|
this.highlightMeridian();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
|
|
formatTime: function(hour, minute, second, meridian) {
|
|
hour = hour < 10 ? '0' + hour : hour;
|
|
minute = minute < 10 ? '0' + minute : minute;
|
|
second = second < 10 ? '0' + second : second;
|
|
|
|
return hour + ':' + minute + (this.options.showSeconds ? ':' + second : '') + (this.options.showMeridian ? ' ' + meridian : '');
|
|
},
|
|
|
|
getCursorPosition: function() {
|
|
|
|
if ('selectionStart' in this.element) {// Standard-compliant browsers
|
|
|
|
return this.element.selectionStart;
|
|
} else if (document.selection) {// IE fix
|
|
this.element.focus();
|
|
var sel = document.selection.createRange(),
|
|
selLen = document.selection.createRange().text.length;
|
|
|
|
sel.moveStart('character', - this.element.value.length);
|
|
|
|
return sel.text.length - selLen;
|
|
}
|
|
},
|
|
|
|
getTime: function() {
|
|
return this.formatTime(this.hour, this.minute, this.second, this.meridian);
|
|
},
|
|
|
|
highlightUnit: function() {
|
|
this.position = this.getCursorPosition();
|
|
if (this.position >= 0 && this.position <= 2) {
|
|
this.highlightHour();
|
|
} else if (this.position >= 3 && this.position <= 5) {
|
|
this.highlightMinute();
|
|
} else if (this.position >= 6 && this.position <= 8) {
|
|
if (this.options.showSeconds) {
|
|
this.highlightSecond();
|
|
} else {
|
|
this.highlightMeridian();
|
|
}
|
|
} else if (this.position >= 9 && this.position <= 11) {
|
|
this.highlightMeridian();
|
|
}
|
|
},
|
|
|
|
highlightNextUnit: function() {
|
|
switch (this.highlightedUnit) {
|
|
case 'hour':
|
|
this.highlightMinute();
|
|
break;
|
|
case 'minute':
|
|
if (this.options.showSeconds) {
|
|
this.highlightSecond();
|
|
} else if (this.options.showMeridian){
|
|
this.highlightMeridian();
|
|
} else {
|
|
this.highlightHour();
|
|
}
|
|
break;
|
|
case 'second':
|
|
if (this.options.showMeridian) {
|
|
this.highlightMeridian();
|
|
} else {
|
|
this.highlightHour();
|
|
}
|
|
break;
|
|
case 'meridian':
|
|
this.highlightHour();
|
|
break;
|
|
}
|
|
},
|
|
|
|
highlightPrevUnit: function() {
|
|
switch (this.highlightedUnit) {
|
|
case 'hour':
|
|
this.highlightMeridian();
|
|
break;
|
|
case 'minute':
|
|
this.highlightHour();
|
|
break;
|
|
case 'second':
|
|
this.highlightMinute();
|
|
break;
|
|
case 'meridian':
|
|
if (this.options.showSeconds) {
|
|
this.highlightSecond();
|
|
} else {
|
|
this.highlightMinute();
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
|
|
highlightHour: function() {
|
|
var $element = this.element;
|
|
|
|
this.highlightedUnit = 'hour';
|
|
|
|
if ($element.setSelectionRange) {
|
|
setTimeout(function() {
|
|
$element.setSelectionRange(0,2);
|
|
}, 0);
|
|
}
|
|
},
|
|
|
|
highlightMinute: function() {
|
|
var $element = this.element;
|
|
|
|
this.highlightedUnit = 'minute';
|
|
|
|
if ($element.setSelectionRange) {
|
|
setTimeout(function() {
|
|
$element.setSelectionRange(3,5);
|
|
}, 0);
|
|
}
|
|
},
|
|
|
|
highlightSecond: function() {
|
|
var $element = this.element;
|
|
|
|
this.highlightedUnit = 'second';
|
|
|
|
if ($element.setSelectionRange) {
|
|
setTimeout(function() {
|
|
$element.setSelectionRange(6,8);
|
|
}, 0);
|
|
}
|
|
},
|
|
|
|
highlightMeridian: function() {
|
|
var $element = this.element;
|
|
|
|
this.highlightedUnit = 'meridian';
|
|
|
|
if ($element.setSelectionRange) {
|
|
if (this.options.showSeconds) {
|
|
setTimeout(function() {
|
|
$element.setSelectionRange(9,11);
|
|
}, 0);
|
|
} else {
|
|
setTimeout(function() {
|
|
$element.setSelectionRange(6,8);
|
|
}, 0);
|
|
}
|
|
}
|
|
},
|
|
|
|
incrementHour: function() {
|
|
if (this.options.showMeridian) {
|
|
if (this.hour === 11) {
|
|
this.hour++;
|
|
return this.toggleMeridian();
|
|
} else if (this.hour === 12) {
|
|
this.hour = 0;
|
|
}
|
|
}
|
|
|
|
if (this.hour === 23) {
|
|
this.hour = 0;
|
|
return;
|
|
}
|
|
|
|
this.hour++;
|
|
this.update();
|
|
},
|
|
|
|
incrementMinute: function(step) {
|
|
|
|
var newVal = step ? (this.minute + step) : (this.minute + this.options.minuteStep - (this.minute % this.options.minuteStep));
|
|
|
|
if (newVal > 59) {
|
|
this.incrementHour();
|
|
this.minute = newVal - 60;
|
|
} else {
|
|
this.minute = newVal;
|
|
}
|
|
this.update();
|
|
},
|
|
|
|
incrementSecond: function() {
|
|
var newVal = this.second + this.options.secondStep - (this.second % this.options.secondStep);
|
|
|
|
if (newVal > 59) {
|
|
this.incrementMinute(true);
|
|
this.second = newVal - 60;
|
|
} else {
|
|
this.second = newVal;
|
|
}
|
|
this.update();
|
|
},
|
|
|
|
remove: function() {
|
|
$('document').off('.timepicker.uikit');
|
|
delete this.$element.data().timepicker;
|
|
},
|
|
|
|
toggleMeridian: function() {
|
|
this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
|
|
this.update();
|
|
},
|
|
|
|
update: function() {
|
|
this.$element.trigger({
|
|
'type': 'changeTime.timepicker',
|
|
'time': {
|
|
'value': this.getTime(),
|
|
'hours': this.hour,
|
|
'minutes': this.minute,
|
|
'seconds': this.second,
|
|
'meridian': this.meridian
|
|
}
|
|
});
|
|
|
|
this.updateElement();
|
|
},
|
|
|
|
updateElement: function() {
|
|
this.$element.val(this.getTime()).trigger("change");
|
|
},
|
|
|
|
updateFromElementVal: function() {
|
|
if (this.element.value) this.setTime(this.element.value);
|
|
}
|
|
|
|
});
|
|
|
|
// init code
|
|
$(document).on("focus.timepicker.uikit", "[data-uk-timepicker]", function(e) {
|
|
|
|
var ele = $(this);
|
|
if (!ele.data("timepicker")) {
|
|
e.preventDefault();
|
|
var obj = new TimePicker(ele, UI.Utils.options(ele.attr("data-uk-timepicker")));
|
|
ele.trigger("focus");
|
|
}
|
|
});
|
|
|
|
})(this, jQuery, jQuery.UIkit);
|