diff --git a/src/timepicker/test/timepicker.spec.js b/src/timepicker/test/timepicker.spec.js index 1b83df5d0f..8a8cac4768 100644 --- a/src/timepicker/test/timepicker.spec.js +++ b/src/timepicker/test/timepicker.spec.js @@ -1271,6 +1271,29 @@ describe('timepicker directive', function() { expect(element.hasClass('ng-invalid-time')).toBe(false); }); + it('should not be invalid when the model is cleared', function() { + var elH = getHoursInputEl(); + var elM = getMinutesInputEl(); + var elS = getSecondsInputEl(); + + $rootScope.time = newTime(10, 20, 30); + $rootScope.$digest(); + + expect(getModelState()).toEqual([10, 20, 30]); + + changeInputValueTo(elH, ''); + elH.blur(); + $rootScope.$digest(); + changeInputValueTo(elM, ''); + elM.blur(); + $rootScope.$digest(); + changeInputValueTo(elS, ''); + elS.blur(); + $rootScope.$digest(); + + expect(element.hasClass('ng-invalid-time')).toBe(false); + }); + it('timepicker1 leaves view alone when hours are invalid and minutes are updated', function() { var hoursEl = getHoursInputEl(), minutesEl = getMinutesInputEl(); diff --git a/src/timepicker/timepicker.js b/src/timepicker/timepicker.js index 6a6171d2eb..8c62024a1c 100644 --- a/src/timepicker/timepicker.js +++ b/src/timepicker/timepicker.js @@ -166,7 +166,7 @@ angular.module('ui.bootstrap.timepicker', []) var hours = +$scope.hours; var valid = $scope.showMeridian ? hours > 0 && hours < 13 : hours >= 0 && hours < 24; - if (!valid) { + if (!valid || $scope.hours === '') { return undefined; } @@ -183,7 +183,11 @@ angular.module('ui.bootstrap.timepicker', []) function getMinutesFromTemplate() { var minutes = +$scope.minutes; - return minutes >= 0 && minutes < 60 ? minutes : undefined; + var valid = minutes >= 0 && minutes < 60; + if (!valid || $scope.minutes === '') { + return undefined; + } + return minutes; } function getSecondsFromTemplate() { @@ -323,7 +327,9 @@ angular.module('ui.bootstrap.timepicker', []) hoursInputEl.bind('blur', function(e) { ngModelCtrl.$setTouched(); - if ($scope.hours === null || $scope.hours === '') { + if (modelIsEmpty()) { + makeValid(); + } else if ($scope.hours === null || $scope.hours === '') { invalidate(true); } else if (!$scope.invalidHours && $scope.hours < 10) { $scope.$apply(function() { @@ -353,7 +359,9 @@ angular.module('ui.bootstrap.timepicker', []) minutesInputEl.bind('blur', function(e) { ngModelCtrl.$setTouched(); - if ($scope.minutes === null) { + if (modelIsEmpty()) { + makeValid(); + } else if ($scope.minutes === null) { invalidate(undefined, true); } else if (!$scope.invalidMinutes && $scope.minutes < 10) { $scope.$apply(function() { @@ -376,7 +384,9 @@ angular.module('ui.bootstrap.timepicker', []) }; secondsInputEl.bind('blur', function(e) { - if (!$scope.invalidSeconds && $scope.seconds < 10) { + if (modelIsEmpty()) { + makeValid(); + } else if (!$scope.invalidSeconds && $scope.seconds < 10) { $scope.$apply( function() { $scope.seconds = pad($scope.seconds); }); @@ -465,6 +475,12 @@ angular.module('ui.bootstrap.timepicker', []) return newDate; } + function modelIsEmpty() { + return ($scope.hours === null || $scope.hours === '') && + ($scope.minutes === null || $scope.minutes === '') && + (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === '')); + } + $scope.showSpinners = angular.isDefined($attrs.showSpinners) ? $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;