@@ -12,145 +12,170 @@ angular.module('ui.bootstrap-slider', [])
12
12
value : "=" ,
13
13
ngModel : '=' ,
14
14
range :'=' ,
15
- sliderid :'=' ,
16
- formater :'&' ,
15
+ sliderid : '=' ,
16
+ formater : '&' ,
17
17
onStartSlide : '&' ,
18
18
onStopSlide : '&' ,
19
19
onSlide : '&'
20
20
} ,
21
21
link : function ( $scope , element , attrs , ngModelCtrl , $compile ) {
22
+ var ngModelDeregisterFn , ngDisabledDeregisterFn ;
23
+
22
24
initSlider ( ) ;
23
25
24
26
function initSlider ( ) {
25
- $ . fn . slider . constructor . prototype . disable = function ( ) {
26
- this . picker . off ( ) ;
27
- } ;
28
-
29
- $ . fn . slider . constructor . prototype . enable = function ( ) {
30
- this . picker . on ( ) ;
31
- } ;
32
-
33
27
var options = { } ;
34
- if ( $scope . sliderid ) options . id = $scope . sliderid ;
35
- if ( $scope . min ) options . min = parseFloat ( $scope . min ) ;
36
- if ( $scope . max ) {
37
- options . max = parseFloat ( $scope . max ) ;
38
- }
39
-
40
28
41
- if ( attrs . step ) options . step = parseFloat ( $scope . step ) ;
42
- if ( attrs . precision ) options . precision = parseFloat ( attrs . precision ) ;
43
- if ( attrs . orientation ) options . orientation = attrs . orientation ;
44
- if ( $scope . value ) {
45
- if ( angular . isNumber ( $scope . value ) || angular . isArray ( $scope . value ) ) {
46
- options . value = $scope . value ;
47
- } else if ( angular . isString ( $scope . value ) ) {
48
- if ( attrs . value . indexOf ( "[" ) === 0 ) {
49
- options . value = angular . fromJson ( $scope . value ) ;
50
- } else {
51
- options . value = parseFloat ( $scope . value ) ;
52
- }
53
- }
29
+ function setOption ( key , value , defaultValue ) {
30
+ options [ key ] = value || defaultValue ;
54
31
}
55
- if ( $scope . range ) {
56
- options . range = $scope . range === true ;
32
+ function setFloatOption ( key , value , defaultValue ) {
33
+ options [ key ] = value ? parseFloat ( value ) : defaultValue ;
57
34
}
58
-
59
- if ( attrs . selection ) options . selection = attrs . selection ;
60
- if ( attrs . tooltip ) options . tooltip = attrs . tooltip ;
61
- if ( attrs . tooltipseparator ) options . tooltip_separator = attrs . tooltipseparator ;
62
- if ( attrs . tooltipsplit ) options . tooltip_split = attrs . tooltipsplit === 'true' ;
63
- if ( attrs . handle ) options . handle = attrs . handle ;
64
- if ( attrs . reversed ) options . reversed = attrs . reversed === 'true' ;
65
- if ( attrs . enabled ) options . enabled = attrs . enabled === 'true' ;
66
- if ( attrs . naturalarrowkeys ) options . natural_arrow_keys = attrs . naturalarrowkeys === 'true' ;
67
- if ( attrs . formater ) options . formater = $scope . $eval ( $scope . formater ) ;
68
-
69
- if ( options . range && ! options . value ) {
70
- options . value = [ 0 , 0 ] ; // This is needed, because of value defined at $.fn.slider.defaults - default value 5 prevents creating range slider
35
+ function setBooleanOption ( key , value , defaultValue ) {
36
+ options [ key ] = value ? value + '' === 'true' : defaultValue ;
37
+ }
38
+ function getArrayOrValue ( value ) {
39
+ return ( angular . isString ( value ) && value . indexOf ( "[" ) === 0 ) ? angular . fromJson ( value ) : value ;
71
40
}
72
41
73
- var slider = $ ( element . find ( ".slider-input" ) [ 0 ] ) . slider ( options ) ;
74
- slider . slider ( 'destroy' ) ;
75
- slider = $ ( element . find ( ".slider-input" ) [ 0 ] ) . slider ( options ) ;
76
-
77
- var updateEvent ;
78
- if ( angular . isString ( attrs . updateevent ) ) {
79
- // check if array of event names
80
- if ( attrs . updateevent . indexOf ( "[" ) === 0 ) {
81
- updateEvent = angular . fromJson ( attrs . updateevent ) ;
42
+ setOption ( 'id' , $scope . sliderid ) ;
43
+ setOption ( 'orientation' , attrs . orientation , 'horizontal' ) ;
44
+ setOption ( 'selection' , attrs . selection , 'before' ) ;
45
+ setOption ( 'handle' , attrs . handle , 'round' ) ;
46
+ setOption ( 'tooltip' , attrs . tooltip , 'show' ) ;
47
+ setOption ( 'tooltipseparator' , attrs . tooltipseparator , ':' ) ;
48
+
49
+ setFloatOption ( 'min' , $scope . min , 0 ) ;
50
+ setFloatOption ( 'max' , $scope . max , 10 ) ;
51
+ setFloatOption ( 'step' , $scope . step , 1 ) ;
52
+ var strNbr = options . step + '' ;
53
+ var decimals = strNbr . substring ( strNbr . lastIndexOf ( '.' ) + 1 ) ;
54
+ setFloatOption ( 'precision' , attrs . precision , decimals ) ;
55
+
56
+ setBooleanOption ( 'tooltip_split' , attrs . tooltipsplit , false ) ;
57
+ setBooleanOption ( 'enabled' , attrs . enabled , true ) ;
58
+ setBooleanOption ( 'naturalarrowkeys' , attrs . naturalarrowkeys , false ) ;
59
+ setBooleanOption ( 'reversed' , attrs . reversed , false ) ;
60
+
61
+ setBooleanOption ( 'range' , $scope . range , false ) ;
62
+ if ( options . range ) {
63
+ if ( angular . isArray ( $scope . value ) ) {
64
+ options . value = $scope . value ;
65
+ }
66
+ else if ( angular . isString ( $scope . value ) ) {
67
+ options . value = getArrayOrValue ( $scope . value ) ;
68
+ if ( ! angular . isArray ( options . value ) ) {
69
+ var value = parseFloat ( $scope . value ) ;
70
+ if ( isNaN ( value ) ) value = 5 ;
71
+
72
+ if ( value < $scope . min ) {
73
+ value = $scope . min ;
74
+ options . value = [ value , options . max ] ;
75
+ }
76
+ else if ( value > $scope . max ) {
77
+ value = $scope . max ;
78
+ options . value = [ options . min , value ] ;
79
+ }
80
+ else {
81
+ options . value = [ options . min , options . max ] ;
82
+ }
83
+ }
82
84
}
83
85
else {
84
- // if only single event name in string
85
- updateEvent = [ attrs . updateevent ] ;
86
+ options . value = [ options . min , options . max ] ; // This is needed, because of value defined at $.fn.slider.defaults - default value 5 prevents creating range slider
86
87
}
88
+ $scope . ngModel = options . value ; // needed, otherwise turns value into [null, ##]
87
89
}
88
90
else {
89
- // default to slide event
90
- updateEvent = [ 'slide' ] ;
91
+ setFloatOption ( 'value' , $scope . value , 5 ) ;
91
92
}
92
93
93
- angular . forEach ( updateEvent , function ( sliderEvent ) {
94
- slider . on ( sliderEvent , function ( ev ) {
95
- ngModelCtrl . $setViewValue ( ev . value ) ;
96
- $timeout ( function ( ) {
97
- $scope . $apply ( ) ;
98
- } ) ;
99
- } ) ;
100
- } ) ;
101
-
102
- // Event listeners
103
- var sliderEvents = {
104
- slideStart : 'onStartSlide' ,
105
- slide : 'onSlide' ,
106
- slideStop : 'onStopSlide'
107
- } ;
108
-
109
- angular . forEach ( sliderEvents , function ( sliderEventAttr , sliderEvent ) {
110
- slider . on ( sliderEvent , function ( ev ) {
111
-
112
- if ( $scope [ sliderEventAttr ] ) {
113
- var invoker = $parse ( attrs [ sliderEventAttr ] ) ;
114
- invoker ( $scope . $parent , { $event : ev , value : ev . value } ) ;
115
-
116
- $timeout ( function ( ) {
94
+ if ( $scope . formater ) options . formater = $scope . $eval ( $scope . formater ) ;
95
+
96
+ var slider = element . find ( ".slider-input" ) . eq ( 0 ) ;
97
+ // check if slider jQuery plugin exists
98
+ if ( $ . fn . slider ) {
99
+ // adding methods to jQuery slider plugin prototype
100
+ $ . fn . slider . Constructor . prototype . disable = function ( ) {
101
+ this . picker . off ( ) ;
102
+ } ;
103
+ $ . fn . slider . Constructor . prototype . enable = function ( ) {
104
+ this . picker . on ( ) ;
105
+ } ;
106
+
107
+ // destroy previous slider to reset all options
108
+ slider . slider ( options ) ;
109
+ slider . slider ( 'destroy' ) ;
110
+ slider . slider ( options ) ;
111
+
112
+ // everything that needs slider element
113
+ var updateEvent = getArrayOrValue ( attrs . updateevent ) ;
114
+ if ( angular . isString ( updateEvent ) ) {
115
+ // if only single event name in string
116
+ updateEvent = [ updateEvent ] ;
117
+ }
118
+ else {
119
+ // default to slide event
120
+ updateEvent = [ 'slide' ] ;
121
+ }
122
+ angular . forEach ( updateEvent , function ( sliderEvent ) {
123
+ slider . on ( sliderEvent , function ( ev ) {
124
+ ngModelCtrl . $setViewValue ( ev . value ) ;
125
+ $timeout ( function ( ) {
117
126
$scope . $apply ( ) ;
118
- } ) ;
119
- }
120
- } ) ;
121
- } ) ;
122
-
123
-
124
- if ( angular . isDefined ( attrs . ngDisabled ) ) {
125
- $scope . $watch ( attrs . ngDisabled , function ( value ) {
126
- if ( value ) {
127
- slider . slider ( 'disable' ) ;
128
- } else {
129
- slider . slider ( 'enable' ) ;
130
- }
131
- } ) ;
127
+ } ) ;
128
+ } ) ;
129
+ } ) ;
130
+
131
+ // Event listeners
132
+ var sliderEvents = {
133
+ slideStart : 'onStartSlide' ,
134
+ slide : 'onSlide' ,
135
+ slideStop : 'onStopSlide'
136
+ } ;
137
+ angular . forEach ( sliderEvents , function ( sliderEventAttr , sliderEvent ) {
138
+ slider . on ( sliderEvent , function ( ev ) {
139
+
140
+ if ( $scope [ sliderEventAttr ] ) {
141
+ var invoker = $parse ( attrs [ sliderEventAttr ] ) ;
142
+ invoker ( $scope . $parent , { $event : ev , value : ev . value } ) ;
143
+
144
+ $timeout ( function ( ) {
145
+ $scope . $apply ( ) ;
146
+ } ) ;
147
+ }
148
+ } ) ;
149
+ } ) ;
150
+
151
+ // deregister ngDisabled watcher to prevent memory leaks
152
+ if ( angular . isFunction ( ngDisabledDeregisterFn ) ) {
153
+ ngDisabledDeregisterFn ( ) ;
154
+ ngDisabledDeregisterFn = null ;
155
+ }
156
+ if ( angular . isDefined ( attrs . ngDisabled ) ) {
157
+ ngDisabledDeregisterFn = $scope . $watch ( attrs . ngDisabled , function ( value ) {
158
+ if ( value ) {
159
+ slider . slider ( 'disable' ) ;
160
+ }
161
+ else {
162
+ slider . slider ( 'enable' ) ;
163
+ }
164
+ } ) ;
165
+ }
166
+ // deregister ngModel watcher to prevent memory leaks
167
+ if ( angular . isFunction ( ngModelDeregisterFn ) ) ngModelDeregisterFn ( ) ;
168
+ ngModelDeregisterFn = $scope . $watch ( 'ngModel' , function ( value ) {
169
+ slider . slider ( 'setValue' , value ) ;
170
+ } ) ;
132
171
}
172
+ }
133
173
134
-
135
- $scope . $watch ( 'ngModel' , function ( value ) {
136
- slider . slider ( 'setValue' , value ) ;
174
+ var watchers = [ 'min' , 'max' , 'step' , 'range' ] ;
175
+ angular . forEach ( watchers , function ( prop ) {
176
+ $scope . $watch ( prop , function ( ) {
177
+ initSlider ( ) ;
137
178
} ) ;
138
- } ;
139
-
140
- $scope . $watch ( 'max' , function ( value ) {
141
- initSlider ( ) ;
142
- } ) ;
143
-
144
- $scope . $watch ( 'min' , function ( value ) {
145
- initSlider ( ) ;
146
- } ) ;
147
-
148
- $scope . $watch ( 'step' , function ( value ) {
149
- initSlider ( ) ;
150
- } ) ;
151
-
152
- $scope . $watch ( 'range' , function ( value ) {
153
- initSlider ( ) ;
154
179
} ) ;
155
180
}
156
181
} ;
0 commit comments