I’ve been mucking around with directives for that last few days and one of my requirements has been a simple timepicker. Nothing too fancy, but if anyone would like to use it – feel free.
The hours and minutes will then be updated whenever the user changes the value. If you need any other hooks it’s fairly easy to modify and there are a heap of comments.
You may also want to put the HTML in an external template. Just make the following changes to the directive (note templateURL):
The JSFiddle is probably the easiest way to see how it all works. You can simply copy it from there to your app. Alternatively, I’ve dumped the code below:
Uncondensed HTML (for those who prefer to use a template)
{{displayHours()}}
{{displayMinutes()}}
= 12" class="display">
PM
<div ng-if="hours
AM
Timepicker Directive
/*
http://www.whatibroke.com/?p=899
*/
var app = angular.module('myApp', []);
app.controller("MyCtrl", function MyCtrl($scope) {
$scope.hours = 11;
$scope.minutes = 45;
});
app.directive("ngTimeSelector", function () {
return {
restrict: 'EA',
template: '
{{displayHours()}}
{{displayMinutes()}}
= 12" class="display"> PM
<div ng-if="hours AM
',
scope: {
hours: "=",
minutes: "="
},
replace: true,
link: function (scope, elem, attr) {
//Create vars
scope.period = "AM";
/* Increases hours by one */
scope.increaseHours = function () {
//Check whether hours have reached max
if (scope.hours < 23) {
scope.hours = ++scope.hours;
}
else {
scope.hours = 0;
}
}
/* Decreases hours by one */
scope.decreaseHours = function () {
//Check whether hours have reached min
scope.hours = scope.hours = 59) {
scope.minutes = 0;
}
else {
scope.minutes++;
}
}
/* Decreases minutes by one */
scope.decreaseMinutes = function () {
//Check whether to reset
if (scope.minutes 12) {
hoursToDisplay = scope.hours - 12;
}
//Check for 12 AM etc
if (hoursToDisplay == 0) {
//Set to am and display 12
hoursToDisplay = 12;
}
else {
//Check whether to prepend 0
if (hoursToDisplay <= 9) {
hoursToDisplay = "0" + hoursToDisplay;
}
}
return hoursToDisplay;
}
/* Displays minutes */
scope.displayMinutes = function () {
return scope.minutes = 12 ? scope.hours - 12 : scope.hours + 12;
}
}
}
});
I ran into a bit of trouble today trying to get datetimepicker to work within bootstrap tabs. The dialog appeared however none of the buttons seemed to work. The fields also remained unpopulated.
It turned out the the issue was caused by the fact that I’d used jquery’s clone function to duplicate the tabs without reassigning field ids. This meant that there were multiple fields with the same id, confusing datetimepicker.
The solution I used was to dynamically assign all of the ids as each tab was displayed:
/* Bind tab change events: this has been done so that there is less js overhead */
function bind_tab_change_events(){
//Bind change event
$('.nav-tabs').bind('show', function(e){
//Create vars
var selected_file_id = $(e.target).data('file_id');
//Initialisations
initialise_time_pickers('#file_' + selected_file_id + ' .timepicker', selected_file_id);
})
}
/* Initalise timepickers */
function initialise_time_pickers(selector, unique_id){
//Loop through each bound element
$.each($(selector), function(index, value){
//Set id - datepicker won't work without unique ids
$(value).attr('id', $(value).attr('id') + '_' + unique_id);
//Initialise datepicker
$(value).datetimepicker();
});
}
UPDATE:
It looks like quite a few people hitting this post are looking for a bootstrap specific alternative, Sebastien has provided a link to one in the comments below: Bootstrap DatetimePicker.