| @@ 5690-6218 (lines=529) @@ | ||
| 5687 | templateUrl: 'uib/template/timepicker/timepicker.html' |
|
| 5688 | }) |
|
| 5689 | ||
| 5690 | .controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) { |
|
| 5691 | var selected = new Date(), |
|
| 5692 | watchers = [], |
|
| 5693 | ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl |
|
| 5694 | meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS, |
|
| 5695 | padHours = angular.isDefined($attrs.padHours) ? $scope.$parent.$eval($attrs.padHours) : true; |
|
| 5696 | ||
| 5697 | $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0; |
|
| 5698 | $element.removeAttr('tabindex'); |
|
| 5699 | ||
| 5700 | this.init = function(ngModelCtrl_, inputs) { |
|
| 5701 | ngModelCtrl = ngModelCtrl_; |
|
| 5702 | ngModelCtrl.$render = this.render; |
|
| 5703 | ||
| 5704 | ngModelCtrl.$formatters.unshift(function(modelValue) { |
|
| 5705 | return modelValue ? new Date(modelValue) : null; |
|
| 5706 | }); |
|
| 5707 | ||
| 5708 | var hoursInputEl = inputs.eq(0), |
|
| 5709 | minutesInputEl = inputs.eq(1), |
|
| 5710 | secondsInputEl = inputs.eq(2); |
|
| 5711 | ||
| 5712 | var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel; |
|
| 5713 | ||
| 5714 | if (mousewheel) { |
|
| 5715 | this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5716 | } |
|
| 5717 | ||
| 5718 | var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys; |
|
| 5719 | if (arrowkeys) { |
|
| 5720 | this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5721 | } |
|
| 5722 | ||
| 5723 | $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput; |
|
| 5724 | this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5725 | }; |
|
| 5726 | ||
| 5727 | var hourStep = timepickerConfig.hourStep; |
|
| 5728 | if ($attrs.hourStep) { |
|
| 5729 | watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) { |
|
| 5730 | hourStep = +value; |
|
| 5731 | })); |
|
| 5732 | } |
|
| 5733 | ||
| 5734 | var minuteStep = timepickerConfig.minuteStep; |
|
| 5735 | if ($attrs.minuteStep) { |
|
| 5736 | watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) { |
|
| 5737 | minuteStep = +value; |
|
| 5738 | })); |
|
| 5739 | } |
|
| 5740 | ||
| 5741 | var min; |
|
| 5742 | watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) { |
|
| 5743 | var dt = new Date(value); |
|
| 5744 | min = isNaN(dt) ? undefined : dt; |
|
| 5745 | })); |
|
| 5746 | ||
| 5747 | var max; |
|
| 5748 | watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) { |
|
| 5749 | var dt = new Date(value); |
|
| 5750 | max = isNaN(dt) ? undefined : dt; |
|
| 5751 | })); |
|
| 5752 | ||
| 5753 | var disabled = false; |
|
| 5754 | if ($attrs.ngDisabled) { |
|
| 5755 | watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) { |
|
| 5756 | disabled = value; |
|
| 5757 | })); |
|
| 5758 | } |
|
| 5759 | ||
| 5760 | $scope.noIncrementHours = function() { |
|
| 5761 | var incrementedSelected = addMinutes(selected, hourStep * 60); |
|
| 5762 | return disabled || incrementedSelected > max || |
|
| 5763 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5764 | }; |
|
| 5765 | ||
| 5766 | $scope.noDecrementHours = function() { |
|
| 5767 | var decrementedSelected = addMinutes(selected, -hourStep * 60); |
|
| 5768 | return disabled || decrementedSelected < min || |
|
| 5769 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5770 | }; |
|
| 5771 | ||
| 5772 | $scope.noIncrementMinutes = function() { |
|
| 5773 | var incrementedSelected = addMinutes(selected, minuteStep); |
|
| 5774 | return disabled || incrementedSelected > max || |
|
| 5775 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5776 | }; |
|
| 5777 | ||
| 5778 | $scope.noDecrementMinutes = function() { |
|
| 5779 | var decrementedSelected = addMinutes(selected, -minuteStep); |
|
| 5780 | return disabled || decrementedSelected < min || |
|
| 5781 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5782 | }; |
|
| 5783 | ||
| 5784 | $scope.noIncrementSeconds = function() { |
|
| 5785 | var incrementedSelected = addSeconds(selected, secondStep); |
|
| 5786 | return disabled || incrementedSelected > max || |
|
| 5787 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5788 | }; |
|
| 5789 | ||
| 5790 | $scope.noDecrementSeconds = function() { |
|
| 5791 | var decrementedSelected = addSeconds(selected, -secondStep); |
|
| 5792 | return disabled || decrementedSelected < min || |
|
| 5793 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5794 | }; |
|
| 5795 | ||
| 5796 | $scope.noToggleMeridian = function() { |
|
| 5797 | if (selected.getHours() < 12) { |
|
| 5798 | return disabled || addMinutes(selected, 12 * 60) > max; |
|
| 5799 | } |
|
| 5800 | ||
| 5801 | return disabled || addMinutes(selected, -12 * 60) < min; |
|
| 5802 | }; |
|
| 5803 | ||
| 5804 | var secondStep = timepickerConfig.secondStep; |
|
| 5805 | if ($attrs.secondStep) { |
|
| 5806 | watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) { |
|
| 5807 | secondStep = +value; |
|
| 5808 | })); |
|
| 5809 | } |
|
| 5810 | ||
| 5811 | $scope.showSeconds = timepickerConfig.showSeconds; |
|
| 5812 | if ($attrs.showSeconds) { |
|
| 5813 | watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) { |
|
| 5814 | $scope.showSeconds = !!value; |
|
| 5815 | })); |
|
| 5816 | } |
|
| 5817 | ||
| 5818 | // 12H / 24H mode |
|
| 5819 | $scope.showMeridian = timepickerConfig.showMeridian; |
|
| 5820 | if ($attrs.showMeridian) { |
|
| 5821 | watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) { |
|
| 5822 | $scope.showMeridian = !!value; |
|
| 5823 | ||
| 5824 | if (ngModelCtrl.$error.time) { |
|
| 5825 | // Evaluate from template |
|
| 5826 | var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate(); |
|
| 5827 | if (angular.isDefined(hours) && angular.isDefined(minutes)) { |
|
| 5828 | selected.setHours(hours); |
|
| 5829 | refresh(); |
|
| 5830 | } |
|
| 5831 | } else { |
|
| 5832 | updateTemplate(); |
|
| 5833 | } |
|
| 5834 | })); |
|
| 5835 | } |
|
| 5836 | ||
| 5837 | // Get $scope.hours in 24H mode if valid |
|
| 5838 | function getHoursFromTemplate() { |
|
| 5839 | var hours = +$scope.hours; |
|
| 5840 | var valid = $scope.showMeridian ? hours > 0 && hours < 13 : |
|
| 5841 | hours >= 0 && hours < 24; |
|
| 5842 | if (!valid || $scope.hours === '') { |
|
| 5843 | return undefined; |
|
| 5844 | } |
|
| 5845 | ||
| 5846 | if ($scope.showMeridian) { |
|
| 5847 | if (hours === 12) { |
|
| 5848 | hours = 0; |
|
| 5849 | } |
|
| 5850 | if ($scope.meridian === meridians[1]) { |
|
| 5851 | hours = hours + 12; |
|
| 5852 | } |
|
| 5853 | } |
|
| 5854 | return hours; |
|
| 5855 | } |
|
| 5856 | ||
| 5857 | function getMinutesFromTemplate() { |
|
| 5858 | var minutes = +$scope.minutes; |
|
| 5859 | var valid = minutes >= 0 && minutes < 60; |
|
| 5860 | if (!valid || $scope.minutes === '') { |
|
| 5861 | return undefined; |
|
| 5862 | } |
|
| 5863 | return minutes; |
|
| 5864 | } |
|
| 5865 | ||
| 5866 | function getSecondsFromTemplate() { |
|
| 5867 | var seconds = +$scope.seconds; |
|
| 5868 | return seconds >= 0 && seconds < 60 ? seconds : undefined; |
|
| 5869 | } |
|
| 5870 | ||
| 5871 | function pad(value, noPad) { |
|
| 5872 | if (value === null) { |
|
| 5873 | return ''; |
|
| 5874 | } |
|
| 5875 | ||
| 5876 | return angular.isDefined(value) && value.toString().length < 2 && !noPad ? |
|
| 5877 | '0' + value : value.toString(); |
|
| 5878 | } |
|
| 5879 | ||
| 5880 | // Respond on mousewheel spin |
|
| 5881 | this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5882 | var isScrollingUp = function(e) { |
|
| 5883 | if (e.originalEvent) { |
|
| 5884 | e = e.originalEvent; |
|
| 5885 | } |
|
| 5886 | //pick correct delta variable depending on event |
|
| 5887 | var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY; |
|
| 5888 | return e.detail || delta > 0; |
|
| 5889 | }; |
|
| 5890 | ||
| 5891 | hoursInputEl.bind('mousewheel wheel', function(e) { |
|
| 5892 | if (!disabled) { |
|
| 5893 | $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours()); |
|
| 5894 | } |
|
| 5895 | e.preventDefault(); |
|
| 5896 | }); |
|
| 5897 | ||
| 5898 | minutesInputEl.bind('mousewheel wheel', function(e) { |
|
| 5899 | if (!disabled) { |
|
| 5900 | $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes()); |
|
| 5901 | } |
|
| 5902 | e.preventDefault(); |
|
| 5903 | }); |
|
| 5904 | ||
| 5905 | secondsInputEl.bind('mousewheel wheel', function(e) { |
|
| 5906 | if (!disabled) { |
|
| 5907 | $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds()); |
|
| 5908 | } |
|
| 5909 | e.preventDefault(); |
|
| 5910 | }); |
|
| 5911 | }; |
|
| 5912 | ||
| 5913 | // Respond on up/down arrowkeys |
|
| 5914 | this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5915 | hoursInputEl.bind('keydown', function(e) { |
|
| 5916 | if (!disabled) { |
|
| 5917 | if (e.which === 38) { // up |
|
| 5918 | e.preventDefault(); |
|
| 5919 | $scope.incrementHours(); |
|
| 5920 | $scope.$apply(); |
|
| 5921 | } else if (e.which === 40) { // down |
|
| 5922 | e.preventDefault(); |
|
| 5923 | $scope.decrementHours(); |
|
| 5924 | $scope.$apply(); |
|
| 5925 | } |
|
| 5926 | } |
|
| 5927 | }); |
|
| 5928 | ||
| 5929 | minutesInputEl.bind('keydown', function(e) { |
|
| 5930 | if (!disabled) { |
|
| 5931 | if (e.which === 38) { // up |
|
| 5932 | e.preventDefault(); |
|
| 5933 | $scope.incrementMinutes(); |
|
| 5934 | $scope.$apply(); |
|
| 5935 | } else if (e.which === 40) { // down |
|
| 5936 | e.preventDefault(); |
|
| 5937 | $scope.decrementMinutes(); |
|
| 5938 | $scope.$apply(); |
|
| 5939 | } |
|
| 5940 | } |
|
| 5941 | }); |
|
| 5942 | ||
| 5943 | secondsInputEl.bind('keydown', function(e) { |
|
| 5944 | if (!disabled) { |
|
| 5945 | if (e.which === 38) { // up |
|
| 5946 | e.preventDefault(); |
|
| 5947 | $scope.incrementSeconds(); |
|
| 5948 | $scope.$apply(); |
|
| 5949 | } else if (e.which === 40) { // down |
|
| 5950 | e.preventDefault(); |
|
| 5951 | $scope.decrementSeconds(); |
|
| 5952 | $scope.$apply(); |
|
| 5953 | } |
|
| 5954 | } |
|
| 5955 | }); |
|
| 5956 | }; |
|
| 5957 | ||
| 5958 | this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5959 | if ($scope.readonlyInput) { |
|
| 5960 | $scope.updateHours = angular.noop; |
|
| 5961 | $scope.updateMinutes = angular.noop; |
|
| 5962 | $scope.updateSeconds = angular.noop; |
|
| 5963 | return; |
|
| 5964 | } |
|
| 5965 | ||
| 5966 | var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) { |
|
| 5967 | ngModelCtrl.$setViewValue(null); |
|
| 5968 | ngModelCtrl.$setValidity('time', false); |
|
| 5969 | if (angular.isDefined(invalidHours)) { |
|
| 5970 | $scope.invalidHours = invalidHours; |
|
| 5971 | } |
|
| 5972 | ||
| 5973 | if (angular.isDefined(invalidMinutes)) { |
|
| 5974 | $scope.invalidMinutes = invalidMinutes; |
|
| 5975 | } |
|
| 5976 | ||
| 5977 | if (angular.isDefined(invalidSeconds)) { |
|
| 5978 | $scope.invalidSeconds = invalidSeconds; |
|
| 5979 | } |
|
| 5980 | }; |
|
| 5981 | ||
| 5982 | $scope.updateHours = function() { |
|
| 5983 | var hours = getHoursFromTemplate(), |
|
| 5984 | minutes = getMinutesFromTemplate(); |
|
| 5985 | ||
| 5986 | ngModelCtrl.$setDirty(); |
|
| 5987 | ||
| 5988 | if (angular.isDefined(hours) && angular.isDefined(minutes)) { |
|
| 5989 | selected.setHours(hours); |
|
| 5990 | selected.setMinutes(minutes); |
|
| 5991 | if (selected < min || selected > max) { |
|
| 5992 | invalidate(true); |
|
| 5993 | } else { |
|
| 5994 | refresh('h'); |
|
| 5995 | } |
|
| 5996 | } else { |
|
| 5997 | invalidate(true); |
|
| 5998 | } |
|
| 5999 | }; |
|
| 6000 | ||
| 6001 | hoursInputEl.bind('blur', function(e) { |
|
| 6002 | ngModelCtrl.$setTouched(); |
|
| 6003 | if (modelIsEmpty()) { |
|
| 6004 | makeValid(); |
|
| 6005 | } else if ($scope.hours === null || $scope.hours === '') { |
|
| 6006 | invalidate(true); |
|
| 6007 | } else if (!$scope.invalidHours && $scope.hours < 10) { |
|
| 6008 | $scope.$apply(function() { |
|
| 6009 | $scope.hours = pad($scope.hours, !padHours); |
|
| 6010 | }); |
|
| 6011 | } |
|
| 6012 | }); |
|
| 6013 | ||
| 6014 | $scope.updateMinutes = function() { |
|
| 6015 | var minutes = getMinutesFromTemplate(), |
|
| 6016 | hours = getHoursFromTemplate(); |
|
| 6017 | ||
| 6018 | ngModelCtrl.$setDirty(); |
|
| 6019 | ||
| 6020 | if (angular.isDefined(minutes) && angular.isDefined(hours)) { |
|
| 6021 | selected.setHours(hours); |
|
| 6022 | selected.setMinutes(minutes); |
|
| 6023 | if (selected < min || selected > max) { |
|
| 6024 | invalidate(undefined, true); |
|
| 6025 | } else { |
|
| 6026 | refresh('m'); |
|
| 6027 | } |
|
| 6028 | } else { |
|
| 6029 | invalidate(undefined, true); |
|
| 6030 | } |
|
| 6031 | }; |
|
| 6032 | ||
| 6033 | minutesInputEl.bind('blur', function(e) { |
|
| 6034 | ngModelCtrl.$setTouched(); |
|
| 6035 | if (modelIsEmpty()) { |
|
| 6036 | makeValid(); |
|
| 6037 | } else if ($scope.minutes === null) { |
|
| 6038 | invalidate(undefined, true); |
|
| 6039 | } else if (!$scope.invalidMinutes && $scope.minutes < 10) { |
|
| 6040 | $scope.$apply(function() { |
|
| 6041 | $scope.minutes = pad($scope.minutes); |
|
| 6042 | }); |
|
| 6043 | } |
|
| 6044 | }); |
|
| 6045 | ||
| 6046 | $scope.updateSeconds = function() { |
|
| 6047 | var seconds = getSecondsFromTemplate(); |
|
| 6048 | ||
| 6049 | ngModelCtrl.$setDirty(); |
|
| 6050 | ||
| 6051 | if (angular.isDefined(seconds)) { |
|
| 6052 | selected.setSeconds(seconds); |
|
| 6053 | refresh('s'); |
|
| 6054 | } else { |
|
| 6055 | invalidate(undefined, undefined, true); |
|
| 6056 | } |
|
| 6057 | }; |
|
| 6058 | ||
| 6059 | secondsInputEl.bind('blur', function(e) { |
|
| 6060 | if (modelIsEmpty()) { |
|
| 6061 | makeValid(); |
|
| 6062 | } else if (!$scope.invalidSeconds && $scope.seconds < 10) { |
|
| 6063 | $scope.$apply( function() { |
|
| 6064 | $scope.seconds = pad($scope.seconds); |
|
| 6065 | }); |
|
| 6066 | } |
|
| 6067 | }); |
|
| 6068 | ||
| 6069 | }; |
|
| 6070 | ||
| 6071 | this.render = function() { |
|
| 6072 | var date = ngModelCtrl.$viewValue; |
|
| 6073 | ||
| 6074 | if (isNaN(date)) { |
|
| 6075 | ngModelCtrl.$setValidity('time', false); |
|
| 6076 | $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'); |
|
| 6077 | } else { |
|
| 6078 | if (date) { |
|
| 6079 | selected = date; |
|
| 6080 | } |
|
| 6081 | ||
| 6082 | if (selected < min || selected > max) { |
|
| 6083 | ngModelCtrl.$setValidity('time', false); |
|
| 6084 | $scope.invalidHours = true; |
|
| 6085 | $scope.invalidMinutes = true; |
|
| 6086 | } else { |
|
| 6087 | makeValid(); |
|
| 6088 | } |
|
| 6089 | updateTemplate(); |
|
| 6090 | } |
|
| 6091 | }; |
|
| 6092 | ||
| 6093 | // Call internally when we know that model is valid. |
|
| 6094 | function refresh(keyboardChange) { |
|
| 6095 | makeValid(); |
|
| 6096 | ngModelCtrl.$setViewValue(new Date(selected)); |
|
| 6097 | updateTemplate(keyboardChange); |
|
| 6098 | } |
|
| 6099 | ||
| 6100 | function makeValid() { |
|
| 6101 | ngModelCtrl.$setValidity('time', true); |
|
| 6102 | $scope.invalidHours = false; |
|
| 6103 | $scope.invalidMinutes = false; |
|
| 6104 | $scope.invalidSeconds = false; |
|
| 6105 | } |
|
| 6106 | ||
| 6107 | function updateTemplate(keyboardChange) { |
|
| 6108 | if (!ngModelCtrl.$modelValue) { |
|
| 6109 | $scope.hours = null; |
|
| 6110 | $scope.minutes = null; |
|
| 6111 | $scope.seconds = null; |
|
| 6112 | $scope.meridian = meridians[0]; |
|
| 6113 | } else { |
|
| 6114 | var hours = selected.getHours(), |
|
| 6115 | minutes = selected.getMinutes(), |
|
| 6116 | seconds = selected.getSeconds(); |
|
| 6117 | ||
| 6118 | if ($scope.showMeridian) { |
|
| 6119 | hours = hours === 0 || hours === 12 ? 12 : hours % 12; // Convert 24 to 12 hour system |
|
| 6120 | } |
|
| 6121 | ||
| 6122 | $scope.hours = keyboardChange === 'h' ? hours : pad(hours, !padHours); |
|
| 6123 | if (keyboardChange !== 'm') { |
|
| 6124 | $scope.minutes = pad(minutes); |
|
| 6125 | } |
|
| 6126 | $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; |
|
| 6127 | ||
| 6128 | if (keyboardChange !== 's') { |
|
| 6129 | $scope.seconds = pad(seconds); |
|
| 6130 | } |
|
| 6131 | $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; |
|
| 6132 | } |
|
| 6133 | } |
|
| 6134 | ||
| 6135 | function addSecondsToSelected(seconds) { |
|
| 6136 | selected = addSeconds(selected, seconds); |
|
| 6137 | refresh(); |
|
| 6138 | } |
|
| 6139 | ||
| 6140 | function addMinutes(selected, minutes) { |
|
| 6141 | return addSeconds(selected, minutes*60); |
|
| 6142 | } |
|
| 6143 | ||
| 6144 | function addSeconds(date, seconds) { |
|
| 6145 | var dt = new Date(date.getTime() + seconds * 1000); |
|
| 6146 | var newDate = new Date(date); |
|
| 6147 | newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds()); |
|
| 6148 | return newDate; |
|
| 6149 | } |
|
| 6150 | ||
| 6151 | function modelIsEmpty() { |
|
| 6152 | return ($scope.hours === null || $scope.hours === '') && |
|
| 6153 | ($scope.minutes === null || $scope.minutes === '') && |
|
| 6154 | (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === '')); |
|
| 6155 | } |
|
| 6156 | ||
| 6157 | $scope.showSpinners = angular.isDefined($attrs.showSpinners) ? |
|
| 6158 | $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners; |
|
| 6159 | ||
| 6160 | $scope.incrementHours = function() { |
|
| 6161 | if (!$scope.noIncrementHours()) { |
|
| 6162 | addSecondsToSelected(hourStep * 60 * 60); |
|
| 6163 | } |
|
| 6164 | }; |
|
| 6165 | ||
| 6166 | $scope.decrementHours = function() { |
|
| 6167 | if (!$scope.noDecrementHours()) { |
|
| 6168 | addSecondsToSelected(-hourStep * 60 * 60); |
|
| 6169 | } |
|
| 6170 | }; |
|
| 6171 | ||
| 6172 | $scope.incrementMinutes = function() { |
|
| 6173 | if (!$scope.noIncrementMinutes()) { |
|
| 6174 | addSecondsToSelected(minuteStep * 60); |
|
| 6175 | } |
|
| 6176 | }; |
|
| 6177 | ||
| 6178 | $scope.decrementMinutes = function() { |
|
| 6179 | if (!$scope.noDecrementMinutes()) { |
|
| 6180 | addSecondsToSelected(-minuteStep * 60); |
|
| 6181 | } |
|
| 6182 | }; |
|
| 6183 | ||
| 6184 | $scope.incrementSeconds = function() { |
|
| 6185 | if (!$scope.noIncrementSeconds()) { |
|
| 6186 | addSecondsToSelected(secondStep); |
|
| 6187 | } |
|
| 6188 | }; |
|
| 6189 | ||
| 6190 | $scope.decrementSeconds = function() { |
|
| 6191 | if (!$scope.noDecrementSeconds()) { |
|
| 6192 | addSecondsToSelected(-secondStep); |
|
| 6193 | } |
|
| 6194 | }; |
|
| 6195 | ||
| 6196 | $scope.toggleMeridian = function() { |
|
| 6197 | var minutes = getMinutesFromTemplate(), |
|
| 6198 | hours = getHoursFromTemplate(); |
|
| 6199 | ||
| 6200 | if (!$scope.noToggleMeridian()) { |
|
| 6201 | if (angular.isDefined(minutes) && angular.isDefined(hours)) { |
|
| 6202 | addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60)); |
|
| 6203 | } else { |
|
| 6204 | $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0]; |
|
| 6205 | } |
|
| 6206 | } |
|
| 6207 | }; |
|
| 6208 | ||
| 6209 | $scope.blur = function() { |
|
| 6210 | ngModelCtrl.$setTouched(); |
|
| 6211 | }; |
|
| 6212 | ||
| 6213 | $scope.$on('$destroy', function() { |
|
| 6214 | while (watchers.length) { |
|
| 6215 | watchers.shift()(); |
|
| 6216 | } |
|
| 6217 | }); |
|
| 6218 | }]) |
|
| 6219 | ||
| 6220 | .directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) { |
|
| 6221 | return { |
|
| @@ 5689-6217 (lines=529) @@ | ||
| 5686 | templateUrl: 'uib/template/timepicker/timepicker.html' |
|
| 5687 | }) |
|
| 5688 | ||
| 5689 | .controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) { |
|
| 5690 | var selected = new Date(), |
|
| 5691 | watchers = [], |
|
| 5692 | ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl |
|
| 5693 | meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS, |
|
| 5694 | padHours = angular.isDefined($attrs.padHours) ? $scope.$parent.$eval($attrs.padHours) : true; |
|
| 5695 | ||
| 5696 | $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0; |
|
| 5697 | $element.removeAttr('tabindex'); |
|
| 5698 | ||
| 5699 | this.init = function(ngModelCtrl_, inputs) { |
|
| 5700 | ngModelCtrl = ngModelCtrl_; |
|
| 5701 | ngModelCtrl.$render = this.render; |
|
| 5702 | ||
| 5703 | ngModelCtrl.$formatters.unshift(function(modelValue) { |
|
| 5704 | return modelValue ? new Date(modelValue) : null; |
|
| 5705 | }); |
|
| 5706 | ||
| 5707 | var hoursInputEl = inputs.eq(0), |
|
| 5708 | minutesInputEl = inputs.eq(1), |
|
| 5709 | secondsInputEl = inputs.eq(2); |
|
| 5710 | ||
| 5711 | var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel; |
|
| 5712 | ||
| 5713 | if (mousewheel) { |
|
| 5714 | this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5715 | } |
|
| 5716 | ||
| 5717 | var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys; |
|
| 5718 | if (arrowkeys) { |
|
| 5719 | this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5720 | } |
|
| 5721 | ||
| 5722 | $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput; |
|
| 5723 | this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl); |
|
| 5724 | }; |
|
| 5725 | ||
| 5726 | var hourStep = timepickerConfig.hourStep; |
|
| 5727 | if ($attrs.hourStep) { |
|
| 5728 | watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) { |
|
| 5729 | hourStep = +value; |
|
| 5730 | })); |
|
| 5731 | } |
|
| 5732 | ||
| 5733 | var minuteStep = timepickerConfig.minuteStep; |
|
| 5734 | if ($attrs.minuteStep) { |
|
| 5735 | watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) { |
|
| 5736 | minuteStep = +value; |
|
| 5737 | })); |
|
| 5738 | } |
|
| 5739 | ||
| 5740 | var min; |
|
| 5741 | watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) { |
|
| 5742 | var dt = new Date(value); |
|
| 5743 | min = isNaN(dt) ? undefined : dt; |
|
| 5744 | })); |
|
| 5745 | ||
| 5746 | var max; |
|
| 5747 | watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) { |
|
| 5748 | var dt = new Date(value); |
|
| 5749 | max = isNaN(dt) ? undefined : dt; |
|
| 5750 | })); |
|
| 5751 | ||
| 5752 | var disabled = false; |
|
| 5753 | if ($attrs.ngDisabled) { |
|
| 5754 | watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) { |
|
| 5755 | disabled = value; |
|
| 5756 | })); |
|
| 5757 | } |
|
| 5758 | ||
| 5759 | $scope.noIncrementHours = function() { |
|
| 5760 | var incrementedSelected = addMinutes(selected, hourStep * 60); |
|
| 5761 | return disabled || incrementedSelected > max || |
|
| 5762 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5763 | }; |
|
| 5764 | ||
| 5765 | $scope.noDecrementHours = function() { |
|
| 5766 | var decrementedSelected = addMinutes(selected, -hourStep * 60); |
|
| 5767 | return disabled || decrementedSelected < min || |
|
| 5768 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5769 | }; |
|
| 5770 | ||
| 5771 | $scope.noIncrementMinutes = function() { |
|
| 5772 | var incrementedSelected = addMinutes(selected, minuteStep); |
|
| 5773 | return disabled || incrementedSelected > max || |
|
| 5774 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5775 | }; |
|
| 5776 | ||
| 5777 | $scope.noDecrementMinutes = function() { |
|
| 5778 | var decrementedSelected = addMinutes(selected, -minuteStep); |
|
| 5779 | return disabled || decrementedSelected < min || |
|
| 5780 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5781 | }; |
|
| 5782 | ||
| 5783 | $scope.noIncrementSeconds = function() { |
|
| 5784 | var incrementedSelected = addSeconds(selected, secondStep); |
|
| 5785 | return disabled || incrementedSelected > max || |
|
| 5786 | incrementedSelected < selected && incrementedSelected < min; |
|
| 5787 | }; |
|
| 5788 | ||
| 5789 | $scope.noDecrementSeconds = function() { |
|
| 5790 | var decrementedSelected = addSeconds(selected, -secondStep); |
|
| 5791 | return disabled || decrementedSelected < min || |
|
| 5792 | decrementedSelected > selected && decrementedSelected > max; |
|
| 5793 | }; |
|
| 5794 | ||
| 5795 | $scope.noToggleMeridian = function() { |
|
| 5796 | if (selected.getHours() < 12) { |
|
| 5797 | return disabled || addMinutes(selected, 12 * 60) > max; |
|
| 5798 | } |
|
| 5799 | ||
| 5800 | return disabled || addMinutes(selected, -12 * 60) < min; |
|
| 5801 | }; |
|
| 5802 | ||
| 5803 | var secondStep = timepickerConfig.secondStep; |
|
| 5804 | if ($attrs.secondStep) { |
|
| 5805 | watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) { |
|
| 5806 | secondStep = +value; |
|
| 5807 | })); |
|
| 5808 | } |
|
| 5809 | ||
| 5810 | $scope.showSeconds = timepickerConfig.showSeconds; |
|
| 5811 | if ($attrs.showSeconds) { |
|
| 5812 | watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) { |
|
| 5813 | $scope.showSeconds = !!value; |
|
| 5814 | })); |
|
| 5815 | } |
|
| 5816 | ||
| 5817 | // 12H / 24H mode |
|
| 5818 | $scope.showMeridian = timepickerConfig.showMeridian; |
|
| 5819 | if ($attrs.showMeridian) { |
|
| 5820 | watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) { |
|
| 5821 | $scope.showMeridian = !!value; |
|
| 5822 | ||
| 5823 | if (ngModelCtrl.$error.time) { |
|
| 5824 | // Evaluate from template |
|
| 5825 | var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate(); |
|
| 5826 | if (angular.isDefined(hours) && angular.isDefined(minutes)) { |
|
| 5827 | selected.setHours(hours); |
|
| 5828 | refresh(); |
|
| 5829 | } |
|
| 5830 | } else { |
|
| 5831 | updateTemplate(); |
|
| 5832 | } |
|
| 5833 | })); |
|
| 5834 | } |
|
| 5835 | ||
| 5836 | // Get $scope.hours in 24H mode if valid |
|
| 5837 | function getHoursFromTemplate() { |
|
| 5838 | var hours = +$scope.hours; |
|
| 5839 | var valid = $scope.showMeridian ? hours > 0 && hours < 13 : |
|
| 5840 | hours >= 0 && hours < 24; |
|
| 5841 | if (!valid || $scope.hours === '') { |
|
| 5842 | return undefined; |
|
| 5843 | } |
|
| 5844 | ||
| 5845 | if ($scope.showMeridian) { |
|
| 5846 | if (hours === 12) { |
|
| 5847 | hours = 0; |
|
| 5848 | } |
|
| 5849 | if ($scope.meridian === meridians[1]) { |
|
| 5850 | hours = hours + 12; |
|
| 5851 | } |
|
| 5852 | } |
|
| 5853 | return hours; |
|
| 5854 | } |
|
| 5855 | ||
| 5856 | function getMinutesFromTemplate() { |
|
| 5857 | var minutes = +$scope.minutes; |
|
| 5858 | var valid = minutes >= 0 && minutes < 60; |
|
| 5859 | if (!valid || $scope.minutes === '') { |
|
| 5860 | return undefined; |
|
| 5861 | } |
|
| 5862 | return minutes; |
|
| 5863 | } |
|
| 5864 | ||
| 5865 | function getSecondsFromTemplate() { |
|
| 5866 | var seconds = +$scope.seconds; |
|
| 5867 | return seconds >= 0 && seconds < 60 ? seconds : undefined; |
|
| 5868 | } |
|
| 5869 | ||
| 5870 | function pad(value, noPad) { |
|
| 5871 | if (value === null) { |
|
| 5872 | return ''; |
|
| 5873 | } |
|
| 5874 | ||
| 5875 | return angular.isDefined(value) && value.toString().length < 2 && !noPad ? |
|
| 5876 | '0' + value : value.toString(); |
|
| 5877 | } |
|
| 5878 | ||
| 5879 | // Respond on mousewheel spin |
|
| 5880 | this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5881 | var isScrollingUp = function(e) { |
|
| 5882 | if (e.originalEvent) { |
|
| 5883 | e = e.originalEvent; |
|
| 5884 | } |
|
| 5885 | //pick correct delta variable depending on event |
|
| 5886 | var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY; |
|
| 5887 | return e.detail || delta > 0; |
|
| 5888 | }; |
|
| 5889 | ||
| 5890 | hoursInputEl.bind('mousewheel wheel', function(e) { |
|
| 5891 | if (!disabled) { |
|
| 5892 | $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours()); |
|
| 5893 | } |
|
| 5894 | e.preventDefault(); |
|
| 5895 | }); |
|
| 5896 | ||
| 5897 | minutesInputEl.bind('mousewheel wheel', function(e) { |
|
| 5898 | if (!disabled) { |
|
| 5899 | $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes()); |
|
| 5900 | } |
|
| 5901 | e.preventDefault(); |
|
| 5902 | }); |
|
| 5903 | ||
| 5904 | secondsInputEl.bind('mousewheel wheel', function(e) { |
|
| 5905 | if (!disabled) { |
|
| 5906 | $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds()); |
|
| 5907 | } |
|
| 5908 | e.preventDefault(); |
|
| 5909 | }); |
|
| 5910 | }; |
|
| 5911 | ||
| 5912 | // Respond on up/down arrowkeys |
|
| 5913 | this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5914 | hoursInputEl.bind('keydown', function(e) { |
|
| 5915 | if (!disabled) { |
|
| 5916 | if (e.which === 38) { // up |
|
| 5917 | e.preventDefault(); |
|
| 5918 | $scope.incrementHours(); |
|
| 5919 | $scope.$apply(); |
|
| 5920 | } else if (e.which === 40) { // down |
|
| 5921 | e.preventDefault(); |
|
| 5922 | $scope.decrementHours(); |
|
| 5923 | $scope.$apply(); |
|
| 5924 | } |
|
| 5925 | } |
|
| 5926 | }); |
|
| 5927 | ||
| 5928 | minutesInputEl.bind('keydown', function(e) { |
|
| 5929 | if (!disabled) { |
|
| 5930 | if (e.which === 38) { // up |
|
| 5931 | e.preventDefault(); |
|
| 5932 | $scope.incrementMinutes(); |
|
| 5933 | $scope.$apply(); |
|
| 5934 | } else if (e.which === 40) { // down |
|
| 5935 | e.preventDefault(); |
|
| 5936 | $scope.decrementMinutes(); |
|
| 5937 | $scope.$apply(); |
|
| 5938 | } |
|
| 5939 | } |
|
| 5940 | }); |
|
| 5941 | ||
| 5942 | secondsInputEl.bind('keydown', function(e) { |
|
| 5943 | if (!disabled) { |
|
| 5944 | if (e.which === 38) { // up |
|
| 5945 | e.preventDefault(); |
|
| 5946 | $scope.incrementSeconds(); |
|
| 5947 | $scope.$apply(); |
|
| 5948 | } else if (e.which === 40) { // down |
|
| 5949 | e.preventDefault(); |
|
| 5950 | $scope.decrementSeconds(); |
|
| 5951 | $scope.$apply(); |
|
| 5952 | } |
|
| 5953 | } |
|
| 5954 | }); |
|
| 5955 | }; |
|
| 5956 | ||
| 5957 | this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) { |
|
| 5958 | if ($scope.readonlyInput) { |
|
| 5959 | $scope.updateHours = angular.noop; |
|
| 5960 | $scope.updateMinutes = angular.noop; |
|
| 5961 | $scope.updateSeconds = angular.noop; |
|
| 5962 | return; |
|
| 5963 | } |
|
| 5964 | ||
| 5965 | var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) { |
|
| 5966 | ngModelCtrl.$setViewValue(null); |
|
| 5967 | ngModelCtrl.$setValidity('time', false); |
|
| 5968 | if (angular.isDefined(invalidHours)) { |
|
| 5969 | $scope.invalidHours = invalidHours; |
|
| 5970 | } |
|
| 5971 | ||
| 5972 | if (angular.isDefined(invalidMinutes)) { |
|
| 5973 | $scope.invalidMinutes = invalidMinutes; |
|
| 5974 | } |
|
| 5975 | ||
| 5976 | if (angular.isDefined(invalidSeconds)) { |
|
| 5977 | $scope.invalidSeconds = invalidSeconds; |
|
| 5978 | } |
|
| 5979 | }; |
|
| 5980 | ||
| 5981 | $scope.updateHours = function() { |
|
| 5982 | var hours = getHoursFromTemplate(), |
|
| 5983 | minutes = getMinutesFromTemplate(); |
|
| 5984 | ||
| 5985 | ngModelCtrl.$setDirty(); |
|
| 5986 | ||
| 5987 | if (angular.isDefined(hours) && angular.isDefined(minutes)) { |
|
| 5988 | selected.setHours(hours); |
|
| 5989 | selected.setMinutes(minutes); |
|
| 5990 | if (selected < min || selected > max) { |
|
| 5991 | invalidate(true); |
|
| 5992 | } else { |
|
| 5993 | refresh('h'); |
|
| 5994 | } |
|
| 5995 | } else { |
|
| 5996 | invalidate(true); |
|
| 5997 | } |
|
| 5998 | }; |
|
| 5999 | ||
| 6000 | hoursInputEl.bind('blur', function(e) { |
|
| 6001 | ngModelCtrl.$setTouched(); |
|
| 6002 | if (modelIsEmpty()) { |
|
| 6003 | makeValid(); |
|
| 6004 | } else if ($scope.hours === null || $scope.hours === '') { |
|
| 6005 | invalidate(true); |
|
| 6006 | } else if (!$scope.invalidHours && $scope.hours < 10) { |
|
| 6007 | $scope.$apply(function() { |
|
| 6008 | $scope.hours = pad($scope.hours, !padHours); |
|
| 6009 | }); |
|
| 6010 | } |
|
| 6011 | }); |
|
| 6012 | ||
| 6013 | $scope.updateMinutes = function() { |
|
| 6014 | var minutes = getMinutesFromTemplate(), |
|
| 6015 | hours = getHoursFromTemplate(); |
|
| 6016 | ||
| 6017 | ngModelCtrl.$setDirty(); |
|
| 6018 | ||
| 6019 | if (angular.isDefined(minutes) && angular.isDefined(hours)) { |
|
| 6020 | selected.setHours(hours); |
|
| 6021 | selected.setMinutes(minutes); |
|
| 6022 | if (selected < min || selected > max) { |
|
| 6023 | invalidate(undefined, true); |
|
| 6024 | } else { |
|
| 6025 | refresh('m'); |
|
| 6026 | } |
|
| 6027 | } else { |
|
| 6028 | invalidate(undefined, true); |
|
| 6029 | } |
|
| 6030 | }; |
|
| 6031 | ||
| 6032 | minutesInputEl.bind('blur', function(e) { |
|
| 6033 | ngModelCtrl.$setTouched(); |
|
| 6034 | if (modelIsEmpty()) { |
|
| 6035 | makeValid(); |
|
| 6036 | } else if ($scope.minutes === null) { |
|
| 6037 | invalidate(undefined, true); |
|
| 6038 | } else if (!$scope.invalidMinutes && $scope.minutes < 10) { |
|
| 6039 | $scope.$apply(function() { |
|
| 6040 | $scope.minutes = pad($scope.minutes); |
|
| 6041 | }); |
|
| 6042 | } |
|
| 6043 | }); |
|
| 6044 | ||
| 6045 | $scope.updateSeconds = function() { |
|
| 6046 | var seconds = getSecondsFromTemplate(); |
|
| 6047 | ||
| 6048 | ngModelCtrl.$setDirty(); |
|
| 6049 | ||
| 6050 | if (angular.isDefined(seconds)) { |
|
| 6051 | selected.setSeconds(seconds); |
|
| 6052 | refresh('s'); |
|
| 6053 | } else { |
|
| 6054 | invalidate(undefined, undefined, true); |
|
| 6055 | } |
|
| 6056 | }; |
|
| 6057 | ||
| 6058 | secondsInputEl.bind('blur', function(e) { |
|
| 6059 | if (modelIsEmpty()) { |
|
| 6060 | makeValid(); |
|
| 6061 | } else if (!$scope.invalidSeconds && $scope.seconds < 10) { |
|
| 6062 | $scope.$apply( function() { |
|
| 6063 | $scope.seconds = pad($scope.seconds); |
|
| 6064 | }); |
|
| 6065 | } |
|
| 6066 | }); |
|
| 6067 | ||
| 6068 | }; |
|
| 6069 | ||
| 6070 | this.render = function() { |
|
| 6071 | var date = ngModelCtrl.$viewValue; |
|
| 6072 | ||
| 6073 | if (isNaN(date)) { |
|
| 6074 | ngModelCtrl.$setValidity('time', false); |
|
| 6075 | $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'); |
|
| 6076 | } else { |
|
| 6077 | if (date) { |
|
| 6078 | selected = date; |
|
| 6079 | } |
|
| 6080 | ||
| 6081 | if (selected < min || selected > max) { |
|
| 6082 | ngModelCtrl.$setValidity('time', false); |
|
| 6083 | $scope.invalidHours = true; |
|
| 6084 | $scope.invalidMinutes = true; |
|
| 6085 | } else { |
|
| 6086 | makeValid(); |
|
| 6087 | } |
|
| 6088 | updateTemplate(); |
|
| 6089 | } |
|
| 6090 | }; |
|
| 6091 | ||
| 6092 | // Call internally when we know that model is valid. |
|
| 6093 | function refresh(keyboardChange) { |
|
| 6094 | makeValid(); |
|
| 6095 | ngModelCtrl.$setViewValue(new Date(selected)); |
|
| 6096 | updateTemplate(keyboardChange); |
|
| 6097 | } |
|
| 6098 | ||
| 6099 | function makeValid() { |
|
| 6100 | ngModelCtrl.$setValidity('time', true); |
|
| 6101 | $scope.invalidHours = false; |
|
| 6102 | $scope.invalidMinutes = false; |
|
| 6103 | $scope.invalidSeconds = false; |
|
| 6104 | } |
|
| 6105 | ||
| 6106 | function updateTemplate(keyboardChange) { |
|
| 6107 | if (!ngModelCtrl.$modelValue) { |
|
| 6108 | $scope.hours = null; |
|
| 6109 | $scope.minutes = null; |
|
| 6110 | $scope.seconds = null; |
|
| 6111 | $scope.meridian = meridians[0]; |
|
| 6112 | } else { |
|
| 6113 | var hours = selected.getHours(), |
|
| 6114 | minutes = selected.getMinutes(), |
|
| 6115 | seconds = selected.getSeconds(); |
|
| 6116 | ||
| 6117 | if ($scope.showMeridian) { |
|
| 6118 | hours = hours === 0 || hours === 12 ? 12 : hours % 12; // Convert 24 to 12 hour system |
|
| 6119 | } |
|
| 6120 | ||
| 6121 | $scope.hours = keyboardChange === 'h' ? hours : pad(hours, !padHours); |
|
| 6122 | if (keyboardChange !== 'm') { |
|
| 6123 | $scope.minutes = pad(minutes); |
|
| 6124 | } |
|
| 6125 | $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; |
|
| 6126 | ||
| 6127 | if (keyboardChange !== 's') { |
|
| 6128 | $scope.seconds = pad(seconds); |
|
| 6129 | } |
|
| 6130 | $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; |
|
| 6131 | } |
|
| 6132 | } |
|
| 6133 | ||
| 6134 | function addSecondsToSelected(seconds) { |
|
| 6135 | selected = addSeconds(selected, seconds); |
|
| 6136 | refresh(); |
|
| 6137 | } |
|
| 6138 | ||
| 6139 | function addMinutes(selected, minutes) { |
|
| 6140 | return addSeconds(selected, minutes*60); |
|
| 6141 | } |
|
| 6142 | ||
| 6143 | function addSeconds(date, seconds) { |
|
| 6144 | var dt = new Date(date.getTime() + seconds * 1000); |
|
| 6145 | var newDate = new Date(date); |
|
| 6146 | newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds()); |
|
| 6147 | return newDate; |
|
| 6148 | } |
|
| 6149 | ||
| 6150 | function modelIsEmpty() { |
|
| 6151 | return ($scope.hours === null || $scope.hours === '') && |
|
| 6152 | ($scope.minutes === null || $scope.minutes === '') && |
|
| 6153 | (!$scope.showSeconds || $scope.showSeconds && ($scope.seconds === null || $scope.seconds === '')); |
|
| 6154 | } |
|
| 6155 | ||
| 6156 | $scope.showSpinners = angular.isDefined($attrs.showSpinners) ? |
|
| 6157 | $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners; |
|
| 6158 | ||
| 6159 | $scope.incrementHours = function() { |
|
| 6160 | if (!$scope.noIncrementHours()) { |
|
| 6161 | addSecondsToSelected(hourStep * 60 * 60); |
|
| 6162 | } |
|
| 6163 | }; |
|
| 6164 | ||
| 6165 | $scope.decrementHours = function() { |
|
| 6166 | if (!$scope.noDecrementHours()) { |
|
| 6167 | addSecondsToSelected(-hourStep * 60 * 60); |
|
| 6168 | } |
|
| 6169 | }; |
|
| 6170 | ||
| 6171 | $scope.incrementMinutes = function() { |
|
| 6172 | if (!$scope.noIncrementMinutes()) { |
|
| 6173 | addSecondsToSelected(minuteStep * 60); |
|
| 6174 | } |
|
| 6175 | }; |
|
| 6176 | ||
| 6177 | $scope.decrementMinutes = function() { |
|
| 6178 | if (!$scope.noDecrementMinutes()) { |
|
| 6179 | addSecondsToSelected(-minuteStep * 60); |
|
| 6180 | } |
|
| 6181 | }; |
|
| 6182 | ||
| 6183 | $scope.incrementSeconds = function() { |
|
| 6184 | if (!$scope.noIncrementSeconds()) { |
|
| 6185 | addSecondsToSelected(secondStep); |
|
| 6186 | } |
|
| 6187 | }; |
|
| 6188 | ||
| 6189 | $scope.decrementSeconds = function() { |
|
| 6190 | if (!$scope.noDecrementSeconds()) { |
|
| 6191 | addSecondsToSelected(-secondStep); |
|
| 6192 | } |
|
| 6193 | }; |
|
| 6194 | ||
| 6195 | $scope.toggleMeridian = function() { |
|
| 6196 | var minutes = getMinutesFromTemplate(), |
|
| 6197 | hours = getHoursFromTemplate(); |
|
| 6198 | ||
| 6199 | if (!$scope.noToggleMeridian()) { |
|
| 6200 | if (angular.isDefined(minutes) && angular.isDefined(hours)) { |
|
| 6201 | addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60)); |
|
| 6202 | } else { |
|
| 6203 | $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0]; |
|
| 6204 | } |
|
| 6205 | } |
|
| 6206 | }; |
|
| 6207 | ||
| 6208 | $scope.blur = function() { |
|
| 6209 | ngModelCtrl.$setTouched(); |
|
| 6210 | }; |
|
| 6211 | ||
| 6212 | $scope.$on('$destroy', function() { |
|
| 6213 | while (watchers.length) { |
|
| 6214 | watchers.shift()(); |
|
| 6215 | } |
|
| 6216 | }); |
|
| 6217 | }]) |
|
| 6218 | ||
| 6219 | .directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) { |
|
| 6220 | return { |
|