初始化
This commit is contained in:
168
MQTTServerSideAPI/plugins/clockpicker/clockpicker.css
Normal file
168
MQTTServerSideAPI/plugins/clockpicker/clockpicker.css
Normal file
@@ -0,0 +1,168 @@
|
||||
/*!
|
||||
* ClockPicker v{package.version} for Bootstrap (http://weareoutman.github.io/clockpicker/)
|
||||
* Copyright 2014 Wang Shenwei.
|
||||
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
|
||||
*/
|
||||
|
||||
.clockpicker .input-group-addon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.clockpicker-moving {
|
||||
cursor: move;
|
||||
}
|
||||
.clockpicker-align-left.popover > .arrow {
|
||||
left: 25px;
|
||||
}
|
||||
.clockpicker-align-top.popover > .arrow {
|
||||
top: 17px;
|
||||
}
|
||||
.clockpicker-align-right.popover > .arrow {
|
||||
left: auto;
|
||||
right: 25px;
|
||||
}
|
||||
.clockpicker-align-bottom.popover > .arrow {
|
||||
top: auto;
|
||||
bottom: 6px;
|
||||
}
|
||||
.clockpicker-popover .popover-title {
|
||||
background-color: #fff;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
.clockpicker-popover .popover-title span {
|
||||
cursor: pointer;
|
||||
}
|
||||
.clockpicker-popover .popover-content {
|
||||
background-color: #f8f8f8;
|
||||
padding: 12px;
|
||||
}
|
||||
.popover-content:last-child {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
.clockpicker-plate {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 50%;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
/* Disable text selection highlighting. Thanks to Hermanya */
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.clockpicker-canvas,
|
||||
.clockpicker-dial {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
top: -1px;
|
||||
}
|
||||
.clockpicker-minutes {
|
||||
visibility: hidden;
|
||||
}
|
||||
.clockpicker-tick {
|
||||
border-radius: 50%;
|
||||
color: #666;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
.clockpicker-tick.active,
|
||||
.clockpicker-tick:hover {
|
||||
background-color: rgb(192, 229, 247);
|
||||
background-color: rgba(0, 149, 221, .25);
|
||||
}
|
||||
.clockpicker-button {
|
||||
background-image: none;
|
||||
background-color: #fff;
|
||||
border-width: 1px 0 0;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.clockpicker-button:hover {
|
||||
background-image: none;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
.clockpicker-button:focus {
|
||||
outline: none!important;
|
||||
}
|
||||
.clockpicker-dial {
|
||||
-webkit-transition: -webkit-transform 350ms, opacity 350ms;
|
||||
-moz-transition: -moz-transform 350ms, opacity 350ms;
|
||||
-ms-transition: -ms-transform 350ms, opacity 350ms;
|
||||
-o-transition: -o-transform 350ms, opacity 350ms;
|
||||
transition: transform 350ms, opacity 350ms;
|
||||
}
|
||||
.clockpicker-dial-out {
|
||||
opacity: 0;
|
||||
}
|
||||
.clockpicker-hours.clockpicker-dial-out {
|
||||
-webkit-transform: scale(1.2, 1.2);
|
||||
-moz-transform: scale(1.2, 1.2);
|
||||
-ms-transform: scale(1.2, 1.2);
|
||||
-o-transform: scale(1.2, 1.2);
|
||||
transform: scale(1.2, 1.2);
|
||||
}
|
||||
.clockpicker-minutes.clockpicker-dial-out {
|
||||
-webkit-transform: scale(.8, .8);
|
||||
-moz-transform: scale(.8, .8);
|
||||
-ms-transform: scale(.8, .8);
|
||||
-o-transform: scale(.8, .8);
|
||||
transform: scale(.8, .8);
|
||||
}
|
||||
.clockpicker-canvas {
|
||||
-webkit-transition: opacity 175ms;
|
||||
-moz-transition: opacity 175ms;
|
||||
-ms-transition: opacity 175ms;
|
||||
-o-transition: opacity 175ms;
|
||||
transition: opacity 175ms;
|
||||
}
|
||||
.clockpicker-canvas-out {
|
||||
opacity: 0.25;
|
||||
}
|
||||
.clockpicker-canvas-bearing,
|
||||
.clockpicker-canvas-fg {
|
||||
stroke: none;
|
||||
fill: rgb(0, 149, 221);
|
||||
}
|
||||
.clockpicker-canvas-bg {
|
||||
stroke: none;
|
||||
fill: rgb(192, 229, 247);
|
||||
}
|
||||
.clockpicker-canvas-bg-trans {
|
||||
fill: rgba(0, 149, 221, .25);
|
||||
}
|
||||
.clockpicker-canvas line {
|
||||
stroke: rgb(0, 149, 221);
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
/*shape-rendering: crispEdges;*/
|
||||
}
|
||||
.clockpicker-button.am-button {
|
||||
margin: 1px;
|
||||
padding: 5px;
|
||||
border: 1px solid rgba(0, 0, 0, .2);
|
||||
border-radius: 4px;
|
||||
|
||||
}
|
||||
.clockpicker-button.pm-button {
|
||||
margin: 1px 1px 1px 136px;
|
||||
padding: 5px;
|
||||
border: 1px solid rgba(0, 0, 0, .2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
729
MQTTServerSideAPI/plugins/clockpicker/clockpicker.js
Normal file
729
MQTTServerSideAPI/plugins/clockpicker/clockpicker.js
Normal file
@@ -0,0 +1,729 @@
|
||||
/*!
|
||||
* ClockPicker v{package.version} (http://weareoutman.github.io/clockpicker/)
|
||||
* Copyright 2014 Wang Shenwei.
|
||||
* Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
|
||||
*/
|
||||
|
||||
;(function(){
|
||||
var $ = window.jQuery,
|
||||
$win = $(window),
|
||||
$doc = $(document),
|
||||
$body;
|
||||
|
||||
// Can I use inline svg ?
|
||||
var svgNS = 'http://www.w3.org/2000/svg',
|
||||
svgSupported = 'SVGAngle' in window && (function(){
|
||||
var supported,
|
||||
el = document.createElement('div');
|
||||
el.innerHTML = '<svg/>';
|
||||
supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS;
|
||||
el.innerHTML = '';
|
||||
return supported;
|
||||
})();
|
||||
|
||||
// Can I use transition ?
|
||||
var transitionSupported = (function(){
|
||||
var style = document.createElement('div').style;
|
||||
return 'transition' in style ||
|
||||
'WebkitTransition' in style ||
|
||||
'MozTransition' in style ||
|
||||
'msTransition' in style ||
|
||||
'OTransition' in style;
|
||||
})();
|
||||
|
||||
// Listen touch events in touch screen device, instead of mouse events in desktop.
|
||||
var touchSupported = 'ontouchstart' in window,
|
||||
mousedownEvent = 'mousedown' + ( touchSupported ? ' touchstart' : ''),
|
||||
mousemoveEvent = 'mousemove.clockpicker' + ( touchSupported ? ' touchmove.clockpicker' : ''),
|
||||
mouseupEvent = 'mouseup.clockpicker' + ( touchSupported ? ' touchend.clockpicker' : '');
|
||||
|
||||
// Vibrate the device if supported
|
||||
var vibrate = navigator.vibrate ? 'vibrate' : navigator.webkitVibrate ? 'webkitVibrate' : null;
|
||||
|
||||
function createSvgElement(name) {
|
||||
return document.createElementNS(svgNS, name);
|
||||
}
|
||||
|
||||
function leadingZero(num) {
|
||||
return (num < 10 ? '0' : '') + num;
|
||||
}
|
||||
|
||||
// Get a unique id
|
||||
var idCounter = 0;
|
||||
function uniqueId(prefix) {
|
||||
var id = ++idCounter + '';
|
||||
return prefix ? prefix + id : id;
|
||||
}
|
||||
|
||||
// Clock size
|
||||
var dialRadius = 100,
|
||||
outerRadius = 80,
|
||||
// innerRadius = 80 on 12 hour clock
|
||||
innerRadius = 54,
|
||||
tickRadius = 13,
|
||||
diameter = dialRadius * 2,
|
||||
duration = transitionSupported ? 350 : 1;
|
||||
|
||||
// Popover template
|
||||
var tpl = [
|
||||
'<div class="popover clockpicker-popover">',
|
||||
'<div class="arrow"></div>',
|
||||
'<div class="popover-title">',
|
||||
'<span class="clockpicker-span-hours text-primary"></span>',
|
||||
' : ',
|
||||
'<span class="clockpicker-span-minutes"></span>',
|
||||
'<span class="clockpicker-span-am-pm"></span>',
|
||||
'</div>',
|
||||
'<div class="popover-content">',
|
||||
'<div class="clockpicker-plate">',
|
||||
'<div class="clockpicker-canvas"></div>',
|
||||
'<div class="clockpicker-dial clockpicker-hours"></div>',
|
||||
'<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',
|
||||
'</div>',
|
||||
'<span class="clockpicker-am-pm-block">',
|
||||
'</span>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
|
||||
// ClockPicker
|
||||
function ClockPicker(element, options) {
|
||||
var popover = $(tpl),
|
||||
plate = popover.find('.clockpicker-plate'),
|
||||
hoursView = popover.find('.clockpicker-hours'),
|
||||
minutesView = popover.find('.clockpicker-minutes'),
|
||||
amPmBlock = popover.find('.clockpicker-am-pm-block'),
|
||||
isInput = element.prop('tagName') === 'INPUT',
|
||||
input = isInput ? element : element.find('input'),
|
||||
addon = element.find('.input-group-addon'),
|
||||
self = this,
|
||||
timer;
|
||||
|
||||
this.id = uniqueId('cp');
|
||||
this.element = element;
|
||||
this.options = options;
|
||||
this.isAppended = false;
|
||||
this.isShown = false;
|
||||
this.currentView = 'hours';
|
||||
this.isInput = isInput;
|
||||
this.input = input;
|
||||
this.addon = addon;
|
||||
this.popover = popover;
|
||||
this.plate = plate;
|
||||
this.hoursView = hoursView;
|
||||
this.minutesView = minutesView;
|
||||
this.amPmBlock = amPmBlock;
|
||||
this.spanHours = popover.find('.clockpicker-span-hours');
|
||||
this.spanMinutes = popover.find('.clockpicker-span-minutes');
|
||||
this.spanAmPm = popover.find('.clockpicker-span-am-pm');
|
||||
this.amOrPm = "PM";
|
||||
|
||||
// Setup for for 12 hour clock if option is selected
|
||||
if (options.twelvehour) {
|
||||
|
||||
var amPmButtonsTemplate = ['<div class="clockpicker-am-pm-block">',
|
||||
'<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-am-button">',
|
||||
'AM</button>',
|
||||
'<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-pm-button">',
|
||||
'PM</button>',
|
||||
'</div>'].join('');
|
||||
|
||||
var amPmButtons = $(amPmButtonsTemplate);
|
||||
//amPmButtons.appendTo(plate);
|
||||
|
||||
////Not working b/c they are not shown when this runs
|
||||
//$('clockpicker-am-button')
|
||||
// .on("click", function() {
|
||||
// self.amOrPm = "AM";
|
||||
// $('.clockpicker-span-am-pm').empty().append('AM');
|
||||
// });
|
||||
//
|
||||
//$('clockpicker-pm-button')
|
||||
// .on("click", function() {
|
||||
// self.amOrPm = "PM";
|
||||
// $('.clockpicker-span-am-pm').empty().append('PM');
|
||||
// });
|
||||
|
||||
$('<button type="button" class="btn btn-sm btn-default clockpicker-button am-button">' + "AM" + '</button>')
|
||||
.on("click", function() {
|
||||
self.amOrPm = "AM";
|
||||
$('.clockpicker-span-am-pm').empty().append('AM');
|
||||
}).appendTo(this.amPmBlock);
|
||||
|
||||
|
||||
$('<button type="button" class="btn btn-sm btn-default clockpicker-button pm-button">' + "PM" + '</button>')
|
||||
.on("click", function() {
|
||||
self.amOrPm = 'PM';
|
||||
$('.clockpicker-span-am-pm').empty().append('PM');
|
||||
}).appendTo(this.amPmBlock);
|
||||
|
||||
}
|
||||
|
||||
if (! options.autoclose) {
|
||||
// If autoclose is not setted, append a button
|
||||
$('<button type="button" class="btn btn-sm btn-default btn-block clockpicker-button">' + options.donetext + '</button>')
|
||||
.click($.proxy(this.done, this))
|
||||
.appendTo(popover);
|
||||
}
|
||||
|
||||
// Placement and arrow align - make sure they make sense.
|
||||
if ((options.placement === 'top' || options.placement === 'bottom') && (options.align === 'top' || options.align === 'bottom')) options.align = 'left';
|
||||
if ((options.placement === 'left' || options.placement === 'right') && (options.align === 'left' || options.align === 'right')) options.align = 'top';
|
||||
|
||||
popover.addClass(options.placement);
|
||||
popover.addClass('clockpicker-align-' + options.align);
|
||||
|
||||
this.spanHours.click($.proxy(this.toggleView, this, 'hours'));
|
||||
this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes'));
|
||||
|
||||
// Show or toggle
|
||||
input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this));
|
||||
addon.on('click.clockpicker', $.proxy(this.toggle, this));
|
||||
|
||||
// Build ticks
|
||||
var tickTpl = $('<div class="clockpicker-tick"></div>'),
|
||||
i, tick, radian, radius;
|
||||
|
||||
// Hours view
|
||||
if (options.twelvehour) {
|
||||
for (i = 1; i < 13; i += 1) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 6 * Math.PI;
|
||||
radius = outerRadius;
|
||||
tick.css('font-size', '120%');
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * radius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * radius - tickRadius
|
||||
});
|
||||
tick.html(i === 0 ? '00' : i);
|
||||
hoursView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 24; i += 1) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 6 * Math.PI;
|
||||
var inner = i > 0 && i < 13;
|
||||
radius = inner ? innerRadius : outerRadius;
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * radius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * radius - tickRadius
|
||||
});
|
||||
if (inner) {
|
||||
tick.css('font-size', '120%');
|
||||
}
|
||||
tick.html(i === 0 ? '00' : i);
|
||||
hoursView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
}
|
||||
|
||||
// Minutes view
|
||||
for (i = 0; i < 60; i += 5) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 30 * Math.PI;
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * outerRadius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * outerRadius - tickRadius
|
||||
});
|
||||
tick.css('font-size', '120%');
|
||||
tick.html(leadingZero(i));
|
||||
minutesView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
|
||||
// Clicking on minutes view space
|
||||
plate.on(mousedownEvent, function(e){
|
||||
if ($(e.target).closest('.clockpicker-tick').length === 0) {
|
||||
mousedown(e, true);
|
||||
}
|
||||
});
|
||||
|
||||
// Mousedown or touchstart
|
||||
function mousedown(e, space) {
|
||||
var offset = plate.offset(),
|
||||
isTouch = /^touch/.test(e.type),
|
||||
x0 = offset.left + dialRadius,
|
||||
y0 = offset.top + dialRadius,
|
||||
dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
|
||||
dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0,
|
||||
z = Math.sqrt(dx * dx + dy * dy),
|
||||
moved = false;
|
||||
|
||||
// When clicking on minutes view space, check the mouse position
|
||||
if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
// Set cursor style of body after 200ms
|
||||
var movingTimer = setTimeout(function(){
|
||||
$body.addClass('clockpicker-moving');
|
||||
}, 200);
|
||||
|
||||
// Place the canvas to top
|
||||
if (svgSupported) {
|
||||
plate.append(self.canvas);
|
||||
}
|
||||
|
||||
// Clock
|
||||
self.setHand(dx, dy, ! space, true);
|
||||
|
||||
// Mousemove on document
|
||||
$doc.off(mousemoveEvent).on(mousemoveEvent, function(e){
|
||||
e.preventDefault();
|
||||
var isTouch = /^touch/.test(e.type),
|
||||
x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
|
||||
y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0;
|
||||
if (! moved && x === dx && y === dy) {
|
||||
// Clicking in chrome on windows will trigger a mousemove event
|
||||
return;
|
||||
}
|
||||
moved = true;
|
||||
self.setHand(x, y, false, true);
|
||||
});
|
||||
|
||||
// Mouseup on document
|
||||
$doc.off(mouseupEvent).on(mouseupEvent, function(e){
|
||||
$doc.off(mouseupEvent);
|
||||
e.preventDefault();
|
||||
var isTouch = /^touch/.test(e.type),
|
||||
x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0,
|
||||
y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0;
|
||||
if ((space || moved) && x === dx && y === dy) {
|
||||
self.setHand(x, y);
|
||||
}
|
||||
if (self.currentView === 'hours') {
|
||||
self.toggleView('minutes', duration / 2);
|
||||
} else {
|
||||
if (options.autoclose) {
|
||||
self.minutesView.addClass('clockpicker-dial-out');
|
||||
setTimeout(function(){
|
||||
self.done();
|
||||
}, duration / 2);
|
||||
}
|
||||
}
|
||||
plate.prepend(canvas);
|
||||
|
||||
// Reset cursor style of body
|
||||
clearTimeout(movingTimer);
|
||||
$body.removeClass('clockpicker-moving');
|
||||
|
||||
// Unbind mousemove event
|
||||
$doc.off(mousemoveEvent);
|
||||
});
|
||||
}
|
||||
|
||||
if (svgSupported) {
|
||||
// Draw clock hands and others
|
||||
var canvas = popover.find('.clockpicker-canvas'),
|
||||
svg = createSvgElement('svg');
|
||||
svg.setAttribute('class', 'clockpicker-svg');
|
||||
svg.setAttribute('width', diameter);
|
||||
svg.setAttribute('height', diameter);
|
||||
var g = createSvgElement('g');
|
||||
g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')');
|
||||
var bearing = createSvgElement('circle');
|
||||
bearing.setAttribute('class', 'clockpicker-canvas-bearing');
|
||||
bearing.setAttribute('cx', 0);
|
||||
bearing.setAttribute('cy', 0);
|
||||
bearing.setAttribute('r', 2);
|
||||
var hand = createSvgElement('line');
|
||||
hand.setAttribute('x1', 0);
|
||||
hand.setAttribute('y1', 0);
|
||||
var bg = createSvgElement('circle');
|
||||
bg.setAttribute('class', 'clockpicker-canvas-bg');
|
||||
bg.setAttribute('r', tickRadius);
|
||||
var fg = createSvgElement('circle');
|
||||
fg.setAttribute('class', 'clockpicker-canvas-fg');
|
||||
fg.setAttribute('r', 3.5);
|
||||
g.appendChild(hand);
|
||||
g.appendChild(bg);
|
||||
g.appendChild(fg);
|
||||
g.appendChild(bearing);
|
||||
svg.appendChild(g);
|
||||
canvas.append(svg);
|
||||
|
||||
this.hand = hand;
|
||||
this.bg = bg;
|
||||
this.fg = fg;
|
||||
this.bearing = bearing;
|
||||
this.g = g;
|
||||
this.canvas = canvas;
|
||||
}
|
||||
|
||||
raiseCallback(this.options.init);
|
||||
}
|
||||
|
||||
function raiseCallback(callbackFunction) {
|
||||
if (callbackFunction && typeof callbackFunction === "function") {
|
||||
callbackFunction();
|
||||
}
|
||||
}
|
||||
|
||||
// Default options
|
||||
ClockPicker.DEFAULTS = {
|
||||
'default': '', // default time, 'now' or '13:14' e.g.
|
||||
fromnow: 0, // set default time to * milliseconds from now (using with default = 'now')
|
||||
placement: 'bottom', // clock popover placement
|
||||
align: 'left', // popover arrow align
|
||||
donetext: '完成', // done button text
|
||||
autoclose: false, // auto close when minute is selected
|
||||
twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
|
||||
vibrate: true // vibrate the device when dragging clock hand
|
||||
};
|
||||
|
||||
// Show or hide popover
|
||||
ClockPicker.prototype.toggle = function(){
|
||||
this[this.isShown ? 'hide' : 'show']();
|
||||
};
|
||||
|
||||
// Set popover position
|
||||
ClockPicker.prototype.locate = function(){
|
||||
var element = this.element,
|
||||
popover = this.popover,
|
||||
offset = element.offset(),
|
||||
width = element.outerWidth(),
|
||||
height = element.outerHeight(),
|
||||
placement = this.options.placement,
|
||||
align = this.options.align,
|
||||
styles = {},
|
||||
self = this;
|
||||
|
||||
popover.show();
|
||||
|
||||
// Place the popover
|
||||
switch (placement) {
|
||||
case 'bottom':
|
||||
styles.top = offset.top + height;
|
||||
break;
|
||||
case 'right':
|
||||
styles.left = offset.left + width;
|
||||
break;
|
||||
case 'top':
|
||||
styles.top = offset.top - popover.outerHeight();
|
||||
break;
|
||||
case 'left':
|
||||
styles.left = offset.left - popover.outerWidth();
|
||||
break;
|
||||
}
|
||||
|
||||
// Align the popover arrow
|
||||
switch (align) {
|
||||
case 'left':
|
||||
styles.left = offset.left;
|
||||
break;
|
||||
case 'right':
|
||||
styles.left = offset.left + width - popover.outerWidth();
|
||||
break;
|
||||
case 'top':
|
||||
styles.top = offset.top;
|
||||
break;
|
||||
case 'bottom':
|
||||
styles.top = offset.top + height - popover.outerHeight();
|
||||
break;
|
||||
}
|
||||
|
||||
popover.css(styles);
|
||||
};
|
||||
|
||||
// Show popover
|
||||
ClockPicker.prototype.show = function(e){
|
||||
// Not show again
|
||||
if (this.isShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
raiseCallback(this.options.beforeShow);
|
||||
|
||||
var self = this;
|
||||
|
||||
// Initialize
|
||||
if (! this.isAppended) {
|
||||
// Append popover to body
|
||||
$body = $(document.body).append(this.popover);
|
||||
|
||||
// Reset position when resize
|
||||
$win.on('resize.clockpicker' + this.id, function(){
|
||||
if (self.isShown) {
|
||||
self.locate();
|
||||
}
|
||||
});
|
||||
|
||||
this.isAppended = true;
|
||||
}
|
||||
|
||||
// Get the time
|
||||
var value = ((this.input.prop('value') || this.options['default'] || '') + '').split(':');
|
||||
if (value[0] === 'now') {
|
||||
var now = new Date(+ new Date() + this.options.fromnow);
|
||||
value = [
|
||||
now.getHours(),
|
||||
now.getMinutes()
|
||||
];
|
||||
}
|
||||
this.hours = + value[0] || 0;
|
||||
this.minutes = + value[1] || 0;
|
||||
this.spanHours.html(leadingZero(this.hours));
|
||||
this.spanMinutes.html(leadingZero(this.minutes));
|
||||
|
||||
// Toggle to hours view
|
||||
this.toggleView('hours');
|
||||
|
||||
// Set position
|
||||
this.locate();
|
||||
|
||||
this.isShown = true;
|
||||
|
||||
// Hide when clicking or tabbing on any element except the clock, input and addon
|
||||
$doc.on('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id, function(e){
|
||||
var target = $(e.target);
|
||||
if (target.closest(self.popover).length === 0 &&
|
||||
target.closest(self.addon).length === 0 &&
|
||||
target.closest(self.input).length === 0) {
|
||||
self.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Hide when ESC is pressed
|
||||
$doc.on('keyup.clockpicker.' + this.id, function(e){
|
||||
if (e.keyCode === 27) {
|
||||
self.hide();
|
||||
}
|
||||
});
|
||||
|
||||
raiseCallback(this.options.afterShow);
|
||||
};
|
||||
|
||||
// Hide popover
|
||||
ClockPicker.prototype.hide = function(){
|
||||
raiseCallback(this.options.beforeHide);
|
||||
|
||||
this.isShown = false;
|
||||
|
||||
// Unbinding events on document
|
||||
$doc.off('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id);
|
||||
$doc.off('keyup.clockpicker.' + this.id);
|
||||
|
||||
this.popover.hide();
|
||||
|
||||
raiseCallback(this.options.afterHide);
|
||||
};
|
||||
|
||||
// Toggle to hours or minutes view
|
||||
ClockPicker.prototype.toggleView = function(view, delay){
|
||||
var raiseAfterHourSelect = false;
|
||||
if (view === 'minutes' && $(this.hoursView).css("visibility") === "visible") {
|
||||
raiseCallback(this.options.beforeHourSelect);
|
||||
raiseAfterHourSelect = true;
|
||||
}
|
||||
var isHours = view === 'hours',
|
||||
nextView = isHours ? this.hoursView : this.minutesView,
|
||||
hideView = isHours ? this.minutesView : this.hoursView;
|
||||
|
||||
this.currentView = view;
|
||||
|
||||
this.spanHours.toggleClass('text-primary', isHours);
|
||||
this.spanMinutes.toggleClass('text-primary', ! isHours);
|
||||
|
||||
// Let's make transitions
|
||||
hideView.addClass('clockpicker-dial-out');
|
||||
nextView.css('visibility', 'visible').removeClass('clockpicker-dial-out');
|
||||
|
||||
// Reset clock hand
|
||||
this.resetClock(delay);
|
||||
|
||||
// After transitions ended
|
||||
clearTimeout(this.toggleViewTimer);
|
||||
this.toggleViewTimer = setTimeout(function(){
|
||||
hideView.css('visibility', 'hidden');
|
||||
}, duration);
|
||||
|
||||
if (raiseAfterHourSelect) {
|
||||
raiseCallback(this.options.afterHourSelect);
|
||||
}
|
||||
};
|
||||
|
||||
// Reset clock hand
|
||||
ClockPicker.prototype.resetClock = function(delay){
|
||||
var view = this.currentView,
|
||||
value = this[view],
|
||||
isHours = view === 'hours',
|
||||
unit = Math.PI / (isHours ? 6 : 30),
|
||||
radian = value * unit,
|
||||
radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius,
|
||||
x = Math.sin(radian) * radius,
|
||||
y = - Math.cos(radian) * radius,
|
||||
self = this;
|
||||
if (svgSupported && delay) {
|
||||
self.canvas.addClass('clockpicker-canvas-out');
|
||||
setTimeout(function(){
|
||||
self.canvas.removeClass('clockpicker-canvas-out');
|
||||
self.setHand(x, y);
|
||||
}, delay);
|
||||
} else {
|
||||
this.setHand(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
// Set clock hand to (x, y)
|
||||
ClockPicker.prototype.setHand = function(x, y, roundBy5, dragging){
|
||||
var radian = Math.atan2(x, - y),
|
||||
isHours = this.currentView === 'hours',
|
||||
unit = Math.PI / (isHours || roundBy5 ? 6 : 30),
|
||||
z = Math.sqrt(x * x + y * y),
|
||||
options = this.options,
|
||||
inner = isHours && z < (outerRadius + innerRadius) / 2,
|
||||
radius = inner ? innerRadius : outerRadius,
|
||||
value;
|
||||
|
||||
if (options.twelvehour) {
|
||||
radius = outerRadius;
|
||||
}
|
||||
|
||||
// Radian should in range [0, 2PI]
|
||||
if (radian < 0) {
|
||||
radian = Math.PI * 2 + radian;
|
||||
}
|
||||
|
||||
// Get the round value
|
||||
value = Math.round(radian / unit);
|
||||
|
||||
// Get the round radian
|
||||
radian = value * unit;
|
||||
|
||||
// Correct the hours or minutes
|
||||
if (options.twelvehour) {
|
||||
if (isHours) {
|
||||
if (value === 0) {
|
||||
value = 12;
|
||||
}
|
||||
} else {
|
||||
if (roundBy5) {
|
||||
value *= 5;
|
||||
}
|
||||
if (value === 60) {
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isHours) {
|
||||
if (value === 12) {
|
||||
value = 0;
|
||||
}
|
||||
value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12;
|
||||
} else {
|
||||
if (roundBy5) {
|
||||
value *= 5;
|
||||
}
|
||||
if (value === 60) {
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Once hours or minutes changed, vibrate the device
|
||||
if (this[this.currentView] !== value) {
|
||||
if (vibrate && this.options.vibrate) {
|
||||
// Do not vibrate too frequently
|
||||
if (! this.vibrateTimer) {
|
||||
navigator[vibrate](10);
|
||||
this.vibrateTimer = setTimeout($.proxy(function(){
|
||||
this.vibrateTimer = null;
|
||||
}, this), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this[this.currentView] = value;
|
||||
this[isHours ? 'spanHours' : 'spanMinutes'].html(leadingZero(value));
|
||||
|
||||
// If svg is not supported, just add an active class to the tick
|
||||
if (! svgSupported) {
|
||||
this[isHours ? 'hoursView' : 'minutesView'].find('.clockpicker-tick').each(function(){
|
||||
var tick = $(this);
|
||||
tick.toggleClass('active', value === + tick.html());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Place clock hand at the top when dragging
|
||||
if (dragging || (! isHours && value % 5)) {
|
||||
this.g.insertBefore(this.hand, this.bearing);
|
||||
this.g.insertBefore(this.bg, this.fg);
|
||||
this.bg.setAttribute('class', 'clockpicker-canvas-bg clockpicker-canvas-bg-trans');
|
||||
} else {
|
||||
// Or place it at the bottom
|
||||
this.g.insertBefore(this.hand, this.bg);
|
||||
this.g.insertBefore(this.fg, this.bg);
|
||||
this.bg.setAttribute('class', 'clockpicker-canvas-bg');
|
||||
}
|
||||
|
||||
// Set clock hand and others' position
|
||||
var cx = Math.sin(radian) * radius,
|
||||
cy = - Math.cos(radian) * radius;
|
||||
this.hand.setAttribute('x2', cx);
|
||||
this.hand.setAttribute('y2', cy);
|
||||
this.bg.setAttribute('cx', cx);
|
||||
this.bg.setAttribute('cy', cy);
|
||||
this.fg.setAttribute('cx', cx);
|
||||
this.fg.setAttribute('cy', cy);
|
||||
};
|
||||
|
||||
// Hours and minutes are selected
|
||||
ClockPicker.prototype.done = function() {
|
||||
raiseCallback(this.options.beforeDone);
|
||||
this.hide();
|
||||
var last = this.input.prop('value'),
|
||||
value = leadingZero(this.hours) + ':' + leadingZero(this.minutes);
|
||||
if (this.options.twelvehour) {
|
||||
value = value + this.amOrPm;
|
||||
}
|
||||
|
||||
this.input.prop('value', value);
|
||||
if (value !== last) {
|
||||
this.input.triggerHandler('change');
|
||||
if (! this.isInput) {
|
||||
this.element.trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.autoclose) {
|
||||
this.input.trigger('blur');
|
||||
}
|
||||
|
||||
raiseCallback(this.options.afterDone);
|
||||
};
|
||||
|
||||
// Remove clockpicker from input
|
||||
ClockPicker.prototype.remove = function() {
|
||||
this.element.removeData('clockpicker');
|
||||
this.input.off('focus.clockpicker click.clockpicker');
|
||||
this.addon.off('click.clockpicker');
|
||||
if (this.isShown) {
|
||||
this.hide();
|
||||
}
|
||||
if (this.isAppended) {
|
||||
$win.off('resize.clockpicker' + this.id);
|
||||
this.popover.remove();
|
||||
}
|
||||
};
|
||||
|
||||
// Extends $.fn.clockpicker
|
||||
$.fn.clockpicker = function(option){
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return this.each(function(){
|
||||
var $this = $(this),
|
||||
data = $this.data('clockpicker');
|
||||
if (! data) {
|
||||
var options = $.extend({}, ClockPicker.DEFAULTS, $this.data(), typeof option == 'object' && option);
|
||||
$this.data('clockpicker', new ClockPicker($this, options));
|
||||
} else {
|
||||
// Manual operatsions. show, hide, remove, e.g.
|
||||
if (typeof data[option] === 'function') {
|
||||
data[option].apply(data, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}());
|
||||
Reference in New Issue
Block a user