rails-angular-strap 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +21 -0
- data/lib/rails-angular-strap.rb +11 -0
- data/lib/rails-angular-strap/engine.rb +4 -0
- data/lib/rails-angular-strap/version.rb +4 -0
- data/vendor/assets/javascripts/angular-strap.js +2 -0
- data/vendor/assets/javascripts/angular-strap.min.js +2 -0
- data/vendor/assets/javascripts/angular-strap/angular-strap.js +5014 -0
- data/vendor/assets/javascripts/angular-strap/angular-strap.min.js +11 -0
- data/vendor/assets/javascripts/angular-strap/angular-strap.tpl.js +89 -0
- data/vendor/assets/javascripts/angular-strap/angular-strap.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/affix.js +249 -0
- data/vendor/assets/javascripts/angular-strap/modules/affix.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/affix.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/alert.js +120 -0
- data/vendor/assets/javascripts/angular-strap/modules/alert.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/alert.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/alert.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/alert.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/aside.js +96 -0
- data/vendor/assets/javascripts/angular-strap/modules/aside.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/aside.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/aside.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/aside.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/button.js +177 -0
- data/vendor/assets/javascripts/angular-strap/modules/button.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/button.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/collapse.js +273 -0
- data/vendor/assets/javascripts/angular-strap/modules/collapse.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/collapse.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-formatter.js +61 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-formatter.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-formatter.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-parser.js +273 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-parser.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/date-parser.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/datepicker.js +640 -0
- data/vendor/assets/javascripts/angular-strap/modules/datepicker.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/datepicker.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/datepicker.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/datepicker.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/debounce.js +62 -0
- data/vendor/assets/javascripts/angular-strap/modules/debounce.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/debounce.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/dimensions.js +156 -0
- data/vendor/assets/javascripts/angular-strap/modules/dimensions.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/dimensions.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/dropdown.js +149 -0
- data/vendor/assets/javascripts/angular-strap/modules/dropdown.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/dropdown.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/dropdown.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/dropdown.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/modal.js +349 -0
- data/vendor/assets/javascripts/angular-strap/modules/modal.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/modal.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/modal.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/modal.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/navbar.js +72 -0
- data/vendor/assets/javascripts/angular-strap/modules/navbar.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/navbar.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/parse-options.js +76 -0
- data/vendor/assets/javascripts/angular-strap/modules/parse-options.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/parse-options.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/popover.js +112 -0
- data/vendor/assets/javascripts/angular-strap/modules/popover.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/popover.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/popover.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/popover.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/raf.js +61 -0
- data/vendor/assets/javascripts/angular-strap/modules/raf.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/raf.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/scrollspy.js +261 -0
- data/vendor/assets/javascripts/angular-strap/modules/scrollspy.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/scrollspy.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/select.js +325 -0
- data/vendor/assets/javascripts/angular-strap/modules/select.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/select.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/select.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/select.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/tab.js +186 -0
- data/vendor/assets/javascripts/angular-strap/modules/tab.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/tab.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/tab.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/tab.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/timepicker.js +485 -0
- data/vendor/assets/javascripts/angular-strap/modules/timepicker.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/timepicker.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/timepicker.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/timepicker.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/tooltip.js +690 -0
- data/vendor/assets/javascripts/angular-strap/modules/tooltip.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/tooltip.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/tooltip.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/tooltip.tpl.min.js +8 -0
- data/vendor/assets/javascripts/angular-strap/modules/typeahead.js +266 -0
- data/vendor/assets/javascripts/angular-strap/modules/typeahead.min.js +9 -0
- data/vendor/assets/javascripts/angular-strap/modules/typeahead.min.js.map +1 -0
- data/vendor/assets/javascripts/angular-strap/modules/typeahead.tpl.js +14 -0
- data/vendor/assets/javascripts/angular-strap/modules/typeahead.tpl.min.js +8 -0
- metadata +143 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
"use strict";angular.module("mgcrea.ngStrap.tab",[]).provider("$tab",function(){var e=this.defaults={animation:"am-fade",template:"tab/tab.tpl.html",navClass:"nav-tabs",activeClass:"active"},a=this.controller=function(a,n,t){var s=this;s.$options=angular.copy(e),angular.forEach(["animation","navClass","activeClass"],function(e){angular.isDefined(t[e])&&(s.$options[e]=t[e])}),a.$navClass=s.$options.navClass,a.$activeClass=s.$options.activeClass,s.$panes=a.$panes=[],s.$activePaneChangeListeners=s.$viewChangeListeners=[],s.$push=function(e){s.$panes.push(e)},s.$remove=function(e){var a=s.$panes.indexOf(e),n=s.$panes.$active;s.$panes.splice(a,1),n>a?n--:a===n&&n===s.$panes.length&&n--,s.$setActive(n)},s.$panes.$active=0,s.$setActive=a.$setActive=function(e){s.$panes.$active=e,s.$activePaneChangeListeners.forEach(function(e){e()})}};this.$get=function(){var n={};return n.defaults=e,n.controller=a,n}}).directive("bsTabs",["$window","$animate","$tab","$parse",function(e,a,n,t){var s=n.defaults;return{require:["?ngModel","bsTabs"],transclude:!0,scope:!0,controller:["$scope","$element","$attrs",n.controller],templateUrl:function(e,a){return a.template||s.template},link:function(e,a,n,s){var i=s[0],o=s[1];if(i&&(console.warn("Usage of ngModel is deprecated, please use bsActivePane instead!"),o.$activePaneChangeListeners.push(function(){i.$setViewValue(o.$panes.$active)}),i.$formatters.push(function(e){return o.$setActive(1*e),e})),n.bsActivePane){var c=t(n.bsActivePane);o.$activePaneChangeListeners.push(function(){c.assign(e,o.$panes.$active)}),e.$watch(n.bsActivePane,function(e){o.$setActive(1*e)},!0)}}}}]).directive("bsPane",["$window","$animate","$sce",function(e,a,n){return{require:["^?ngModel","^bsTabs"],scope:!0,link:function(e,t,s,i){function o(){var n=c.$panes.indexOf(e),s=c.$panes.$active;a[n===s?"addClass":"removeClass"](t,c.$options.activeClass)}var c=(i[0],i[1]);t.addClass("tab-pane"),s.$observe("title",function(a){e.title=n.trustAsHtml(a)}),c.$options.animation&&t.addClass(c.$options.animation),c.$push(e),e.$on("$destroy",function(){c.$remove(e)}),c.$activePaneChangeListeners.push(function(){o()}),o()}}}]);
|
|
9
|
+
//# sourceMappingURL=tab.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["tab/tab.js"],"names":[],"mappings":"qBASM,OAAA,oDAIF,GAAI,GAAA,KAAa,UACf,UAAW,0DAGX,YAAK,sDAOL,GAAA,SAAO,QAAe,KAAK,sEAEtB,QAAA,UAAgB,EAAS,MAAA,EAAA,SAAA,GAAA,EAAA,sCAK9B,EAAK,aAAA,EAAA,SAA6B,YAElC,EAAK,OAAQ,EAAA,YAKX,2BAAgC,EAAA,gEAMhC,QAAY,SAAA,kDAKP,OAAI,OAAU,EAAA,OAKnB,gCAKA,MAEE,WAAA,gFAMN,EAAK,2BAAkB,QAAA,SAAA,GACjB,qCAUN,OAFD,GAAA,SAAU,iBAEL,eAKK,UAAA,UAAA,WAAA,OAAA,SAAA,SAAA,EAAA,EAAA,EAAA,MAEP,GAAa,EAAA,gBAGb,SAAM,WAAS,+BAET,cACA,SAAa,WAAY,SAAA,EAAA,+FAM3B,GAAa,EAAA,oGAUX,2BAAmC,KAAA,WACnC,EAAO,cAAA,EAAA,OAAA,wEAYP,EAAA,aAAmB,2BAMlB,2BAAA,KAAA,kGAOA,mBAOD,UAAA,UAAc,WAAY,OAAA,SAAA,EAAA,EAAA,iDAI9B,iCA2BE,+BAEF,EAAA,EAAA,OAAA,oEA1BA,GACE,IADa,EAAS,GACR,EAAK,2GAYrB,EAAU,SAAA,EAAY,SAAW,WAIjC,EAAS,MAAA,KAGP,IAAA,WAAmB,uEAWxB","file":"tab.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // DEPRECATED: $viewChangeListeners, please use $activePaneChangeListeners\n // Because we deprecated ngModel usage, we rename viewChangeListeners to \n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var activeIndex = self.$panes.$active;\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to \n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n self.$setActive(activeIndex);\n };\n\n self.$panes.$active = 0;\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // DEPRECATED: ngModel, please use bsActivePane\n // 'ngModel' is deprecated bacause if interferes with form validation\n // and status, so avoid using it here.\n if(ngModelCtrl) {\n console.warn('Usage of ngModel is deprecated, please use bsActivePane instead!');\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue * 1);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue * 1);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n var active = bsTabsCtrl.$panes.$active;\n $animate[index === active ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
angular.module('mgcrea.ngStrap.tab').run(['$templateCache', function($templateCache) {
|
|
11
|
+
|
|
12
|
+
$templateCache.put('tab/tab.tpl.html', '<ul class="nav" ng-class="$navClass" role="tablist"><li ng-repeat="$pane in $panes track by $index" ng-class="$index == $panes.$active ? $activeClass : \'\'"><a role="tab" data-toggle="tab" ng-click="$setActive($index)" data-index="{{ $index }}" ng-bind-html="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>');
|
|
13
|
+
|
|
14
|
+
}]);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
"use strict";angular.module("mgcrea.ngStrap.tab").run(["$templateCache",function(a){a.put("tab/tab.tpl.html",'<ul class="nav" ng-class="$navClass" role="tablist"><li ng-repeat="$pane in $panes track by $index" ng-class="$index == $panes.$active ? $activeClass : \'\'"><a role="tab" data-toggle="tab" ng-click="$setActive($index)" data-index="{{ $index }}" ng-bind-html="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>')}]);
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* angular-strap
|
|
3
|
+
* @version v2.1.6 - 2015-01-11
|
|
4
|
+
* @link http://mgcrea.github.io/angular-strap
|
|
5
|
+
* @author Olivier Louvignes (olivier@mg-crea.com)
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
angular.module('mgcrea.ngStrap.timepicker', [
|
|
11
|
+
'mgcrea.ngStrap.helpers.dateParser',
|
|
12
|
+
'mgcrea.ngStrap.helpers.dateFormatter',
|
|
13
|
+
'mgcrea.ngStrap.tooltip'])
|
|
14
|
+
|
|
15
|
+
.provider('$timepicker', function() {
|
|
16
|
+
|
|
17
|
+
var defaults = this.defaults = {
|
|
18
|
+
animation: 'am-fade',
|
|
19
|
+
prefixClass: 'timepicker',
|
|
20
|
+
placement: 'bottom-left',
|
|
21
|
+
template: 'timepicker/timepicker.tpl.html',
|
|
22
|
+
trigger: 'focus',
|
|
23
|
+
container: false,
|
|
24
|
+
keyboard: true,
|
|
25
|
+
html: false,
|
|
26
|
+
delay: 0,
|
|
27
|
+
// lang: $locale.id,
|
|
28
|
+
useNative: true,
|
|
29
|
+
timeType: 'date',
|
|
30
|
+
timeFormat: 'shortTime',
|
|
31
|
+
modelTimeFormat: null,
|
|
32
|
+
autoclose: false,
|
|
33
|
+
minTime: -Infinity,
|
|
34
|
+
maxTime: +Infinity,
|
|
35
|
+
length: 5,
|
|
36
|
+
hourStep: 1,
|
|
37
|
+
minuteStep: 5,
|
|
38
|
+
iconUp: 'glyphicon glyphicon-chevron-up',
|
|
39
|
+
iconDown: 'glyphicon glyphicon-chevron-down',
|
|
40
|
+
arrowBehavior: 'pager'
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
this.$get = ["$window", "$document", "$rootScope", "$sce", "$dateFormatter", "$tooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {
|
|
44
|
+
|
|
45
|
+
var bodyEl = angular.element($window.document.body);
|
|
46
|
+
var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);
|
|
47
|
+
var isTouch = ('createTouch' in $window.document) && isNative;
|
|
48
|
+
if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();
|
|
49
|
+
|
|
50
|
+
function timepickerFactory(element, controller, config) {
|
|
51
|
+
|
|
52
|
+
var $timepicker = $tooltip(element, angular.extend({}, defaults, config));
|
|
53
|
+
var parentScope = config.scope;
|
|
54
|
+
var options = $timepicker.$options;
|
|
55
|
+
var scope = $timepicker.$scope;
|
|
56
|
+
|
|
57
|
+
var lang = options.lang;
|
|
58
|
+
var formatDate = function(date, format) {
|
|
59
|
+
return $dateFormatter.formatDate(date, format, lang);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// View vars
|
|
63
|
+
|
|
64
|
+
var selectedIndex = 0;
|
|
65
|
+
var startDate = controller.$dateValue || new Date();
|
|
66
|
+
var viewDate = {hour: startDate.getHours(), meridian: startDate.getHours() < 12, minute: startDate.getMinutes(), second: startDate.getSeconds(), millisecond: startDate.getMilliseconds()};
|
|
67
|
+
|
|
68
|
+
var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);
|
|
69
|
+
|
|
70
|
+
var hoursFormat = $dateFormatter.hoursFormat(format),
|
|
71
|
+
timeSeparator = $dateFormatter.timeSeparator(format),
|
|
72
|
+
minutesFormat = $dateFormatter.minutesFormat(format),
|
|
73
|
+
showAM = $dateFormatter.showAM(format);
|
|
74
|
+
|
|
75
|
+
scope.$iconUp = options.iconUp;
|
|
76
|
+
scope.$iconDown = options.iconDown;
|
|
77
|
+
|
|
78
|
+
// Scope methods
|
|
79
|
+
|
|
80
|
+
scope.$select = function(date, index) {
|
|
81
|
+
$timepicker.select(date, index);
|
|
82
|
+
};
|
|
83
|
+
scope.$moveIndex = function(value, index) {
|
|
84
|
+
$timepicker.$moveIndex(value, index);
|
|
85
|
+
};
|
|
86
|
+
scope.$switchMeridian = function(date) {
|
|
87
|
+
$timepicker.switchMeridian(date);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Public methods
|
|
91
|
+
|
|
92
|
+
$timepicker.update = function(date) {
|
|
93
|
+
// console.warn('$timepicker.update() newValue=%o', date);
|
|
94
|
+
if(angular.isDate(date) && !isNaN(date.getTime())) {
|
|
95
|
+
$timepicker.$date = date;
|
|
96
|
+
angular.extend(viewDate, {hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds()});
|
|
97
|
+
$timepicker.$build();
|
|
98
|
+
} else if(!$timepicker.$isBuilt) {
|
|
99
|
+
$timepicker.$build();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
$timepicker.select = function(date, index, keep) {
|
|
104
|
+
// console.warn('$timepicker.select', date, scope.$mode);
|
|
105
|
+
if(!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);
|
|
106
|
+
if(!angular.isDate(date)) date = new Date(date);
|
|
107
|
+
if(index === 0) controller.$dateValue.setHours(date.getHours());
|
|
108
|
+
else if(index === 1) controller.$dateValue.setMinutes(date.getMinutes());
|
|
109
|
+
controller.$setViewValue(angular.copy(controller.$dateValue));
|
|
110
|
+
controller.$render();
|
|
111
|
+
if(options.autoclose && !keep) {
|
|
112
|
+
$timeout(function() { $timepicker.hide(true); });
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
$timepicker.switchMeridian = function(date) {
|
|
117
|
+
if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
var hours = (date || controller.$dateValue).getHours();
|
|
121
|
+
controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);
|
|
122
|
+
controller.$setViewValue(angular.copy(controller.$dateValue));
|
|
123
|
+
controller.$render();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Protected methods
|
|
127
|
+
|
|
128
|
+
$timepicker.$build = function() {
|
|
129
|
+
// console.warn('$timepicker.$build() viewDate=%o', viewDate);
|
|
130
|
+
var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);
|
|
131
|
+
var hours = [], hour;
|
|
132
|
+
for(i = 0; i < options.length; i++) {
|
|
133
|
+
hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);
|
|
134
|
+
hours.push({date: hour, label: formatDate(hour, hoursFormat), selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), disabled: $timepicker.$isDisabled(hour, 0)});
|
|
135
|
+
}
|
|
136
|
+
var minutes = [], minute;
|
|
137
|
+
for(i = 0; i < options.length; i++) {
|
|
138
|
+
minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);
|
|
139
|
+
minutes.push({date: minute, label: formatDate(minute, minutesFormat), selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), disabled: $timepicker.$isDisabled(minute, 1)});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var rows = [];
|
|
143
|
+
for(i = 0; i < options.length; i++) {
|
|
144
|
+
rows.push([hours[i], minutes[i]]);
|
|
145
|
+
}
|
|
146
|
+
scope.rows = rows;
|
|
147
|
+
scope.showAM = showAM;
|
|
148
|
+
scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;
|
|
149
|
+
scope.timeSeparator = timeSeparator;
|
|
150
|
+
$timepicker.$isBuilt = true;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
$timepicker.$isSelected = function(date, index) {
|
|
154
|
+
if(!$timepicker.$date) return false;
|
|
155
|
+
else if(index === 0) {
|
|
156
|
+
return date.getHours() === $timepicker.$date.getHours();
|
|
157
|
+
} else if(index === 1) {
|
|
158
|
+
return date.getMinutes() === $timepicker.$date.getMinutes();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
$timepicker.$isDisabled = function(date, index) {
|
|
163
|
+
var selectedTime;
|
|
164
|
+
if(index === 0) {
|
|
165
|
+
selectedTime = date.getTime() + viewDate.minute * 6e4;
|
|
166
|
+
} else if(index === 1) {
|
|
167
|
+
selectedTime = date.getTime() + viewDate.hour * 36e5;
|
|
168
|
+
}
|
|
169
|
+
return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
scope.$arrowAction = function (value, index) {
|
|
173
|
+
if (options.arrowBehavior === 'picker') {
|
|
174
|
+
$timepicker.$setTimeByStep(value,index);
|
|
175
|
+
} else {
|
|
176
|
+
$timepicker.$moveIndex(value,index);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
$timepicker.$setTimeByStep = function(value, index) {
|
|
181
|
+
var newDate = new Date($timepicker.$date);
|
|
182
|
+
var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;
|
|
183
|
+
var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;
|
|
184
|
+
if (index === 0) {
|
|
185
|
+
newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));
|
|
189
|
+
}
|
|
190
|
+
$timepicker.select(newDate, index, true);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
$timepicker.$moveIndex = function(value, index) {
|
|
194
|
+
var targetDate;
|
|
195
|
+
if(index === 0) {
|
|
196
|
+
targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute);
|
|
197
|
+
angular.extend(viewDate, {hour: targetDate.getHours()});
|
|
198
|
+
} else if(index === 1) {
|
|
199
|
+
targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep));
|
|
200
|
+
angular.extend(viewDate, {minute: targetDate.getMinutes()});
|
|
201
|
+
}
|
|
202
|
+
$timepicker.$build();
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
$timepicker.$onMouseDown = function(evt) {
|
|
206
|
+
// Prevent blur on mousedown on .dropdown-menu
|
|
207
|
+
if(evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();
|
|
208
|
+
evt.stopPropagation();
|
|
209
|
+
// Emulate click for mobile devices
|
|
210
|
+
if(isTouch) {
|
|
211
|
+
var targetEl = angular.element(evt.target);
|
|
212
|
+
if(targetEl[0].nodeName.toLowerCase() !== 'button') {
|
|
213
|
+
targetEl = targetEl.parent();
|
|
214
|
+
}
|
|
215
|
+
targetEl.triggerHandler('click');
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
$timepicker.$onKeyDown = function(evt) {
|
|
220
|
+
if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;
|
|
221
|
+
evt.preventDefault();
|
|
222
|
+
evt.stopPropagation();
|
|
223
|
+
|
|
224
|
+
// Close on enter
|
|
225
|
+
if(evt.keyCode === 13) return $timepicker.hide(true);
|
|
226
|
+
|
|
227
|
+
// Navigate with keyboard
|
|
228
|
+
var newDate = new Date($timepicker.$date);
|
|
229
|
+
var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length;
|
|
230
|
+
var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length;
|
|
231
|
+
var lateralMove = /(37|39)/.test(evt.keyCode);
|
|
232
|
+
var count = 2 + showAM * 1;
|
|
233
|
+
|
|
234
|
+
// Navigate indexes (left, right)
|
|
235
|
+
if (lateralMove) {
|
|
236
|
+
if(evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;
|
|
237
|
+
else if(evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Update values (up, down)
|
|
241
|
+
var selectRange = [0, hoursLength];
|
|
242
|
+
if(selectedIndex === 0) {
|
|
243
|
+
if(evt.keyCode === 38) newDate.setHours(hours - parseInt(options.hourStep, 10));
|
|
244
|
+
else if(evt.keyCode === 40) newDate.setHours(hours + parseInt(options.hourStep, 10));
|
|
245
|
+
// re-calculate hours length because we have changed hours value
|
|
246
|
+
hoursLength = formatDate(newDate, hoursFormat).length;
|
|
247
|
+
selectRange = [0, hoursLength];
|
|
248
|
+
} else if(selectedIndex === 1) {
|
|
249
|
+
if(evt.keyCode === 38) newDate.setMinutes(minutes - parseInt(options.minuteStep, 10));
|
|
250
|
+
else if(evt.keyCode === 40) newDate.setMinutes(minutes + parseInt(options.minuteStep, 10));
|
|
251
|
+
// re-calculate minutes length because we have changes minutes value
|
|
252
|
+
minutesLength = formatDate(newDate, minutesFormat).length;
|
|
253
|
+
selectRange = [hoursLength + 1, hoursLength + 1 + minutesLength];
|
|
254
|
+
} else if(selectedIndex === 2) {
|
|
255
|
+
if(!lateralMove) $timepicker.switchMeridian();
|
|
256
|
+
selectRange = [hoursLength + 1 + minutesLength + 1, hoursLength + 1 + minutesLength + 3];
|
|
257
|
+
}
|
|
258
|
+
$timepicker.select(newDate, selectedIndex, true);
|
|
259
|
+
createSelection(selectRange[0], selectRange[1]);
|
|
260
|
+
parentScope.$digest();
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Private
|
|
264
|
+
|
|
265
|
+
function createSelection(start, end) {
|
|
266
|
+
if(element[0].createTextRange) {
|
|
267
|
+
var selRange = element[0].createTextRange();
|
|
268
|
+
selRange.collapse(true);
|
|
269
|
+
selRange.moveStart('character', start);
|
|
270
|
+
selRange.moveEnd('character', end);
|
|
271
|
+
selRange.select();
|
|
272
|
+
} else if(element[0].setSelectionRange) {
|
|
273
|
+
element[0].setSelectionRange(start, end);
|
|
274
|
+
} else if(angular.isUndefined(element[0].selectionStart)) {
|
|
275
|
+
element[0].selectionStart = start;
|
|
276
|
+
element[0].selectionEnd = end;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function focusElement() {
|
|
281
|
+
element[0].focus();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Overrides
|
|
285
|
+
|
|
286
|
+
var _init = $timepicker.init;
|
|
287
|
+
$timepicker.init = function() {
|
|
288
|
+
if(isNative && options.useNative) {
|
|
289
|
+
element.prop('type', 'time');
|
|
290
|
+
element.css('-webkit-appearance', 'textfield');
|
|
291
|
+
return;
|
|
292
|
+
} else if(isTouch) {
|
|
293
|
+
element.prop('type', 'text');
|
|
294
|
+
element.attr('readonly', 'true');
|
|
295
|
+
element.on('click', focusElement);
|
|
296
|
+
}
|
|
297
|
+
_init();
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
var _destroy = $timepicker.destroy;
|
|
301
|
+
$timepicker.destroy = function() {
|
|
302
|
+
if(isNative && options.useNative) {
|
|
303
|
+
element.off('click', focusElement);
|
|
304
|
+
}
|
|
305
|
+
_destroy();
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
var _show = $timepicker.show;
|
|
309
|
+
$timepicker.show = function() {
|
|
310
|
+
_show();
|
|
311
|
+
// use timeout to hookup the events to prevent
|
|
312
|
+
// event bubbling from being processed imediately.
|
|
313
|
+
$timeout(function() {
|
|
314
|
+
$timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);
|
|
315
|
+
if(options.keyboard) {
|
|
316
|
+
element.on('keydown', $timepicker.$onKeyDown);
|
|
317
|
+
}
|
|
318
|
+
}, 0, false);
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
var _hide = $timepicker.hide;
|
|
322
|
+
$timepicker.hide = function(blur) {
|
|
323
|
+
if(!$timepicker.$isShown) return;
|
|
324
|
+
$timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);
|
|
325
|
+
if(options.keyboard) {
|
|
326
|
+
element.off('keydown', $timepicker.$onKeyDown);
|
|
327
|
+
}
|
|
328
|
+
_hide(blur);
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
return $timepicker;
|
|
332
|
+
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
timepickerFactory.defaults = defaults;
|
|
336
|
+
return timepickerFactory;
|
|
337
|
+
|
|
338
|
+
}];
|
|
339
|
+
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
.directive('bsTimepicker', ["$window", "$parse", "$q", "$dateFormatter", "$dateParser", "$timepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {
|
|
344
|
+
|
|
345
|
+
var defaults = $timepicker.defaults;
|
|
346
|
+
var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);
|
|
347
|
+
var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;
|
|
348
|
+
|
|
349
|
+
return {
|
|
350
|
+
restrict: 'EAC',
|
|
351
|
+
require: 'ngModel',
|
|
352
|
+
link: function postLink(scope, element, attr, controller) {
|
|
353
|
+
|
|
354
|
+
// Directive options
|
|
355
|
+
var options = {scope: scope, controller: controller};
|
|
356
|
+
angular.forEach(['placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'template', 'autoclose', 'timeType', 'timeFormat', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'id'], function(key) {
|
|
357
|
+
if(angular.isDefined(attr[key])) options[key] = attr[key];
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Visibility binding support
|
|
361
|
+
attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {
|
|
362
|
+
if(!timepicker || !angular.isDefined(newValue)) return;
|
|
363
|
+
if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);
|
|
364
|
+
newValue === true ? timepicker.show() : timepicker.hide();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// Initialize timepicker
|
|
368
|
+
if(isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';
|
|
369
|
+
var timepicker = $timepicker(element, controller, options);
|
|
370
|
+
options = timepicker.$options;
|
|
371
|
+
|
|
372
|
+
var lang = options.lang;
|
|
373
|
+
var formatDate = function(date, format) {
|
|
374
|
+
return $dateFormatter.formatDate(date, format, lang);
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// Initialize parser
|
|
378
|
+
var dateParser = $dateParser({format: options.timeFormat, lang: lang});
|
|
379
|
+
|
|
380
|
+
// Observe attributes for changes
|
|
381
|
+
angular.forEach(['minTime', 'maxTime'], function(key) {
|
|
382
|
+
// console.warn('attr.$observe(%s)', key, attr[key]);
|
|
383
|
+
angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {
|
|
384
|
+
timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);
|
|
385
|
+
!isNaN(timepicker.$options[key]) && timepicker.$build();
|
|
386
|
+
validateAgainstMinMaxTime(controller.$dateValue);
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// Watch model for changes
|
|
391
|
+
scope.$watch(attr.ngModel, function(newValue, oldValue) {
|
|
392
|
+
// console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);
|
|
393
|
+
timepicker.update(controller.$dateValue);
|
|
394
|
+
}, true);
|
|
395
|
+
|
|
396
|
+
function validateAgainstMinMaxTime(parsedTime) {
|
|
397
|
+
if (!angular.isDate(parsedTime)) return;
|
|
398
|
+
var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;
|
|
399
|
+
var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;
|
|
400
|
+
var isValid = isMinValid && isMaxValid;
|
|
401
|
+
controller.$setValidity('date', isValid);
|
|
402
|
+
controller.$setValidity('min', isMinValid);
|
|
403
|
+
controller.$setValidity('max', isMaxValid);
|
|
404
|
+
// Only update the model when we have a valid date
|
|
405
|
+
if(!isValid) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
controller.$dateValue = parsedTime;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// viewValue -> $parsers -> modelValue
|
|
412
|
+
controller.$parsers.unshift(function(viewValue) {
|
|
413
|
+
// console.warn('$parser("%s"): viewValue=%o', element.attr('ng-model'), viewValue);
|
|
414
|
+
// Null values should correctly reset the model value & validity
|
|
415
|
+
if(!viewValue) {
|
|
416
|
+
// BREAKING CHANGE:
|
|
417
|
+
// return null (not undefined) when input value is empty, so angularjs 1.3
|
|
418
|
+
// ngModelController can go ahead and run validators, like ngRequired
|
|
419
|
+
controller.$setValidity('date', true);
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);
|
|
423
|
+
if(!parsedTime || isNaN(parsedTime.getTime())) {
|
|
424
|
+
controller.$setValidity('date', false);
|
|
425
|
+
// return undefined, causes ngModelController to
|
|
426
|
+
// invalidate model value
|
|
427
|
+
return;
|
|
428
|
+
} else {
|
|
429
|
+
validateAgainstMinMaxTime(parsedTime);
|
|
430
|
+
}
|
|
431
|
+
if(options.timeType === 'string') {
|
|
432
|
+
return formatDate(parsedTime, options.modelTimeFormat || options.timeFormat);
|
|
433
|
+
} else if(options.timeType === 'number') {
|
|
434
|
+
return controller.$dateValue.getTime();
|
|
435
|
+
} else if(options.timeType === 'unix') {
|
|
436
|
+
return controller.$dateValue.getTime() / 1000;
|
|
437
|
+
} else if(options.timeType === 'iso') {
|
|
438
|
+
return controller.$dateValue.toISOString();
|
|
439
|
+
} else {
|
|
440
|
+
return new Date(controller.$dateValue);
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// modelValue -> $formatters -> viewValue
|
|
445
|
+
controller.$formatters.push(function(modelValue) {
|
|
446
|
+
// console.warn('$formatter("%s"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);
|
|
447
|
+
var date;
|
|
448
|
+
if(angular.isUndefined(modelValue) || modelValue === null) {
|
|
449
|
+
date = NaN;
|
|
450
|
+
} else if(angular.isDate(modelValue)) {
|
|
451
|
+
date = modelValue;
|
|
452
|
+
} else if(options.timeType === 'string') {
|
|
453
|
+
date = dateParser.parse(modelValue, null, options.modelTimeFormat);
|
|
454
|
+
} else if(options.timeType === 'unix') {
|
|
455
|
+
date = new Date(modelValue * 1000);
|
|
456
|
+
} else {
|
|
457
|
+
date = new Date(modelValue);
|
|
458
|
+
}
|
|
459
|
+
// Setup default value?
|
|
460
|
+
// if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);
|
|
461
|
+
controller.$dateValue = date;
|
|
462
|
+
return getTimeFormattedString();
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
// viewValue -> element
|
|
466
|
+
controller.$render = function() {
|
|
467
|
+
// console.warn('$render("%s"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);
|
|
468
|
+
element.val(getTimeFormattedString());
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
function getTimeFormattedString() {
|
|
472
|
+
return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Garbage collection
|
|
476
|
+
scope.$on('$destroy', function() {
|
|
477
|
+
if (timepicker) timepicker.destroy();
|
|
478
|
+
options = null;
|
|
479
|
+
timepicker = null;
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
}]);
|