weareoutman / clockpicker Goto Github PK
View Code? Open in Web Editor NEWA clock-style timepicker for Bootstrap (or jQuery). Sorry but no longer maintained.
Home Page: http://weareoutman.github.io/clockpicker/
License: MIT License
A clock-style timepicker for Bootstrap (or jQuery). Sorry but no longer maintained.
Home Page: http://weareoutman.github.io/clockpicker/
License: MIT License
Hi, i would fixed a step 5 by 5 min , like the minute on the display not between like 16min or 54 just 05-00-05-10-15-20-25-30-35-40-45-50-55-. I search in jquery.clockpicker-min.js but its hard; If anybody know how//
i have check he other post on 30 minute step and doesb't run for me
Thanks
You have appended meridiem(AM/PM) with the time without a separator. So, I want to add space between time and meridiem. Can I use BeforeDone/AfterDone events and if yes, how to use? if not, how can I add separator?
Thanks
Use some tablet or smartphone with touchscreen
Open picker first time, use drug and drop functionality to choose the time
After choosing minutes it is automatically closed
Open picker one more time
Expected result: it is opened
Actual result: It is opened for a second but then closed without any reason
If I bind something to beforeShow and afterHide, the events do not get triggered when opening the clockpicker via the clockpicker("show")
command (In my usecase, I have a separate clock icon that also toggles the picker).
Automatically outputs PM.
var input = $('#time');
input.clockpicker({
autoclose: true,
twelvehour: true
});
Seems one can only have autoclose OR the "done" button, but not both, I'd love to have both.
When using the "Done" button, clicking out of the clockpicker closes it without setting the time selected
Hello there, and thank you for this nice script.
We want to use it into one of our projects, but we really need to limit minutes selection to "00" and "30", and disallow any other selection.
Can this be achieved with your code? If not, any advice of where should we take a look?
Thank you in advanced for your help.
hi, i made the input as read only but when a user want to rest the time to blank or none it's not possible so i suggest a reset button beside the validation button
thank you
Is there an option to disable mobile device native keyboard support for the input fields?
I noticed when setting the default value to a time with AM or PM, with twelvehour=true, it wouldn't get reflected in the popup title or button focus. So I added that functionality.
I don't know how to post that in Github, so I'm just going to post it here if you want to add it or if anyone needs it.
; (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('');
function AmOrPm(v) {
if (!v)
return "PM";
if (v.toUpperCase().indexOf("AM") != -1)
return "AM";
if (v.toUpperCase().indexOf("PM") != -1)
return "PM";
return "PM";
}
// 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'] || '') + '');
this.amOrPm = AmOrPm(value);
value = value.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));
if (this.options.twelvehour)
this.spanAmPm.html(this.amOrPm);
// 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 _this = this;
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 () {
if (_this.options.twelvehour)
nextView.parents(".popover-content").find("." + _this.amOrPm.toLowerCase() + "-button").focus();
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 operations. show, hide, remove, e.g.
if (typeof data[option] === 'function') {
data[option].apply(data, args);
}
}
});
};
}());
You could add a readonly property as a clockpicker option like this;:
Options
Name Default Description
readonly false (true, flase)
and then the plugin add automatically this property in input tag:
On your landing page : http://weareoutman.github.io/clockpicker/
https://github.com/weareoutman/clockpicker/archive/master.zip
Should be
https://github.com/weareoutman/clockpicker/archive/gh-pages.zip
Anyway your plugin looks great, thanks for the work!
The current output of the time presentation and the way to retrieve it ($('input.clockpicker').val()), is not always useful. Especially when using 12-hour notation, it forces me to write complex functions to convert it.
A way to get the time as an offset (e.g. seconds from midnite) would be useful. So, '10:00' would give us '36000' (or even in millisecs like '36000000'). This way, it can be easily used in calculations.
Would be nice if I could just do npm install bootstrap-clockpicker
.
You need to add a "main" entry to the package.json that points to the bootstrap-clockpicker source, and then use npm publish
to push it to npm
Hi, sorry if this is the wrong place to ask this but is it possible to set the minutes to display 0 15 30 45 only? I've found where I can set this for the display but when dragging it still goes up by 1 minute as you drag, would like it to snap to 0 15 30 45.
Hope that makes sense :)
Rich
Could this be added to current todos, please? :) I am used to that from Angular - one data source for both date and time picker - one date object.
I'm a newbie and using this in an MVC project. In a "Create" view I have used two fields as clockPicker (start and end time). First one works like a charm but the second one does not function.
I do not know if this is the right place to bring this up. Here's my code in Create view:
@Html.EditorFor(model => model.StringStartTime, new { htmlAttributes = new { @Class = "form-control clockPicker", id = "single-input", value = "", placeholder = "اکنون" } })
@Html.EditorFor(model => model.StringEndTime, new { htmlAttributes = new { @Class = "form-control clockPicker", id = "single-input", value = "", placeholder = "اکنون" } })
Hi,
I needed a feature where I wanted to let the timepicker submit on clicking on AM/PM rather than the minute hands. Since it seems like the owner of the project has been inactive for quite some time I thought I would fork the project myself and implement the feature. It didn't take much time really (just a couple of minutes).
I thought it might help someone else who is in search of similar functionality. You'll find the functionality on my fork - https://github.com/rishabhp/clockpicker
My fork is a fork of https://github.com/JordyMoos/clockpicker which has several other interesting features like hours and minute steps (really needed that in my project). I've even opened a PR on that project for this same functionality that I implemented JordyMoos#2
Hope that'll help someone else in search of true enlightenment!
nor click nor drag works in canary 36. can anyone confirm?
How can we add min hours and min time between two time pickers , like start time and end time. The end time should not before of the start time
Is there any possibility to set model value to be "Invalid" if a user types in textbox with any invalid time format?
I would like to choose the layout of the clock to show only 12 hours, 24 hours or both (like it's done), I'm going to fork it If I can make an workaround
Military time is not confusing, but this clock's implementation is.
The inner circle (morning) goes from 1-12. The outer circle (eveining) goes from 00 to 23.
Where would you logically click to select 12:30 in the afternoon? Try it.
Clicking the 12 sets the clock to AM. This is wrong. In military time, 12 is noon. Always.
The inner circle should start with 00 at the top, and go up to 11. The OUTER circle should start at 12 at the top and go to 23.
Where should one click for 'Midnight' is a logical question. Do you click on the top of the OUTER circle (the end of the day), or do you click on the top of the INNER circle (the start of the day)? I'm modifying the clock so that 00 is on the inside, and that is where you would click for midnight.
Change one: Move 12 to the outer circle, and 00 to the inner circle:
// Near line 185 of jquery-clickpicker.js
var inner = i > 0 && i < 13; // Old line
var inner = i >= 0 && i < 12; // New line
Change two: Correct the 'Radius =' line for inner/outer.
// Near line 548 of jquery-clockpicker.js
radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius, // old
radius = isHours && value >= 0 && value < 12 ? innerRadius : outerRadius, // new
Change three: Correct the detection of the swap of 00 and 12.
// Near line 600 of jquery-clockpicker.js
// ----- "if (isHours)" section. --------
// Replace the three IF statements, with the below statements.
if (! options.twelvehour ) {
if (inner && value === 12 ) {
value = 0;
}
if (! inner && value === 0 ) {
value = 12;
}
if (! inner && value < 12 ) {
value += 12;
}
}
if (options.twelvehour && value === 0) {
value = 12;
}
if (value === 24) {
value = 0;
}
Is it possible the add a property like "enableNowButton" and when is true, it will be visible in the tooltip?
Furthermore the AM/PM buttons could be using Bootstraps button group and the AM/PM button acts as a toggle buttons.
Here is two previews of how it could look:
if twelvehour is false the AM/PM buttons are hidden, but still you could choose to use the "now" button.
Hey,
I installed the clockpicker via bower and the version is not the same as the one in the zip file. I.e. I can't use events with the bower version. Is this planned to be updated?
Thanks
Please implement more events with options extending.
For example:
I need an function after function done, I extended, but now I need to merge with you.
As for me it would be great to has functions like:
init, beforeShow, afterShow, beforeDone, afterDone, beforeHourSelect, afterHourSelect
then your plugin will be more flexible. thanks.
Hi.
I would like to have two visible clockpickers concurrently.
inputa.clockpicker().clockpicker("show");
inputb.clockpicker().clockpicker("show");
The problem is that when you click on one, the other one dissapears.
How can I disable hours ? (ex from(18:00) To (08:00) )
It'd be so great to have this plugin managed by bower ;)
Hi,
So if we just select an hour, the clock will display eg. '13:00', and if we click outside the overlay, the value will not be taken into account.
I think it should either display '13:__' to make obvious that minutes need to be selected, or valid the fact that minutes default to 00 without user action.
What do you think?
I tested your picker and find it very nice.
Is it planned to use the clockpicker inline in a form, and not in a bootstrap popover. I would like to use it directly in a bootstrap modal.
Thank you in advance !
When the option "twelvehour" = true, the text "AM"/"PM" is added to the output string.
This is great for TEXT inputs, but does not work for TIME inputs. TIME inputs expect a value in the format of HH:MM:SS.
The easiest way to account for this is down in the "ClockPicker.prototype.done" function:
Hi, after drive me crazy trying to understand why afterShow
does not trigger on the options. I checked the code on master
vs release 0.0.7
, and this tag, does not have this option.
Idk if is missing other options, plz, re release the tag 0.0.7 to match the current documentation with the api.
Hello. Is there any way to set / restrict the minutes to a certain increment? For example, to set an increment of "5" would only allow the minutes selection to be 0, 5, 10, 15.... As it is now, one can click and drag around the clock face for the minutes and select any minute.
only happens in 12 hour mode true.
when time is 11:12AM the popup starts at 11:00AM would like it to start with 11:12AM.
Very nice plugin by the way !
Is it possible to disable hours and minutes choices that are in the past ( e.x. from now and below ) ?
clock picker can't displaying inside bootstrap modal popup window, it showing modal overlay behind..
Try to use :
.popover {
z-index: 215000000 !important;
}
let options =
{
donetext : 'Done',
placement: 'top',
align: 'left'
}
$('.clockpicker').clockpicker(options);
Hello,
The plugin is very nice and easy to us it
i want to compare two times (range) and i dont found the solution for this
for example : the restaurant manager put two times : open and close , i must verify if time close is bigger then time open
thank's
For example, if autoclose
is on, when you selected a time, a focus is left in the input. If you click the input again, nothing happens. You have to remove focus manually (click somewhere out of the input) to make it work.
Seems like onclick
does not toggle popup at all. Only onfocus
works.
The clockpicker is an excellent implementation to select a time value. And yes, the normal way would be to have an element. That way the current clockpicker is fine, but with my project I need a button to trigger the clockpicker but without an <input> element, example (partial html code)
<div class="btn-group"> <!-- ON -->
<button class="btn btn-default btn-sm dropdown-toggle clockpicker-with-callbacks" type="button"
id="ON"
data-toggle="dropdown" aria-expanded="false">
{{ON}} -- <span class="caret"></span>
</button>
This works with callbacks and the clockpicker is tied to the button with the id "ON".
So the preset time value for the clockpicker has to be passed somehow.
To extend the clockpicker for that -- and not change the standard behavior -- was a very easy job with just a few lines of the clockpicker.js code and a specific calling sequence like this:
$('#ON').clockpicker()
.clockpicker('show',{
'current': setON
});
To get the time value selected with the clockpicker a "return time value" is passed with a modified callback like this:
var clockInput = $('.clockpicker-with-callbacks').clockpicker({
afterDone: function(timeValue) {
.... code to process timeValue ...
}
});
The required clockpicker.js code changes can be found with a pull request with the same title.
Would be great to include it with the standard code base.
Thanks.
Is there an angular directive in existence that will load this jquery plugin.
When Clockpicker placed inside "Modal" control, user can't change time value. Dropdown with dial shows correct, user can select new hour and minute, selected values are show in dropdown, But, after click on 'Done' button - nothing changes in input text.
Error occurs only in IE10.
UPD: it's possible to change editor's value, when 'autoclose' option set to 'true'. If 'autoclose' option not set (or set to 'false' explicit), user can't change editor's value
I tried using data-placement="bottom" data-align="left"
and I tried using jquery $('.clockpicker').clockpicker({ placement: 'bottom', align: 'left' });
Very nice plugin! Just encountered a problem with the bower version (0.0.7). The raiseCallback calls are nowhere to be found in that version. Is that intended?
Is it currently possible to use a 12 hour clock instead of 24 hour?
If it isnt already implemented, perhaps it could be added? Possibly could show an AM
/ PM
next t select time which could be clicked on to toggle between the 2 which in the backend would then convert the PM time to a time great than 12.
For example if you select 2
and PM
it would then save the time as 14
but would show 2
PM
to the user on the clock UI
Below shows the 24 hours clock
Hello,
I tested your clock picker and it's really great !
Is it possible to add seconds, same display than minutes ???
Thanks a lot !
Please add function to select AM/PM after Minutes selection on twelve hour mode.
It would be nice to have typescript typings stored in the usual place DefinitelyTyped on github.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.