Built motion from commit 943eae279.|1.0.24
[motion.git] / public / bower_components / angular-bootstrap-slider / slider.js
1 angular.module('ui.bootstrap-slider', [])
2     .directive('slider', ['$parse', '$timeout', '$rootScope', function ($parse, $timeout, $rootScope) {
3         return {
4             restrict: 'AE',
5             replace: true,
6             template: '<div><input class="slider-input" type="text" style="width:100%" /></div>',
7             require: 'ngModel',
8             scope: {
9                 max: "=",
10                 min: "=",
11                 step: "=",
12                 value: "=",
13                 ngModel: '=',
14                 ngDisabled: '=',
15                 range: '=',
16                 sliderid: '=',
17                 ticks: '=',
18                 ticksLabels: '=',
19                 ticksSnapBounds: '=',
20                 ticksPositions: '=',
21                 scale: '=',
22                 focus: '=',
23                 formatter: '&',
24                 onStartSlide: '&',
25                 onStopSlide: '&',
26                 onSlide: '&'
27             },
28             link: function ($scope, element, attrs, ngModelCtrl, $compile) {
29                 var ngModelDeregisterFn, ngDisabledDeregisterFn;
30
31                 var slider = initSlider();
32
33                 function initSlider() {
34                     var options = {};
35
36                     function setOption(key, value, defaultValue) {
37                         options[key] = value || defaultValue;
38                     }
39
40                     function setFloatOption(key, value, defaultValue) {
41                         options[key] = value || value === 0 ? parseFloat(value) : defaultValue;
42                     }
43
44                     function setBooleanOption(key, value, defaultValue) {
45                         options[key] = value ? value + '' === 'true' : defaultValue;
46                     }
47
48                     function getArrayOrValue(value) {
49                         return (angular.isString(value) && value.indexOf("[") === 0) ? angular.fromJson(value) : value;
50                     }
51
52                     setOption('id', $scope.sliderid);
53                     setOption('orientation', attrs.orientation, 'horizontal');
54                     setOption('selection', attrs.selection, 'before');
55                     setOption('handle', attrs.handle, 'round');
56                     setOption('tooltip', attrs.sliderTooltip || attrs.tooltip, 'show');
57                     setOption('tooltip_position', attrs.sliderTooltipPosition, 'top');
58                     setOption('tooltipseparator', attrs.tooltipseparator, ':');
59                     setOption('ticks', $scope.ticks);
60                     setOption('ticks_labels', $scope.ticksLabels);
61                     setOption('ticks_snap_bounds', $scope.ticksSnapBounds);
62                     setOption('ticks_positions', $scope.ticksPositions);
63                     setOption('scale', $scope.scale, 'linear');
64                     setOption('focus', $scope.focus);
65
66                     setFloatOption('min', $scope.min, 0);
67                     setFloatOption('max', $scope.max, 10);
68                     setFloatOption('step', $scope.step, 1);
69                     var strNbr = options.step + '';
70                     var dotPos = strNbr.search(/[^.,]*$/);
71                     var decimals = strNbr.substring(dotPos);
72                     setFloatOption('precision', attrs.precision, decimals.length);
73
74                     setBooleanOption('tooltip_split', attrs.tooltipsplit, false);
75                     setBooleanOption('enabled', attrs.enabled, true);
76                     setBooleanOption('naturalarrowkeys', attrs.naturalarrowkeys, false);
77                     setBooleanOption('reversed', attrs.reversed, false);
78
79                     setBooleanOption('range', $scope.range, false);
80                     if (options.range) {
81                         if (angular.isArray($scope.value)) {
82                             options.value = $scope.value;
83                         }
84                         else if (angular.isString($scope.value)) {
85                             options.value = getArrayOrValue($scope.value);
86                             if (!angular.isArray(options.value)) {
87                                 var value = parseFloat($scope.value);
88                                 if (isNaN(value)) value = 5;
89
90                                 if (value < $scope.min) {
91                                     value = $scope.min;
92                                     options.value = [value, options.max];
93                                 }
94                                 else if (value > $scope.max) {
95                                     value = $scope.max;
96                                     options.value = [options.min, value];
97                                 }
98                                 else {
99                                     options.value = [options.min, options.max];
100                                 }
101                             }
102                         }
103                         else {
104                             options.value = [options.min, options.max]; // This is needed, because of value defined at $.fn.slider.defaults - default value 5 prevents creating range slider
105                         }
106                         $scope.ngModel = options.value; // needed, otherwise turns value into [null, ##]
107                     }
108                     else {
109                         setFloatOption('value', $scope.value, 5);
110                     }
111
112                     if (attrs.formatter) {
113                         options.formatter = function(value) {
114                             return $scope.formatter({value: value});
115                         }
116                     }
117
118                     // check if slider jQuery plugin exists
119                     if ('$' in window && $.fn.slider) {
120                         // adding methods to jQuery slider plugin prototype
121                         $.fn.slider.constructor.prototype.disable = function () {
122                             this.picker.off();
123                         };
124                         $.fn.slider.constructor.prototype.enable = function () {
125                             this.picker.on();
126                         };
127                     }
128
129                     // destroy previous slider to reset all options
130                     if (element[0].__slider)
131                         element[0].__slider.destroy();
132
133                     var slider = new Slider(element[0].getElementsByClassName('slider-input')[0], options);
134                     element[0].__slider = slider;
135
136                     // everything that needs slider element
137                     var updateEvent = getArrayOrValue(attrs.updateevent);
138                     if (angular.isString(updateEvent)) {
139                         // if only single event name in string
140                         updateEvent = [updateEvent];
141                     }
142                     else {
143                         // default to slide event
144                         updateEvent = ['slide'];
145                     }
146                     angular.forEach(updateEvent, function (sliderEvent) {
147                         slider.on(sliderEvent, function (ev) {
148                             ngModelCtrl.$setViewValue(ev);
149                         });
150                     });
151                     slider.on('change', function (ev) {
152                         ngModelCtrl.$setViewValue(ev.newValue);
153                     });
154
155
156                     // Event listeners
157                     var sliderEvents = {
158                         slideStart: 'onStartSlide',
159                         slide: 'onSlide',
160                         slideStop: 'onStopSlide'
161                     };
162                     angular.forEach(sliderEvents, function (sliderEventAttr, sliderEvent) {
163                         var fn = $parse(attrs[sliderEventAttr]);
164                         slider.on(sliderEvent, function (ev) {
165                             if ($scope[sliderEventAttr]) {
166                                 $scope.$apply(function () {
167                                     fn($scope.$parent, { $event: ev, value: ev });
168                                 });
169                             }
170                         });
171                     });
172
173                     // deregister ngDisabled watcher to prevent memory leaks
174                     if (angular.isFunction(ngDisabledDeregisterFn)) {
175                         ngDisabledDeregisterFn();
176                         ngDisabledDeregisterFn = null;
177                     }
178
179                     ngDisabledDeregisterFn = $scope.$watch('ngDisabled', function (value) {
180                         if (value) {
181                             slider.disable();
182                         }
183                         else {
184                             slider.enable();
185                         }
186                     });
187
188                     // deregister ngModel watcher to prevent memory leaks
189                     if (angular.isFunction(ngModelDeregisterFn)) ngModelDeregisterFn();
190                     ngModelDeregisterFn = $scope.$watch('ngModel', function (value) {
191                         if($scope.range){
192                             slider.setValue(value);
193                         }else{
194                             slider.setValue(parseFloat(value));
195                         }
196                         slider.relayout();
197                     }, true);
198
199                     return slider;
200                 }
201
202
203                 var watchers = ['min', 'max', 'step', 'range', 'scale', 'ticksLabels'];
204                 angular.forEach(watchers, function (prop) {
205                     $scope.$watch(prop, function () {
206                         slider = initSlider();
207                     });
208                 });
209
210                 var globalEvents = ['relayout', 'refresh', 'resize'];
211                 angular.forEach(globalEvents, function(event) {
212                     if(angular.isFunction(slider[event])) {
213                         $scope.$on('slider:' + event, function () {
214                             slider[event]();
215                         });
216                     }
217                 });
218             }
219         };
220     }])
221 ;