From 97fed98a44a780fc78824ac113edff2a4e46d479 Mon Sep 17 00:00:00 2001 From: Pouyan Savoli Date: Tue, 15 Jul 2014 18:06:18 +0200 Subject: [PATCH] feat(timepicker): added support for seconds --- src/timepicker/test/timepicker.spec.js | 6 +- src/timepicker/timepicker.js | 95 +++++++++++++++++++++----- template/timepicker/timepicker.html | 8 +++ 3 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/timepicker/test/timepicker.spec.js b/src/timepicker/test/timepicker.spec.js index 7958b2d463..3f41e70833 100644 --- a/src/timepicker/test/timepicker.spec.js +++ b/src/timepicker/test/timepicker.spec.js @@ -71,9 +71,9 @@ describe('timepicker directive', function () { return e; } - it('contains three row & three input elements', function() { + it('contains three row & four input elements', function() { expect(element.find('tr').length).toBe(3); - expect(element.find('input').length).toBe(2); + expect(element.find('input').length).toBe(3); expect(element.find('button').length).toBe(1); }); @@ -549,7 +549,7 @@ describe('timepicker directive', function () { }); function getMeridianTd() { - return element.find('tr').eq(1).find('td').eq(3); + return element.find('tr').eq(1).find('td').eq(5); } it('initially displays correct time when `show-meridian` is false', function() { diff --git a/src/timepicker/timepicker.js b/src/timepicker/timepicker.js index 91ac86bcee..15d4a22713 100644 --- a/src/timepicker/timepicker.js +++ b/src/timepicker/timepicker.js @@ -3,7 +3,9 @@ angular.module('ui.bootstrap.timepicker', []) .constant('timepickerConfig', { hourStep: 1, minuteStep: 1, + secondStep: 1, showMeridian: true, + showSeconds: false, meridians: null, readonlyInput: false, mousewheel: true @@ -19,15 +21,16 @@ angular.module('ui.bootstrap.timepicker', []) ngModelCtrl.$render = this.render; var hoursInputEl = inputs.eq(0), - minutesInputEl = inputs.eq(1); + minutesInputEl = inputs.eq(1), + secondsInputEl = inputs.eq(2); var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel; if ( mousewheel ) { - this.setupMousewheelEvents( hoursInputEl, minutesInputEl ); + this.setupMousewheelEvents( hoursInputEl, minutesInputEl, secondsInputEl ); } $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput; - this.setupInputEvents( hoursInputEl, minutesInputEl ); + this.setupInputEvents( hoursInputEl, minutesInputEl, secondsInputEl ); }; var hourStep = timepickerConfig.hourStep; @@ -43,6 +46,13 @@ angular.module('ui.bootstrap.timepicker', []) minuteStep = parseInt(value, 10); }); } + + var secondStep = timepickerConfig.secondStep; + if ($attrs.secondStep) { + $scope.$parent.$watch($parse($attrs.secondStep), function(value) { + secondStep = parseInt(value, 10); + }); + } // 12H / 24H mode $scope.showMeridian = timepickerConfig.showMeridian; @@ -52,9 +62,11 @@ angular.module('ui.bootstrap.timepicker', []) if ( ngModelCtrl.$error.time ) { // Evaluate from template - var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate(); - if (angular.isDefined( hours ) && angular.isDefined( minutes )) { - selected.setHours( hours ); + var hours = getHoursFromTemplate(), + minutes = getMinutesFromTemplate(), + seconds = getSecondsFromTemplate(); + if (angular.isDefined( hours ) && angular.isDefined( minutes ) && angular.isDefined( seconds )) { + selected.setHours( hours, minutes, seconds ); refresh(); } } else { @@ -62,6 +74,12 @@ angular.module('ui.bootstrap.timepicker', []) } }); } + + // Show seconds? + $scope.showSeconds = timepickerConfig.showSeconds; + if ($attrs.showSeconds) { + $scope.showSeconds = !!$attrs.showSeconds; + } // Get $scope.hours in 24H mode if valid function getHoursFromTemplate ( ) { @@ -86,13 +104,18 @@ angular.module('ui.bootstrap.timepicker', []) var minutes = parseInt($scope.minutes, 10); return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined; } + + function getSecondsFromTemplate() { + var seconds = parseInt($scope.seconds, 10); + return ( seconds >= 0 && seconds < 60 ) ? seconds : undefined; + } function pad( value ) { return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value; } // Respond on mousewheel spin - this.setupMousewheelEvents = function( hoursInputEl, minutesInputEl ) { + this.setupMousewheelEvents = function( hoursInputEl, minutesInputEl, secondsInputEl ) { var isScrollingUp = function(e) { if (e.originalEvent) { e = e.originalEvent; @@ -111,17 +134,23 @@ angular.module('ui.bootstrap.timepicker', []) $scope.$apply( (isScrollingUp(e)) ? $scope.incrementMinutes() : $scope.decrementMinutes() ); e.preventDefault(); }); + + secondsInputEl.bind('mousewheel wheel', function(e) { + $scope.$apply( (isScrollingUp(e)) ? $scope.incrementSeconds() : $scope.decrementSeconds() ); + e.preventDefault(); + }); }; - this.setupInputEvents = function( hoursInputEl, minutesInputEl ) { + this.setupInputEvents = function( hoursInputEl, minutesInputEl, secondsInputEl ) { if ( $scope.readonlyInput ) { $scope.updateHours = angular.noop; $scope.updateMinutes = angular.noop; + $scope.updateSeconds = angular.noop; return; } - var invalidate = function(invalidHours, invalidMinutes) { + var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) { ngModelCtrl.$setViewValue( null ); ngModelCtrl.$setValidity('time', false); if (angular.isDefined(invalidHours)) { @@ -130,6 +159,9 @@ angular.module('ui.bootstrap.timepicker', []) if (angular.isDefined(invalidMinutes)) { $scope.invalidMinutes = invalidMinutes; } + if (angular.isDefined(invalidSeconds)) { + $scope.invalidSeconds = invalidSeconds; + } }; $scope.updateHours = function() { @@ -169,6 +201,25 @@ angular.module('ui.bootstrap.timepicker', []) }); } }); + + $scope.updateSeconds = function() { + var seconds = getSecondsFromTemplate(); + + if ( angular.isDefined(seconds) ) { + selected.setSeconds( seconds ); + refresh( 's' ); + } else { + invalidate(undefined, undefined, true); + } + }; + + secondsInputEl.bind('blur', function(e) { + if ( !$scope.invalidSeconds && $scope.seconds < 10 ) { + $scope.$apply( function() { + $scope.seconds = pad( $scope.seconds ); + }); + } + }); }; @@ -198,10 +249,11 @@ angular.module('ui.bootstrap.timepicker', []) ngModelCtrl.$setValidity('time', true); $scope.invalidHours = false; $scope.invalidMinutes = false; + $scope.invalidSeconds = false; } function updateTemplate( keyboardChange ) { - var hours = selected.getHours(), minutes = selected.getMinutes(); + var hours = selected.getHours(), minutes = selected.getMinutes(), seconds = selected.getSeconds(); if ( $scope.showMeridian ) { hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system @@ -209,29 +261,36 @@ angular.module('ui.bootstrap.timepicker', []) $scope.hours = keyboardChange === 'h' ? hours : pad(hours); $scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes); + $scope.seconds = keyboardChange === 's' ? seconds : pad(seconds); $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; } - function addMinutes( minutes ) { - var dt = new Date( selected.getTime() + minutes * 60000 ); - selected.setHours( dt.getHours(), dt.getMinutes() ); + function addSeconds( seconds ) { + var dt = new Date( selected.getTime() + seconds * 1000 ); + selected.setHours( dt.getHours(), dt.getMinutes(), dt.getSeconds() ); refresh(); } $scope.incrementHours = function() { - addMinutes( hourStep * 60 ); + addSeconds( hourStep * 60 * 60 ); }; $scope.decrementHours = function() { - addMinutes( - hourStep * 60 ); + addSeconds( - hourStep * 60 * 60 ); }; $scope.incrementMinutes = function() { - addMinutes( minuteStep ); + addSeconds( minuteStep * 60 ); }; $scope.decrementMinutes = function() { - addMinutes( - minuteStep ); + addSeconds( - minuteStep * 60 ); + }; + $scope.incrementSeconds = function() { + addSeconds( secondStep ); + }; + $scope.decrementSeconds = function() { + addSeconds( - secondStep ); }; $scope.toggleMeridian = function() { - addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) ); + addSeconds( 12 * 60 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) ); }; }]) diff --git a/template/timepicker/timepicker.html b/template/timepicker/timepicker.html index bef8e27f19..6b9ca2595a 100644 --- a/template/timepicker/timepicker.html +++ b/template/timepicker/timepicker.html @@ -4,6 +4,8 @@   +   + @@ -14,12 +16,18 @@ + : + + +   +   +