TimeSelector / TimePicker Directive - AngularJS
Hey everyone,
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.
See the following fiddle for the demo: http://jsfiddle.net/LFB3F/2/
Image unavailable in the original archive: Timepicker Directive
Timepicker Directive
The directive is initialised with both the hour and minute defaults being set like this:
Note that hours and minutes should be set in the controller that wraps around the Timepicker:
app.controller("MyCtrl", function MyCtrl($scope) {
$scope.hours = 11;
$scope.minutes = 45;
});
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):
app.directive("ngTimeSelector", function () {
return {
restrict: 'EA',
templateUrl: '/Directives/TimeSelector',
scope: {
hours: "=",
minutes: "="
},
replace: true,
link: function (scope, elem, attr) {
...
...
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)
<div class="timeSelectorDirective">
<div class="section hours">
<div class="increase">
<i class="icon fa fa-caret-up"></i>
</div>
<div class="display">
{{displayHours()}}
</div>
<div class="decrease">
<i class="icon fa fa-caret-down"></i>
</div>
</div>
<div class="section minutes">
<div class="increase">
<i class="icon fa fa-caret-up"></i>
</div>
<div class="display">
{{displayMinutes()}}
</div>
<div class="decrease">
<i class="icon fa fa-caret-down"></i>
</div>
</div>
<div class="section hours">
<div class="increase">
<i class="icon fa fa-caret-up"></i>
</div>
<div>= 12" class="display">
PM
</div>
<div ng-if="hours
AM
</div>
<div class="decrease">
<i class="icon fa fa-caret-down"></i>
</div>
</div>
</div>
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: '<div class="timeSelectorDirective"> <div class="section hours"> <div class="increase"> <i class="icon fa fa-caret-up"></i> </div> <div class="display"> {{displayHours()}} </div> <div class="decrease"> <i class="icon fa fa-caret-down"></i> </div> </div> <div class="section minutes"> <div class="increase"> <i class="icon fa fa-caret-up"></i> </div> <div class="display"> {{displayMinutes()}} </div> <div class="decrease"> <i class="icon fa fa-caret-down"></i> </div> </div> <div class="section hours"> <div class="increase"> <i class="icon fa fa-caret-up"></i> </div> <div>= 12" class="display"> PM </div> <div ng-if="hours AM </div> <div class="decrease"> <i class="icon fa fa-caret-down"></i> </div> </div> </div>',
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;
}
}
}
});
Styles
body{
background-color: #F0F0F0;
font-family: "Lato", sans-serif;
font-weight: 300;
color: #363636;
}
.timeSelectorDirective {
background: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.timeSelectorDirective .increase, .timeSelectorDirective .decrease{
text-align: center;
vertical-align: middle;
color: rgb(112, 112, 112);
text-shadow: 0px 1px #FFF;
cursor: pointer;
-webkit-transition: 500ms ease-out all;
-moz-transition: 500ms ease-out all;
-ms-transition: 500ms ease-out all;
-o-transition: 500ms ease-out all;
transition: 500ms ease-out all;
font-size: 100%;
border: 1px solid #CCC;
padding: 3px;
margin: 3px;
border: 1px solid #EDE;
}
.timeSelectorDirective .increase:hover, .timeSelectorDirective .decrease:hover{
color: rgba(112, 112, 112, 0.5);
border-color: #CCC;
background-color: #FFF;
}
.timeSelectorDirective .increase:active, .timeSelectorDirective .decrease:active{
color: rgb(112, 112, 112);
box-shadow: inset 1px 1px 1px #DDD;
}
.timeSelectorDirective .section{
display: inline-block;
}
.timeSelectorDirective .display{
background-color: rgb(247, 247, 247);
color: #555555;
padding: 5px;
margin: 0px 3px;
min-width: 30px;
text-align: center;
border: 1px solid #DDD;
box-shadow: 1px 1px 1px #FFFFFF;
}
Sample Usage
<div>
<h1><a href='http://www.whatibroke.com/?p=899'>www.whatibroke.com</a></h1>
<div style="margin-top:40px;">
<b>Hours: </b>{{hours}}
<b>Minutes: </b>{{minutes}}
</div>
</div>
Misc Includes
AngularJS: http://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js
FontAwesome: http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css
Font: http://fonts.googleapis.com/css?family=Lato:300,300italic,400,700,700italic|Rokkitt:400,700.css