/**
* @preserve jQuery PeriodPicker plugin v5.4.2
* @homepage http://xdsoft.net/jqplugins/periodpicker/
* @copyright (c) 2016 xdsoft.net Chupurnov Valeriy
* @license PRO http://xdsoft.net/jqplugins/periodpicker/license/
*/
(function ($, window, document) {
'use strict';
var uniqueid = 1;
function TimeWrapper(options) {
var now = new Date(), pm = 0, that = this;
that.onChange = [];
that.validate = function () {
if (options.minTime) {
if (!(options.minTime instanceof Date)) {
options.minTime = that.parse(options.minTime);
}
if (that.isValid(options.minTime)) {
options.minTime = that.cloneTime(options.minTime);
if (now < options.minTime) {
now = that.cloneTime(options.minTime);
}
} else {
options.minTime = false;
}
}
if (options.maxTime) {
if (!(options.maxTime instanceof Date)) {
options.maxTime = that.parse(options.maxTime);
}
if (that.isValid(options.maxTime)) {
options.maxTime = that.cloneTime(options.maxTime);
if (now > options.maxTime) {
now = that.cloneTime(options.maxTime);
}
} else {
options.maxTime = false;
}
}
};
that.cloneTime = function (time) {
var tmp = new Date();
tmp.setHours(time.getHours());
tmp.setMinutes(time.getMinutes());
tmp.setSeconds(time.getSeconds());
return tmp;
};
that.isValid = function (now) {
if (Object.prototype.toString.call(now) !== "[object Date]") {
return false;
}
return !isNaN(now.getTime());
};
that.hours12Format = function () {
var value = now.getHours();
if (value === 0) {
return 12;
}
if (value > 0 && value < 13) {
return value;
}
if (value > 12 && value <= 23) {
return value - 12;
}
};
that.to12Format = function (value) {
if (value === 12 && !pm) {
return 0;
}
return (pm && value < 12) ? value + 12 : value;
};
that.change = function (notriggerchange) {
var h;
if (that.onChange.length) {
for (h = 0; h < that.onChange.length; h += 1) {
if ($.isFunction(that.onChange[h])) {
that.onChange[h].call(that, that.get(), now, notriggerchange);
}
}
}
};
that.index = function (index, value) {
var h, oldvalue = now.getTime();
if (value !== undefined && value !== null) {
value = parseInt(value, 10);
switch (index) {
case 1:
now.setMinutes(value);
break;
case 2:
now.setSeconds(value);
break;
case 3:
h = now.getHours();
pm = value;
if (h < 12 && value) {
now.setHours(h + 12);
} else if (h >= 12 && !value) {
now.setHours(h - 12);
}
break;
default:
now.setHours((options.twelveHoursFormat) ? that.to12Format(value) : value);
break;
}
pm = that.index(3);
that.validate();
if (oldvalue !== now.getTime()) {
that.change();
}
}
switch (index) {
case 1:
return now.getMinutes();
case 2:
return now.getSeconds();
case 3:
pm = (now.getHours() >= 12 ? 1 : 0); // 1 - pm, 0 - am
return pm;
default:
return options.twelveHoursFormat ? that.hours12Format() : now.getHours();
}
};
that.parse = function (strOrDate) {
return window.moment !== undefined ? moment(strOrDate, options.inputFormat).toDate() : Date.parse(strOrDate);
};
that.set = function (strOrDate, notriggerchange) {
var oldvalue = now.getTime(), buff = that.isValid(strOrDate) ? that.cloneTime(strOrDate) : that.parse(strOrDate);
if (that.isValid(buff)) {
now = buff;
if (oldvalue !== now.getTime()) {
that.validate();
that.change(notriggerchange);
}
}
};
that.get = function () {
return window.moment !== undefined ? moment(now).format(options.inputFormat) : String(now);
};
that.getTime = function () {
return now.getTime();
};
return that;
}
function TimePicker(startinput, options, box) {
var that = this;
that.box = box || document.body;
that.options = options;
that.startinput = $(startinput);
that.uniqueid = uniqueid;
uniqueid += 1;
that.init();
}
TimePicker.prototype.getRealOffset = function (j) {
var index = this.getIndex(j);
return this.indexes[j].indexOf(index) !== -1 ? this.indexes[j].indexOf(index) * this.itemHeight() : 0;
};
TimePicker.prototype.getIndex = function (j) {
return Math.floor(this.currentime.index(j) / this.options.steps[j]) * this.options.steps[j];
};
TimePicker.prototype.height = function () {
return this.timepicker ? parseInt(this.timepicker.get(0).offsetHeight, 10) : 0;
};
TimePicker.prototype.itemHeight = function () {
return this.items[0][0] ? parseInt(this.items[0][0].get(0).offsetHeight, 10) : 22;
};
TimePicker.prototype.highlight = function () {
var i, val;
if (this.last === undefined) {
this.last = [];
}
for (i = 0; i < this.boxes.length; i += 1) {
val = this.getIndex(i);
if (this.items[i][this.indexes[i].indexOf(val)] !== undefined) {
this.items[i][this.indexes[i].indexOf(val)].addClass('active');
}
if (this.last[i] !== undefined && this.last[i] !== this.indexes[i].indexOf(val) && this.items[i][this.last[i]] !== undefined) {
this.items[i][this.last[i]].removeClass('active');
}
this.last[i] = this.indexes[i].indexOf(val);
}
};
TimePicker.prototype.setTime = function (args) {
var offset, j;
if (args !== undefined && args && args.length) {
for (j = this.boxes.length - 1; j >= 0; j -= 1) {
this.currentime.index(j, args[j]);
}
}
for (j = 0; j < this.boxes.length; j += 1) {
if (this.boxes[j] !== undefined) {
offset = -this.getRealOffset(j) + Math.ceil(this.height() - this.itemHeight()) / 2;
this.boxes[j].css('margin-top', offset + 'px');
}
}
this.highlight();
};
TimePicker.prototype.xy = function (e) {
var out = {x: 0, y: 0},
touch;
if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
out.x = touch.clientX;
out.y = touch.clientY;
} else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
out.x = e.clientX;
out.y = e.clientY;
}
return out;
};
TimePicker.prototype.init = function () {
var that = this, start, diff, maxindex;
that.timepicker = $('
' +
'
' +
(that.options.hours ?
'
' : '') +
(that.options.minutes ?
'
' : '') +
(that.options.seconds ?
'
' : '') +
(that.options.ampm ?
'
' : '') +
'
' +
'
' +
'
');
that.currentime = new TimeWrapper(that.options);
if (that.startinput.length && that.startinput.val()) {
that.currentime.set(that.startinput.val());
} else {
that.startinput.val(that.options.defaultTime);
that.currentime.set(that.options.defaultTime);
}
if (that.options.onChange) {
that.currentime.onChange.push(that.options.onChange);
}
if (that.options.saveOnChange) {
that.currentime.onChange.push(function (formatTime, normalTime, notriggerchange) {
var oldvalue = that.startinput.val();
that.startinput.val(formatTime);
if (formatTime !== oldvalue && !notriggerchange) {
that.startinput.trigger('change');
}
});
}
that.boxes = {};
maxindex = 0;
that.timepicker.find('.periodpicker_timepicker_sliders>div>div').each(function () {
maxindex = Math.max(maxindex, parseInt($(this).parent().data('index'), 10));
that.boxes[parseInt($(this).parent().data('index'), 10)] = $(this);
});
that.boxes.length = maxindex + 1;
that.timepicker.find('.periodpicker_timepicker_sliders>div').addClass('periodpicker_col' + that.timepicker.find('.periodpicker_timepicker_sliders>div>div').length);
that.timer2 = 0;
that.timepicker.on('mousewheel', function (e) {
if (that.options.mouseWheel) {
e.preventDefault();
e.stopPropagation();
}
});
that.timepicker.find('.periodpicker_timepicker_sliders>div').on('mousewheel', function (e) {
if (that.options.mouseWheel) {
var box = $(this), time = [null, null, null, null], i = parseInt($(this).data('index'), 10);
box.addClass('draggable');
if (i < 3) {
time[i] = that.currentime.index(i) + (-e.deltaY * (that.options.inverseMouseWheel ? -1 : 1)) * that.options.steps[i];
} else {
time[i] = that.currentime.index(i) - 1;
}
that.setTime(time);
clearTimeout(that.timer2);
that.timer2 = setTimeout(function () {
box.removeClass('draggable');
}, 300);
e.preventDefault();
e.stopPropagation();
}
});
that.timepicker.find('.periodpicker_timepicker_sliders').on('click', '.periodpicker_item', function () {
if (that.options.clickAndSelect) {
var value = parseInt($(this).data('value'), 10), time = [null, null, null, null], i = parseInt($(this).parent().parent().data('index'), 10);
if (!that.iwasdragged && !isNaN(value)) {
time[i] = value;
that.setTime(time);
}
}
});
that.timer = 0;
that.timepicker.find('.periodpicker_timepicker_sliders>div input.periodpicker_key_hooker').on('keydown', function (e) {
if (that.options.listenKeyPress) {
var time = [null, null, null, null], $input = $(this), i = parseInt($input.parent().data('index'), 10), worked = false;
switch (e.keyCode) {
case 38:
time[i] = that.currentime.index(i) - that.options.steps[i];
that.setTime(time);
worked = true;
break;
case 39:
if ($(this).parent().next().length) {
$(this).parent().next().find('input.periodpicker_key_hooker').eq(0).focus();
}
worked = true;
break;
case 37:
if ($(this).parent().prev().length) {
$(this).parent().prev().find('input.periodpicker_key_hooker').eq(0).focus();
}
worked = true;
break;
case 40:
time[i] = that.currentime.index(i) + that.options.steps[i];
that.setTime(time);
worked = true;
break;
default:
if (/[0-9amp]/i.test(String.fromCharCode(e.keyCode))) {
$input.val($input.val() + String.fromCharCode(e.keyCode));
worked = true;
}
clearTimeout(that.timer);
that.timer = setTimeout(function () {
var value = $input.val();
$input.val('');
if (i === 3 && value.length) {
value = value.toLowerCase().substr(0, 1) === 'p' ? 1 : 0;
}
value = parseInt(value, 10);
if (!isNaN(value)) {
time[i] = value;
that.setTime(time);
}
}, 300);
}
if (worked) {
e.preventDefault();
e.stopImmediatePropagation();
}
}
});
that.timepicker.find('.periodpicker_timepicker_sliders>div').on('mousedown.xdsoft touchstart.xdsoft', function (e) {
if (that.options.dragAndDrop) {
that.drag = true;
start = [that.xy(e).x, that.xy(e).y];
start[4] = parseInt($(this).data('index'), 10);
start[3] = that.boxes[start[4]];
start[2] = parseInt(start[3].css('margin-top'), 10);
start[3].find('div').removeClass('active');
start[3].parent().addClass('draggable');
that.iwasdragged = false;
e.preventDefault();
e.stopImmediatePropagation();
}
$(this).find('input.periodpicker_key_hooker').focus();
});
that.iwasdragged = false;
$(window)
.on('mouseup.xdsoft' + that.uniqueid + ' touchend.xdsoft' + that.uniqueid, function (e) {
if (that.options.dragAndDrop && that.drag) {
that.drag = false;
that.setTime();
start[3].parent().removeClass('draggable');
e.stopImmediatePropagation();
}
})
.on('mousemove.xdsoft' + that.uniqueid + ' touchmove.xdsoft' + that.uniqueid, function (e) {
if (that.drag && that.options.dragAndDrop) {
diff = [that.xy(e).x - start[0], that.xy(e).y - start[1]];
start[3].css({
marginTop: start[2] + diff[1]
});
if (diff[1] > 10) {
that.iwasdragged = true;
}
var value = -Math.round((-(that.height() - that.itemHeight()) / 2 + start[2] + diff[1]) / that.itemHeight());
if (value < 0) {
value = 0;
}
if (value >= that.items[start[4]].length) {
value = that.items[start[4]].length - 1;
}
value = parseInt(that.items[start[4]][value].data('value'), 10);
that.currentime.index(start[4], value);
that.highlight();
e.preventDefault();
}
});
$(that.box).append(that.timepicker);
that.generateTimepicker();
that.setTime();
};
TimePicker.prototype.destroy = function () {
var that = this;
$(window)
.off('mouseup.xdsoft' + that.uniqueid + ' touchend.xdsoft' + that.uniqueid)
.off('mousemove.xdsoft' + that.uniqueid + ' touchmove.xdsoft' + that.uniqueid);
that.timepicker.remove();
delete that.timepicker;
delete that.boxes;
delete that.currentime;
};
TimePicker.prototype.generateTimepicker = function () {
var i, j, that = this;
that.items = [[], [], [], []];
that.indexes = [[], [], [], [0, 1]];
for (i = 0; i <= 2; i += 1) {
if (that.options.parts[i] !== undefined && that.boxes[i] !== undefined) {
if (!that.options.twelveHoursFormat || i > 0) {
for (j = that.options.parts[i][0][0]; j <= that.options.parts[i][0][1]; j += that.options.steps[i]) {
that.items[i].push($('' + (j < 10 ? '0' : '') + j + '
'));
that.indexes[i].push(j);
}
} else {
that.items[i].push($('12
'));
that.indexes[i].push(12);
for (j = 1; j <= 11; j += that.options.steps[i]) {
that.items[i].push($('' + (j < 10 ? '0' : '') + j + '
'));
that.indexes[i].push(j);
}
}
that.boxes[i].html(that.items[i]);
}
}
if (that.boxes[3] && that.boxes[3].length) {
that.boxes[i].find('div').each(function () {
that.items[3].push($(this));
});
}
};
$.fn.TimePicker = function (opt, opt1, opt3) {
var returnValue = this, oldvalue;
this.each(function () {
var options,
$this = $(this),
timepicker = $this.data('timepicker');
// do nothing if call command instead init
if (!timepicker && typeof opt === 'string') {
return;
}
if (!timepicker) {
options = $.extend(true, {}, $.fn.TimePicker.defaultOptions, opt);
timepicker = new TimePicker(this, options, opt1);
$this.data('timepicker', timepicker);
} else {
switch (opt) {
case 'stopDrag':
timepicker.drag = false;
timepicker.timepicker.find('.draggable').removeClass('draggable');
timepicker.setTime();
break;
case 'regenerate':
timepicker.setTime();
break;
case 'destroy':
timepicker.destroy();
break;
case 'save':
$this.val(timepicker.currentime.get());
break;
case 'setValue':
timepicker.currentime.set(opt1, opt3);
timepicker.setTime();
break;
case 'setMin':
case 'setMax':
oldvalue = timepicker.currentime.getTime();
timepicker.options[opt === 'setMin' ? 'minTime' : 'maxTime'] = opt1;
timepicker.currentime.validate();
timepicker.setTime();
if (oldvalue !== timepicker.currentime.getTime()) {
timepicker.currentime.change();
}
break;
case 'getValue':
returnValue = timepicker.currentime.get();
break;
}
}
});
return returnValue;
};
$.fn.timepicker = $.fn.TimePicker;
$.fn.TimePicker.defaultOptions = {
clickAndSelect: true,
dragAndDrop: true,
mouseWheel: true,
inverseMouseWheel: false,
listenKeyPress: true,
saveOnChange: true,
onChange: function () {
//console.log(str); // arguments[0]
//console.log(datetime); // arguments[1]
return true;
},
twelveHoursFormat: true,
inputFormat: 'HH:mm:ss',
defaultTime: '00:00:00',
minTime: false,
maxTime: false,
hours: true,
minutes: true,
seconds: false,
ampm: true,
parts: [
[
[0, 23]
],
[
[0, 59]
],
[
[0, 59]
],
[
[0, 1]
]
],
steps: [1, 1, 1, 1]
};
function TimePickerAlone(startinput, options) {
var that = this;
that.uniqueid = uniqueid;
uniqueid += 1;
that.options = options;
that.startinput = $(startinput);
that.picker = $('');
that.startinput.TimePicker(options, that.picker);
if (that.options.inline) {
that.picker.addClass('periodpicker_timepicker_inline');
that.startinput.after(that.picker).hide();
that.startinput.TimePicker('regenerate');
} else {
$(document.body).append(that.picker);
that.startinput.on('focus.xdsoft' + that.uniqueid, function () {
that.show();
});
$(window).on('mousedown.xdsoft' + that.uniqueid, function () {
that.hide();
});
}
}
TimePickerAlone.prototype.destroy = function () {
this.startinput.TimePicker('destroy');
this.picker.remove();
};
TimePickerAlone.prototype.hide = function () {
if (this.picker.hasClass('visible')) {
var hide = true;
if (this.options.onHide && $.isFunction(this.options.onHide)) {
hide = !(this.options.onHide.call(this, this.startinput) === false);
}
if (hide) {
this.picker.removeClass('visible');
}
}
};
TimePickerAlone.prototype.show = function () {
if (!this.picker.hasClass('visible')) {
var offset = this.startinput.offset(), top, left;
top = offset.top + this.startinput.outerHeight() - 1;
left = offset.left;
if (top + this.picker.outerHeight() > $(window).height() + $(window).scrollTop()) {
top = offset.top - this.picker.outerHeight() - 1;
}
if (top < 0) {
top = 0;
}
if (left + this.picker.outerWidth() > $(window).width()) {
left = $(window).width() - this.picker.outerWidth();
}
this.picker.css({
left: left,
top: top,
});
this.picker.addClass('visible');
this.startinput.TimePicker('regenerate');
}
};
$.fn.TimePickerAlone = function (opt, opt1, opt2) {
var returnValue = this;
this.each(function () {
var options,
$this = $(this),
timepickeralone = $this.data('timepickeralone');
if (!timepickeralone) {
options = $.extend(true, {}, $.fn.TimePicker.defaultOptions, $.fn.TimePickerAlone.defaultOptions, opt);
timepickeralone = new TimePickerAlone(this, options);
$this.data('timepickeralone', timepickeralone);
} else {
switch (opt) {
case 'destroy':
timepickeralone.destroy();
break;
default:
return timepickeralone.startinput.TimePicker(opt, opt1, opt2);
}
}
});
return returnValue;
};
$.fn.timepickeralone = $.fn.TimePickerAlone;
$.fn.TimePickerAlone.defaultOptions = {
inline: false,
onHide: function () {
return true;
}
};
}(jQuery, window, document));