Skip to content

Commit 3743d65

Browse files
committed
Merge pull request seiyria#40 from robman87/master
Restructured code without changing features
2 parents 293a66f + 7450bff commit 3743d65

File tree

3 files changed

+353
-188
lines changed

3 files changed

+353
-188
lines changed

slider.js

Lines changed: 139 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -12,145 +12,170 @@ angular.module('ui.bootstrap-slider', [])
1212
value: "=",
1313
ngModel: '=',
1414
range:'=',
15-
sliderid:'=',
16-
formater:'&',
15+
sliderid: '=',
16+
formater: '&',
1717
onStartSlide: '&',
1818
onStopSlide: '&',
1919
onSlide: '&'
2020
},
2121
link: function ($scope, element, attrs, ngModelCtrl, $compile) {
22+
var ngModelDeregisterFn, ngDisabledDeregisterFn;
23+
2224
initSlider();
2325

2426
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-
3327
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-
4028

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;
5431
}
55-
if ($scope.range) {
56-
options.range = $scope.range === true;
32+
function setFloatOption(key, value, defaultValue) {
33+
options[key] = value ? parseFloat(value) : defaultValue;
5734
}
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;
7140
}
7241

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+
}
8284
}
8385
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
8687
}
88+
$scope.ngModel = options.value; // needed, otherwise turns value into [null, ##]
8789
}
8890
else {
89-
// default to slide event
90-
updateEvent = ['slide'];
91+
setFloatOption('value', $scope.value, 5);
9192
}
9293

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 () {
117126
$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+
} );
132171
}
172+
}
133173

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();
137178
});
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();
154179
});
155180
}
156181
};

0 commit comments

Comments
 (0)