forked from HackaBXL/2014_think-of-the-children
-
Notifications
You must be signed in to change notification settings - Fork 0
/
slider.js
135 lines (116 loc) · 5.95 KB
/
slider.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
jQuery UI Slider plugin wrapper
*/
angular.module('ui.slider', []).value('uiSliderConfig',{}).directive('uiSlider', ['uiSliderConfig', '$timeout', function(uiSliderConfig, $timeout) {
uiSliderConfig = uiSliderConfig || {};
return {
require: 'ngModel',
compile: function () {
return function (scope, elm, attrs, ngModel) {
function parseNumber(n, decimals) {
return (decimals) ? parseFloat(n) : parseInt(n);
};
var options = angular.extend(scope.$eval(attrs.uiSlider) || {}, uiSliderConfig);
// Object holding range values
var prevRangeValues = {
min: null,
max: null
};
// convenience properties
var properties = ['min', 'max', 'step'];
var useDecimals = (!angular.isUndefined(attrs.useDecimals)) ? true : false;
var init = function() {
// When ngModel is assigned an array of values then range is expected to be true.
// Warn user and change range to true else an error occurs when trying to drag handle
if (angular.isArray(ngModel.$viewValue) && options.range !== true) {
console.warn('Change your range option of ui-slider. When assigning ngModel an array of values then the range option should be set to true.');
options.range = true;
}
// Ensure the convenience properties are passed as options if they're defined
// This avoids init ordering issues where the slider's initial state (eg handle
// position) is calculated using widget defaults
// Note the properties take precedence over any duplicates in options
angular.forEach(properties, function(property) {
if (angular.isDefined(attrs[property])) {
options[property] = parseNumber(attrs[property], useDecimals);
}
});
elm.slider(options);
init = angular.noop;
};
// Find out if decimals are to be used for slider
angular.forEach(properties, function(property) {
// support {{}} and watch for updates
attrs.$observe(property, function(newVal) {
if (!!newVal) {
init();
elm.slider('option', property, parseNumber(newVal, useDecimals));
ngModel.$render();
}
});
});
attrs.$observe('disabled', function(newVal) {
init();
elm.slider('option', 'disabled', !!newVal);
});
// Watch ui-slider (byVal) for changes and update
scope.$watch(attrs.uiSlider, function(newVal) {
init();
if(newVal != undefined) {
elm.slider('option', newVal);
}
}, true);
// Late-bind to prevent compiler clobbering
$timeout(init, 0, true);
// Update model value from slider
elm.bind('slide', function(event, ui) {
ngModel.$setViewValue(ui.values || ui.value);
scope.$apply();
});
// Update slider from model value
ngModel.$render = function() {
init();
var method = options.range === true ? 'values' : 'value';
if (!options.range && isNaN(ngModel.$viewValue) && !(ngModel.$viewValue instanceof Array)) {
ngModel.$viewValue = 0;
}
else if (options.range && !angular.isDefined(ngModel.$viewValue)) {
ngModel.$viewValue = [0,0];
}
// Do some sanity check of range values
if (options.range === true) {
// Check outer bounds for min and max values
if (angular.isDefined(options.min) && options.min > ngModel.$viewValue[0]) {
ngModel.$viewValue[0] = options.min;
}
if (angular.isDefined(options.max) && options.max < ngModel.$viewValue[1]) {
ngModel.$viewValue[1] = options.max;
}
// Check min and max range values
if (ngModel.$viewValue[0] > ngModel.$viewValue[1]) {
// Min value should be less to equal to max value
if (prevRangeValues.min >= ngModel.$viewValue[1])
ngModel.$viewValue[0] = prevRangeValues.min;
// Max value should be less to equal to min value
if (prevRangeValues.max <= ngModel.$viewValue[0])
ngModel.$viewValue[1] = prevRangeValues.max;
}
// Store values for later user
prevRangeValues.min = ngModel.$viewValue[0];
prevRangeValues.max = ngModel.$viewValue[1];
}
elm.slider(method, ngModel.$viewValue);
};
scope.$watch(attrs.ngModel, function() {
if (options.range === true) {
ngModel.$render();
}
}, true);
function destroy() {
elm.slider('destroy');
}
elm.bind('$destroy', destroy);
};
}
};
}]);