jquery-nouislider-rails 3.2.1 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -8
- data/lib/jquery-nouislider-rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.nouislider.js +761 -299
- data/vendor/assets/stylesheets/jquery.nouislider.css +111 -0
- metadata +5 -13
- data/vendor/assets/stylesheets/nouislider.fox.css +0 -94
- data/vendor/assets/stylesheets/nouislider.space.css +0 -112
data/README.md
CHANGED
@@ -18,15 +18,11 @@ And then execute:
|
|
18
18
|
In your app/assets/javascript manifest file:
|
19
19
|
//=require jquery.nouislider
|
20
20
|
|
21
|
-
In your app/assets/stylesheets manifest file
|
22
|
-
|
23
|
-
//=require 'nouislider.fox.css'
|
24
|
-
|
25
|
-
or
|
26
|
-
|
27
|
-
//=require 'nouislider.space.css'
|
21
|
+
In your app/assets/stylesheets manifest file:
|
22
|
+
//=require jquery.nouislider
|
28
23
|
|
29
|
-
You are encouraged to use your own stylesheet
|
24
|
+
You are encouraged to use your own stylesheet. The styles for 4.0 have change significantly.
|
25
|
+
A reference is here: http://refreshless.com/nouislider/slider-design-styles
|
30
26
|
|
31
27
|
## Contributing
|
32
28
|
|
@@ -1,364 +1,826 @@
|
|
1
|
-
/* noUiSlider
|
2
|
-
(function
|
3
|
-
|
4
|
-
$.fn.noUiSlider = function
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if (typeof f === "function") {
|
15
|
-
f.call(scope, args);
|
1
|
+
/* noUiSlider 4.0.0 */
|
2
|
+
(function($, UNDEF){
|
3
|
+
|
4
|
+
$.fn.noUiSlider = function( options ){
|
5
|
+
|
6
|
+
var namespace = '.nui'
|
7
|
+
// Create a shorthand for document event binding
|
8
|
+
,all = $(document)
|
9
|
+
// Create a map of touch and mouse actions
|
10
|
+
,actions = {
|
11
|
+
start: 'mousedown' + namespace + ' touchstart' + namespace
|
12
|
+
,move: 'mousemove' + namespace + ' touchmove' + namespace
|
13
|
+
,end: 'mouseup' + namespace + ' touchend' + namespace
|
16
14
|
}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
15
|
+
// Make a copy of the current val function.
|
16
|
+
,$VAL = $.fn.val
|
17
|
+
// Define a set of standard HTML classes for
|
18
|
+
// the various structures noUiSlider uses.
|
19
|
+
,clsList = [
|
20
|
+
'noUi-base' // 0
|
21
|
+
,'noUi-origin' // 1
|
22
|
+
,'noUi-handle' // 2
|
23
|
+
,'noUi-input' // 3
|
24
|
+
,'noUi-active' // 4
|
25
|
+
,'noUi-state-tap' // 5
|
26
|
+
,'noUi-target' // 6
|
27
|
+
,'-lower' // 7
|
28
|
+
,'-upper' // 8
|
29
|
+
,'noUi-connect' // 9
|
30
|
+
,'noUi-vertical' // 10
|
31
|
+
,'noUi-horizontal' // 11
|
32
|
+
,'handles' // 12
|
33
|
+
,'noUi-background' // 13
|
34
|
+
,'noUi-z-index' // 14
|
35
|
+
]
|
36
|
+
,stdCls = {
|
37
|
+
base: [clsList[0], clsList[13]]
|
38
|
+
,origin: [clsList[1]]
|
39
|
+
,handle: [clsList[2]]
|
33
40
|
}
|
41
|
+
,percentage = {
|
42
|
+
to : function (range, value) {
|
43
|
+
value = range[0] < 0 ? value + Math.abs(range[0]) : value - range[0];
|
44
|
+
return (value * 100) / this._length(range);
|
45
|
+
},
|
46
|
+
from : function (range, value) {
|
47
|
+
return (value * 100) / this._length(range);
|
48
|
+
},
|
49
|
+
is : function (range, value) {
|
50
|
+
return ((value * this._length(range)) / 100) + range[0];
|
51
|
+
},
|
52
|
+
_length : function (range) {
|
53
|
+
return (range[0] > range[1] ? range[0] - range[1] : range[1] - range[0]);
|
54
|
+
}
|
55
|
+
};
|
56
|
+
|
57
|
+
if ( window.navigator.msPointerEnabled ) {
|
58
|
+
actions = {
|
59
|
+
start: 'MSPointerDown' + namespace
|
60
|
+
,move: 'MSPointerMove' + namespace
|
61
|
+
,end: 'MSPointerUp' + namespace
|
62
|
+
};
|
63
|
+
}
|
64
|
+
|
65
|
+
function __sp ( e ) {
|
66
|
+
e.stopPropagation();
|
34
67
|
}
|
35
68
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
setup = slider.data('setup'),
|
41
|
-
handles = setup.handles,
|
42
|
-
settings = setup.settings,
|
43
|
-
pos = setup.pos;
|
44
|
-
|
45
|
-
proposal = proposal < 0 ? 0 : proposal > 100 ? 100 : proposal;
|
46
|
-
|
47
|
-
if (settings.handles == 2) {
|
48
|
-
if (handle.is(':first-child')) {
|
49
|
-
var other = parseFloat(handles[1][0].style[pos]) - settings.margin;
|
50
|
-
proposal = proposal > other ? other : proposal;
|
51
|
-
} else {
|
52
|
-
var other = parseFloat(handles[0][0].style[pos]) + settings.margin;
|
53
|
-
proposal = proposal < other ? other : proposal;
|
69
|
+
function call ( f, scope, args ) {
|
70
|
+
$.each(f,function(i,q){
|
71
|
+
if (typeof q === "function") {
|
72
|
+
q.call(scope, args);
|
54
73
|
}
|
74
|
+
});
|
75
|
+
}
|
76
|
+
|
77
|
+
function blocked ( e ) {
|
78
|
+
return ( e.data.base.data('target').is('[class*="noUi-state-"], [disabled]') );
|
79
|
+
}
|
80
|
+
|
81
|
+
function fixEvent ( e, preventDefault ) {
|
82
|
+
|
83
|
+
// Required (in at the very least Chrome) to prevent
|
84
|
+
// scrolling and panning while attempting to slide.
|
85
|
+
// The tap event also depends on this.
|
86
|
+
if( preventDefault ) {
|
87
|
+
e.preventDefault();
|
55
88
|
}
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
89
|
+
|
90
|
+
var jQueryEvent = e
|
91
|
+
,touch = e.type.indexOf('touch') === 0
|
92
|
+
,mouse = e.type.indexOf('mouse') === 0
|
93
|
+
,pointer = e.type.indexOf('MSPointer') === 0
|
94
|
+
,x,y;
|
95
|
+
|
96
|
+
e = e.originalEvent;
|
97
|
+
|
98
|
+
if (touch) {
|
99
|
+
x = e.changedTouches[0].pageX;
|
100
|
+
y = e.changedTouches[0].pageY;
|
60
101
|
}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
102
|
+
if (mouse) {
|
103
|
+
|
104
|
+
// Polyfill the pageXOffset and pageYOffset
|
105
|
+
// variables for IE7 and IE8;
|
106
|
+
if(window.pageXOffset === UNDEF){
|
107
|
+
window.pageXOffset = document.documentElement.scrollLeft;
|
108
|
+
window.pageYOffset = document.documentElement.scrollTop;
|
109
|
+
}
|
110
|
+
|
111
|
+
x = e.clientX + window.pageXOffset;
|
112
|
+
y = e.clientY + window.pageYOffset;
|
72
113
|
}
|
114
|
+
if (pointer) {
|
115
|
+
x = e.pageX;
|
116
|
+
y = e.pageY;
|
117
|
+
}
|
118
|
+
|
119
|
+
return { pass: jQueryEvent.data, e:e, x:x, y:y, t: [touch, mouse, pointer] };
|
120
|
+
|
73
121
|
}
|
74
122
|
|
75
|
-
|
76
|
-
|
77
|
-
return parseFloat(handle[0].style[pos]);
|
123
|
+
function getPercentage( a ){
|
124
|
+
return parseFloat(this.style[a]);
|
78
125
|
}
|
126
|
+
|
127
|
+
function test ( o, set ){
|
79
128
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
129
|
+
// checks is number is numerical
|
130
|
+
function num(e){
|
131
|
+
return !isNaN(e) && isFinite(e);
|
132
|
+
}
|
133
|
+
function ser(r){
|
134
|
+
return ( r instanceof $ || typeof r === 'string' || r === false );
|
86
135
|
}
|
87
|
-
};
|
88
|
-
|
89
|
-
// contains all methods
|
90
|
-
methods = {
|
91
|
-
create : function () {
|
92
|
-
|
93
|
-
return this.each(function () {
|
94
136
|
|
95
|
-
|
96
|
-
|
97
|
-
|
137
|
+
|
138
|
+
/**
|
139
|
+
These tests are structured with an item for every option available.
|
140
|
+
Every item contains an 'r' flag, which marks a required option, and
|
141
|
+
a 't' function, which in turn takes some arguments:
|
142
|
+
- a reference to options object
|
143
|
+
- the value for the option
|
144
|
+
- the option name (optional);
|
145
|
+
The testing function returns false when an error is detected,
|
146
|
+
or true when everything is OK. Every test also has an 'init'
|
147
|
+
method which appends the parent object to all children.
|
148
|
+
**/
|
149
|
+
var TESTS = {
|
150
|
+
"handles": {
|
151
|
+
r: true // has default
|
152
|
+
,t: function(o,q){
|
153
|
+
q = parseInt(q, 10);
|
154
|
+
return ( q === 1 || q === 2 );
|
98
155
|
}
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
res = split[0] == 1 ? 0 : split[1].length;
|
121
|
-
|
122
|
-
settings.start = num(settings.start) ? [settings.start, 0] : settings.start;
|
123
|
-
|
124
|
-
// logs bad input values, if possible
|
125
|
-
$.each(settings, function (a, b) {
|
126
|
-
|
127
|
-
if (num(b)) {
|
128
|
-
settings[a] = parseFloat(b);
|
129
|
-
} else if (typeof b == "object" && num(b[0])) {
|
130
|
-
b[0] = parseFloat(b[0]);
|
131
|
-
if (num(b[1])) {
|
132
|
-
b[1] = parseFloat(b[1]);
|
156
|
+
}
|
157
|
+
,"range": {
|
158
|
+
r: true
|
159
|
+
,t: function(o,q,w){
|
160
|
+
if(q.length!==2){
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
q = [parseFloat(q[0]),parseFloat(q[1])];
|
164
|
+
if(!num(q[0])||!num(q[1])){
|
165
|
+
return false;
|
166
|
+
}
|
167
|
+
o[w]=q;
|
168
|
+
return true;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
,"start": {
|
172
|
+
r: true
|
173
|
+
,t: function(o,q,w){
|
174
|
+
if(o.handles === 1){
|
175
|
+
if($.isArray(q)){
|
176
|
+
q=q[0];
|
133
177
|
}
|
178
|
+
q = parseFloat(q);
|
179
|
+
o.start = [q];
|
180
|
+
return num(q);
|
134
181
|
}
|
182
|
+
return this.parent.range.t(o,q,w);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
,"connect": {
|
186
|
+
t: function(o,q){
|
187
|
+
return ( q === true
|
188
|
+
|| q === false
|
189
|
+
|| ( q === 'lower' && o.handles === 1)
|
190
|
+
|| ( q === 'upper' && o.handles === 1));
|
191
|
+
}
|
192
|
+
}
|
193
|
+
,"orientation": {
|
194
|
+
t: function(o,q){
|
195
|
+
return ( q === "horizontal" || q === "vertical" );
|
196
|
+
}
|
197
|
+
}
|
198
|
+
,"margin": {
|
199
|
+
r: true // has default
|
200
|
+
,t: function(o,q,w){
|
201
|
+
q = parseFloat(q);
|
202
|
+
o[w]=q;
|
203
|
+
return num(q);
|
204
|
+
}
|
205
|
+
}
|
206
|
+
,"serialization": {
|
207
|
+
r: true // has default
|
208
|
+
,t: function(o,q){
|
135
209
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
case 'orientation':
|
151
|
-
e = (b != "vertical" && b != "horizontal");
|
152
|
-
break;
|
153
|
-
case 'margin':
|
154
|
-
case 'step':
|
155
|
-
e = typeof b != "undefined" && !num(b);
|
156
|
-
break;
|
157
|
-
case 'serialization':
|
158
|
-
e = typeof b != "object" || !num(b.resolution) || (typeof b.to == 'object' && b.to.length < settings.handles);
|
159
|
-
break;
|
160
|
-
case 'slide':
|
161
|
-
e = typeof b != "function";
|
162
|
-
break;
|
210
|
+
if(!q.resolution){
|
211
|
+
o.serialization.resolution = 0.01;
|
212
|
+
} else {
|
213
|
+
switch(q.resolution){
|
214
|
+
case 1:
|
215
|
+
case 0.1:
|
216
|
+
case 0.01:
|
217
|
+
case 0.001:
|
218
|
+
case 0.0001:
|
219
|
+
case 0.00001:
|
220
|
+
break;
|
221
|
+
default:
|
222
|
+
return false;
|
223
|
+
}
|
163
224
|
}
|
164
225
|
|
165
|
-
if
|
166
|
-
|
167
|
-
|
226
|
+
if(q.to){
|
227
|
+
|
228
|
+
if(o.handles === 1){
|
229
|
+
if(!$.isArray(q.to)){
|
230
|
+
q.to = [q.to];
|
231
|
+
}
|
232
|
+
o.serialization.to = q.to;
|
233
|
+
return ser(q.to[0]);
|
234
|
+
}
|
235
|
+
return (q.to.length === 2 && ser(q.to[0]) && ser(q.to[1]));
|
168
236
|
|
237
|
+
}
|
238
|
+
|
239
|
+
return false;
|
240
|
+
|
241
|
+
}
|
242
|
+
}
|
243
|
+
,"slide": {
|
244
|
+
t: function(o,q){
|
245
|
+
return typeof q === "function";
|
246
|
+
}
|
247
|
+
}
|
248
|
+
,"step": {
|
249
|
+
t: function(o,q,w){
|
250
|
+
return this.parent.margin.t(o,q,w);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
,"init": function(){
|
254
|
+
var obj = this;
|
255
|
+
$.each(obj,function(i,c){
|
256
|
+
c.parent = obj;
|
169
257
|
});
|
258
|
+
delete this.init;
|
259
|
+
return this;
|
260
|
+
}
|
261
|
+
},
|
262
|
+
|
263
|
+
// Prepare a set of tests, by adding some internal reference
|
264
|
+
// values not available in native Javascript object implementation.
|
265
|
+
a = TESTS.init();
|
266
|
+
|
267
|
+
// Loop all provided tests;
|
268
|
+
// v is the option set, i is the index for the current test.
|
269
|
+
$.each(a, function( i, v ){
|
270
|
+
|
271
|
+
// If the value is required but not set,
|
272
|
+
// or if the test fails, throw an error.
|
273
|
+
if((v.r && (!o[i] && o[i] !== 0)) || ((o[i] || o[i] === 0) && !v.t(o,o[i],i))){
|
274
|
+
|
275
|
+
// For debugging purposes it might be very useful
|
276
|
+
// to know what option caused the trouble.
|
277
|
+
if(console&&console.log){
|
278
|
+
console.log(
|
279
|
+
"Slider:\t\t\t", set,
|
280
|
+
"\nOption:\t\t\t", i,
|
281
|
+
"\nValue:\t\t\t", o[i]
|
282
|
+
);
|
283
|
+
}
|
284
|
+
$.error("Error on noUiSlider initialisation.");
|
285
|
+
return false;
|
286
|
+
}
|
170
287
|
|
171
|
-
|
288
|
+
});
|
172
289
|
|
173
|
-
|
174
|
-
|
175
|
-
|
290
|
+
}
|
291
|
+
|
292
|
+
function closest( value, to ){
|
293
|
+
return Math.round(value / to) * to;
|
294
|
+
}
|
295
|
+
|
296
|
+
function setHandle ( handle, to, forgive ) {
|
297
|
+
|
298
|
+
var nui = handle.data('nui').options
|
299
|
+
// Get the array of handles from the base.
|
300
|
+
// Will be undefined at initialisation.
|
301
|
+
,handles = handle.data('nui').base.data(clsList[12])
|
302
|
+
// Get some settings from the handle
|
303
|
+
,style = handle.data('nui').style
|
304
|
+
,dec = handle.data('nui').decimals
|
305
|
+
,hLimit;
|
306
|
+
|
307
|
+
// Ignore the call if the handle won't move anyway.
|
308
|
+
if(to === handle[0].getPercentage(style)) {
|
309
|
+
return false;
|
310
|
+
}
|
311
|
+
|
312
|
+
// Limit `to` to 0 - 100
|
313
|
+
to = to < 0 ? 0 : to > 100 ? 100 : to;
|
314
|
+
|
315
|
+
// Handle the step option, or ignore it.
|
316
|
+
if( nui.step && !forgive ){
|
317
|
+
to = closest( to, percentage.from(nui.range, nui.step));
|
318
|
+
}
|
319
|
+
|
320
|
+
// Stop handling this call if the handle won't step to a new value.
|
321
|
+
if(to === handle[0].getPercentage(style)) {
|
322
|
+
return false;
|
323
|
+
}
|
324
|
+
|
325
|
+
// We're done if this is the only handle,
|
326
|
+
// if the handle bounce is trusted to the user
|
327
|
+
// or on initialisation when handles isn't defined yet.
|
328
|
+
if( handle.siblings('.' + clsList[1]).length && !forgive && handles ){
|
329
|
+
|
330
|
+
// Otherwise, the handle should bounce,
|
331
|
+
// and stop at the other handle.
|
332
|
+
if ( handle.data('nui').number ) {
|
333
|
+
hLimit = handles[0][0].getPercentage(style) + nui.margin;
|
334
|
+
to = to < hLimit ? hLimit : to;
|
335
|
+
} else {
|
336
|
+
hLimit = handles[1][0].getPercentage(style) - nui.margin;
|
337
|
+
to = to > hLimit ? hLimit : to;
|
338
|
+
}
|
339
|
+
|
340
|
+
// Stop handling this call if the handle can't move past another.
|
341
|
+
if(to === handle[0].getPercentage(style)) {
|
342
|
+
return false;
|
343
|
+
}
|
344
|
+
|
345
|
+
}
|
346
|
+
|
347
|
+
// Fix for the z-index issue where the lower handle gets stuck
|
348
|
+
// below the upper one. Since this function is called for every
|
349
|
+
// movement, toggleClass cannot be used.
|
350
|
+
if(handle.data('nui').number === 0 && to > 95){
|
351
|
+
handle.addClass(clsList[14]);
|
352
|
+
} else {
|
353
|
+
handle.removeClass(clsList[14]);
|
354
|
+
}
|
355
|
+
|
356
|
+
// Set handle to new location
|
357
|
+
handle.css( style , to + '%');
|
358
|
+
|
359
|
+
// Write the value to the serialization object.
|
360
|
+
handle.data('store').val(percentage.is(nui.range, to).toFixed(dec));
|
361
|
+
|
362
|
+
return true;
|
363
|
+
|
364
|
+
}
|
365
|
+
|
366
|
+
function store ( handle, S ) {
|
367
|
+
|
368
|
+
var i = handle.data('nui').number;
|
369
|
+
|
370
|
+
if( S.to[i] instanceof $ ) {
|
371
|
+
|
372
|
+
// Attach a change event to the supplied jQuery object,
|
373
|
+
// which will just trigger the val function on the parent.
|
374
|
+
// In some cases, the change event will not fire on select elements,
|
375
|
+
// so listen to 'blur' too.
|
376
|
+
return S.to[i].on('change'+namespace+' blur'+namespace, function(){
|
377
|
+
var arr = [null, null];
|
378
|
+
arr[i] = $(this).val();
|
379
|
+
handle.data('nui').target.val(arr, true);
|
380
|
+
});
|
381
|
+
|
382
|
+
}
|
383
|
+
|
384
|
+
if ( typeof S.to[i] === "string" ) {
|
385
|
+
|
386
|
+
// Append a new object to the noUiSlider base,
|
387
|
+
// prevent change events flowing upward.
|
388
|
+
return $('<input type="hidden" class="'+clsList[3]+'" name="' + S.to[i] + '">')
|
389
|
+
.appendTo(handle).change(__sp);
|
390
|
+
|
391
|
+
}
|
392
|
+
|
393
|
+
if ( S.to[i] === false ) {
|
394
|
+
|
395
|
+
// Create an object capable of handling all jQuery calls.
|
396
|
+
return {
|
397
|
+
// The value will be stored a data on the handle.
|
398
|
+
val : function(a) {
|
399
|
+
// Value function provides a getter and a setter.
|
400
|
+
// Can't just test for !a, as a might be 0.
|
401
|
+
if ( a === UNDEF ) {
|
402
|
+
// Either set...
|
403
|
+
return this._handle.data('nui-val');
|
404
|
+
}
|
405
|
+
// ... or return;
|
406
|
+
this._handle.data('nui-val', a);
|
176
407
|
}
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
orientation = 1;
|
182
|
-
} else {
|
183
|
-
classes += "horizontal";
|
184
|
-
pos = 'left';
|
185
|
-
orientation = 0;
|
408
|
+
// The object could be mistaken for a jQuery object,
|
409
|
+
// make sure that doesn't trigger any errors.
|
410
|
+
,hasClass: function(){
|
411
|
+
return false;
|
186
412
|
}
|
413
|
+
// The val function needs access to the handle.
|
414
|
+
,_handle: handle
|
415
|
+
};
|
416
|
+
}
|
417
|
+
|
418
|
+
}
|
187
419
|
|
188
|
-
|
420
|
+
function move( event ) {
|
189
421
|
|
190
|
-
|
422
|
+
// This function is called often, keep it light.
|
423
|
+
|
424
|
+
event = fixEvent( event, true );
|
191
425
|
|
192
|
-
|
426
|
+
if(!event) {
|
427
|
+
return;
|
428
|
+
}
|
193
429
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
430
|
+
var base = event.pass.base
|
431
|
+
,style = base.data('style')
|
432
|
+
// Subtract the initial movement from the current event,
|
433
|
+
// while taking vertical sliders into account.
|
434
|
+
,proposal = event.x - event.pass.startEvent.x
|
435
|
+
,baseSize = style === 'left' ? base.width() : base.height();
|
436
|
+
|
437
|
+
if(style === 'top') {
|
438
|
+
proposal = event.y - event.pass.startEvent.y;
|
439
|
+
}
|
440
|
+
|
441
|
+
proposal = event.pass.position + ( ( proposal * 100 ) / baseSize );
|
442
|
+
|
443
|
+
setHandle( event.pass.handle, proposal );
|
200
444
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
445
|
+
// Trigger the 'slide' event, pass the target so that it is 'this'.
|
446
|
+
call(
|
447
|
+
[ event.pass.base.data('options').slide ]
|
448
|
+
,event.pass.base.data('target')
|
449
|
+
);
|
450
|
+
|
451
|
+
}
|
205
452
|
|
206
|
-
|
453
|
+
function end ( event ) {
|
207
454
|
|
208
|
-
|
209
|
-
|
210
|
-
|
455
|
+
if ( blocked( event ) ) {
|
456
|
+
return;
|
457
|
+
}
|
458
|
+
|
459
|
+
// Handle is no longer active;
|
460
|
+
event.data.handle.children().removeClass(clsList[4]);
|
461
|
+
|
462
|
+
// Unbind move and end events, to prevent
|
463
|
+
// them stacking up over and over;
|
464
|
+
all.off(actions.move);
|
465
|
+
all.off(actions.end);
|
466
|
+
$('body').off(namespace);
|
467
|
+
|
468
|
+
event.data.base.data('target').change();
|
469
|
+
|
470
|
+
}
|
211
471
|
|
212
|
-
|
472
|
+
function start ( event ) {
|
213
473
|
|
214
|
-
|
474
|
+
// When the slider is in a transitional state, stop.
|
475
|
+
// Also prevents interaction with disabled sliders.
|
476
|
+
if ( blocked( event ) ) {
|
477
|
+
return;
|
478
|
+
}
|
479
|
+
|
480
|
+
event = fixEvent( event );
|
215
481
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
originalClick = client(e),
|
220
|
-
previousClick = originalClick,
|
221
|
-
previousProposal = false;
|
482
|
+
if(!event) {
|
483
|
+
return;
|
484
|
+
}
|
222
485
|
|
223
|
-
|
486
|
+
var handle = event.pass.handle
|
487
|
+
,position = handle[0].getPercentage( handle.data('nui').style );
|
488
|
+
|
489
|
+
handle.children().addClass('noUi-active');
|
490
|
+
|
491
|
+
// Attach the move event handler, while
|
492
|
+
// passing all relevant information along.
|
493
|
+
all.on(actions.move, {
|
494
|
+
startEvent: event
|
495
|
+
,position: position
|
496
|
+
,base: event.pass.base
|
497
|
+
,handle: handle
|
498
|
+
}, move);
|
499
|
+
|
500
|
+
all.on(actions.end, { base: event.pass.base, handle: handle }, end);
|
501
|
+
|
502
|
+
$('body').on('selectstart' + namespace, function(){ return false; });
|
503
|
+
|
504
|
+
}
|
505
|
+
|
506
|
+
function selfEnd( event ) {
|
507
|
+
// Trigger the end handler. Supply correct data using a
|
508
|
+
// fake object that contains all required information;
|
509
|
+
end({ data: { base: event.data.base, handle: event.data.handle } });
|
510
|
+
// Stop propagation so that the tap handler doesn't interfere;
|
511
|
+
event.stopPropagation();
|
512
|
+
}
|
513
|
+
|
514
|
+
function tap ( event ) {
|
224
515
|
|
225
|
-
|
516
|
+
if ( blocked( event ) || event.data.base.find('.' + clsList[4]).length ) {
|
517
|
+
return;
|
518
|
+
}
|
519
|
+
|
520
|
+
event = fixEvent( event );
|
226
521
|
|
227
|
-
|
522
|
+
// The event handler might have rejected this event.
|
523
|
+
if(!event) {
|
524
|
+
return;
|
525
|
+
}
|
526
|
+
|
527
|
+
// Getting variables from the event is not required, but
|
528
|
+
// shortens other expressions and is far more convenient;
|
529
|
+
var i, handle, base = event.pass.base
|
530
|
+
,handles = event.pass.handles
|
531
|
+
,style = base.data('style')
|
532
|
+
,eventXY = event[style === 'left' ? 'x' : 'y']
|
533
|
+
,baseSize = style === 'left' ? base.width() : base.height()
|
534
|
+
|
535
|
+
// Create a standard set off offsets compensated with the
|
536
|
+
// scroll distance. When required, correct for scrolling.
|
537
|
+
// This is a bug, as far as I can see, in IE(10?).
|
538
|
+
,correction = {
|
539
|
+
x: ( event.t[2] ? window.pageXOffset : 0 )
|
540
|
+
}
|
541
|
+
,offset = {
|
542
|
+
handles: []
|
543
|
+
,base: {
|
544
|
+
left: base.offset().left - correction.x
|
545
|
+
,top: base.offset().top
|
546
|
+
}
|
547
|
+
};
|
548
|
+
|
549
|
+
// Loop handles and add data to the offset list.
|
550
|
+
for (i = 0; i < handles.length; i++ ) {
|
551
|
+
offset.handles.push({
|
552
|
+
left: handles[i].offset().left - correction.x
|
553
|
+
,top: handles[i].offset().top
|
554
|
+
});
|
555
|
+
}
|
556
|
+
|
557
|
+
// Calculate the central point between the handles;
|
558
|
+
var handleCenter = handles.length === 1 ? 0 :
|
559
|
+
(( offset.handles[0][style] + offset.handles[1][style] ) / 2 );
|
560
|
+
|
561
|
+
// If there is just one handle,
|
562
|
+
// or the lower handles in closest to the event,
|
563
|
+
// select the first handle. Otherwise, pick the second.
|
564
|
+
if ( handles.length === 1 || eventXY < handleCenter ){
|
565
|
+
handle = handles[0];
|
566
|
+
} else {
|
567
|
+
handle = handles[1];
|
568
|
+
}
|
228
569
|
|
229
|
-
|
230
|
-
|
231
|
-
|
570
|
+
// Flag the slider as it is now in a transitional state.
|
571
|
+
// Transition takes 300 ms, so re-enable the slider afterwards.
|
572
|
+
base.addClass(clsList[5]);
|
573
|
+
setTimeout(function(){
|
574
|
+
base.removeClass(clsList[5]);
|
575
|
+
}, 300);
|
576
|
+
|
577
|
+
// Calculate the new position for the handle and
|
578
|
+
// trigger the movement.
|
579
|
+
setHandle(
|
580
|
+
handle
|
581
|
+
,(((eventXY - offset.base[style]) * 100) / baseSize)
|
582
|
+
);
|
583
|
+
|
584
|
+
// Trigger the 'slide' event, pass the target so that it is 'this'.
|
585
|
+
call(
|
586
|
+
[ handle.data('nui').options.slide ]
|
587
|
+
,base.data('target')
|
588
|
+
);
|
589
|
+
|
590
|
+
base.data('target').change();
|
232
591
|
|
233
|
-
|
234
|
-
|
592
|
+
}
|
593
|
+
|
594
|
+
function create ( ) {
|
595
|
+
|
596
|
+
return this.each(function( index, target ){
|
597
|
+
|
598
|
+
// Target is the wrapper that will receive all external
|
599
|
+
// scripting interaction. It has no styling and serves no
|
600
|
+
// other function.
|
601
|
+
target = $(target);
|
602
|
+
target.addClass(clsList[6]);
|
603
|
+
|
604
|
+
// Base is the internal main 'bar'.
|
605
|
+
var i, style, decimals, handle
|
606
|
+
,base = $('<div/>').appendTo(target)
|
607
|
+
,handles = []
|
608
|
+
,cls = {
|
609
|
+
base: stdCls.base
|
610
|
+
,origin: [
|
611
|
+
stdCls.origin.concat([clsList[1] + clsList[7]])
|
612
|
+
,stdCls.origin.concat([clsList[1] + clsList[8]])
|
613
|
+
]
|
614
|
+
,handle: [
|
615
|
+
stdCls.handle.concat([clsList[2] + clsList[7]])
|
616
|
+
,stdCls.handle.concat([clsList[2] + clsList[8]])
|
617
|
+
]
|
618
|
+
};
|
619
|
+
|
620
|
+
// Set defaults where applicable;
|
621
|
+
options = $.extend({
|
622
|
+
handles: 2
|
623
|
+
,margin: 0
|
624
|
+
,orientation: "horizontal"
|
625
|
+
}, options) || {};
|
626
|
+
|
627
|
+
// Set a default for serialization;
|
628
|
+
if(!options.serialization){
|
629
|
+
options.serialization = {
|
630
|
+
to : [false, false]
|
631
|
+
,resolution : 0.01
|
632
|
+
};
|
633
|
+
}
|
634
|
+
|
635
|
+
// Run all options through a testing mechanism to ensure correct
|
636
|
+
// input. The test function will throw errors, so there is
|
637
|
+
// no need to capture the result of this call. It should be noted
|
638
|
+
// that options might get modified to be handled properly. E.g.
|
639
|
+
// wrapping integers in arrays.
|
640
|
+
test(options, target);
|
641
|
+
|
642
|
+
// I can't type serialization any more, and it doesn't compress
|
643
|
+
// very well, so shorten it.
|
644
|
+
options.S = options.serialization;
|
645
|
+
|
646
|
+
|
647
|
+
// INCOMPLETE
|
648
|
+
if( options.connect ) {
|
649
|
+
cls.origin[0].push(clsList[9]);
|
650
|
+
if( options.connect === "lower" ){
|
651
|
+
// Add some styling classes to the base;
|
652
|
+
cls.base.push(clsList[9], clsList[9] + clsList[7]);
|
653
|
+
// When using the option 'Lower', there is only one
|
654
|
+
// handle, and thus only one origin.
|
655
|
+
cls.origin[0].push(clsList[13]);
|
656
|
+
} else {
|
657
|
+
cls.base.push(clsList[9] + clsList[8]);
|
658
|
+
}
|
659
|
+
}
|
235
660
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
661
|
+
// Parse the syntactic sugar that is the serialization
|
662
|
+
// resolution option to a usable integer.
|
663
|
+
style = options.orientation === 'vertical' ? 'top' : 'left';
|
664
|
+
|
665
|
+
decimals = options.S.resolution.toString().split('.');
|
666
|
+
// Test ==, not ===
|
667
|
+
decimals = decimals[0] == 1 ? 0 : decimals[1].length;
|
668
|
+
|
669
|
+
// Add classes for horizontal and vertical sliders.
|
670
|
+
// The horizontal class is provided for completeness,
|
671
|
+
// as it isn't used in the default theme.
|
672
|
+
if( options.orientation === "vertical" ){
|
673
|
+
cls.base.push(clsList[10]);
|
674
|
+
} else {
|
675
|
+
cls.base.push(clsList[11]);
|
676
|
+
}
|
677
|
+
|
678
|
+
// Merge base classes with default;
|
679
|
+
base.addClass(cls.base.join(" ")).data('target', target);
|
680
|
+
|
681
|
+
for (i = 0; i < options.handles; i++ ) {
|
682
|
+
|
683
|
+
handle = $('<div><div/></i>').appendTo(base);
|
684
|
+
|
685
|
+
// Add all default and option-specific classes to the
|
686
|
+
// origins and handles.
|
687
|
+
handle.addClass(cls.origin[i].join(" "));
|
688
|
+
handle.children().addClass(cls.handle[i].join(" "));
|
689
|
+
|
690
|
+
// These events are only bound to the visual handle element,
|
691
|
+
// not the `real` origin element.
|
692
|
+
handle.children()
|
693
|
+
.on(actions.start, { base: base, handle: handle }, start)
|
694
|
+
.on(actions.end, { base: base, handle: handle }, selfEnd);
|
695
|
+
|
696
|
+
// Make sure every handle has access to all primary
|
697
|
+
// variables. Can't uses jQuery's .data( obj ) structure
|
698
|
+
// here, as `store` needs some values from the `nui` object.
|
699
|
+
handle.data('nui', {
|
700
|
+
target: target
|
701
|
+
,decimals: decimals
|
702
|
+
,options: options
|
703
|
+
,base: base
|
704
|
+
,style: style
|
705
|
+
,number: i
|
706
|
+
}).data('store', store (
|
707
|
+
handle
|
708
|
+
,options.S
|
709
|
+
));
|
710
|
+
|
711
|
+
// Attach a function to the native DOM element,
|
712
|
+
// since jQuery wont let me get the current value in percentages.
|
713
|
+
handle[0].getPercentage = getPercentage;
|
714
|
+
|
715
|
+
// Make handles loop-able
|
716
|
+
handles.push(handle);
|
717
|
+
|
718
|
+
// Set the handle to its initial position;
|
719
|
+
setHandle(handle, percentage.to(options.range, options.start[i]));
|
241
720
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
721
|
+
}
|
722
|
+
|
723
|
+
// The base could use the handles too;
|
724
|
+
base.data({
|
725
|
+
options: options
|
726
|
+
,handles: handles
|
727
|
+
,style: style
|
728
|
+
});
|
729
|
+
|
730
|
+
target.data({
|
731
|
+
base: base
|
732
|
+
,handles: handles
|
733
|
+
});
|
734
|
+
|
735
|
+
// The tap event.
|
736
|
+
base.on(actions.end, { base: base, handles: handles }, tap);
|
248
737
|
|
249
|
-
|
738
|
+
});
|
250
739
|
|
251
|
-
|
740
|
+
}
|
252
741
|
|
253
|
-
|
254
|
-
$('body').removeClass('TOUCH');
|
255
|
-
if (slider.find('.active').removeClass('active').end().data('_n')) {
|
256
|
-
slider.data('_n', false).change();
|
257
|
-
}
|
742
|
+
function val ( args, ignore ) {
|
258
743
|
|
259
|
-
|
744
|
+
// Setter
|
745
|
+
if( args !== UNDEF ){
|
260
746
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
747
|
+
// If the val is to be set to a number, which is valid
|
748
|
+
// when using a one-handle slider, wrap it in an array.
|
749
|
+
if(!$.isArray(args)){
|
750
|
+
args = [args];
|
751
|
+
}
|
752
|
+
|
753
|
+
// Setting is handled properly for each slider in the data set.
|
754
|
+
return this.each(function(){
|
265
755
|
|
266
|
-
|
756
|
+
$.each($(this).data(clsList[12]), function(i, handle){
|
267
757
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
758
|
+
// The set request might want to ignore this handle.
|
759
|
+
if( args[i] === null ) {
|
760
|
+
return;
|
761
|
+
}
|
762
|
+
|
763
|
+
// Calculate a new position for the handle.
|
764
|
+
var value, current
|
765
|
+
,range = handle.data('nui').options.range
|
766
|
+
,to = percentage.to(
|
767
|
+
range
|
768
|
+
,parseFloat(args[i])
|
769
|
+
),
|
770
|
+
|
771
|
+
// Set handle to new location, and make sure developer
|
772
|
+
// input is always accepted. The ignore flag indicates
|
773
|
+
// input from user facing elements.
|
774
|
+
result = setHandle(handle, to, (ignore === true ? false : true));
|
775
|
+
|
776
|
+
// If the value of the input doesn't match the slider,
|
777
|
+
// reset it.
|
778
|
+
if(!result){
|
779
|
+
|
780
|
+
value = handle.data('store').val();
|
781
|
+
current = percentage.is(range,
|
782
|
+
handle[0].getPercentage(handle.data('nui').style)
|
783
|
+
).toFixed(handle.data('nui').decimals);
|
784
|
+
|
785
|
+
if(value !== current){
|
786
|
+
handle.data('store').val(current);
|
277
787
|
}
|
278
|
-
});
|
279
|
-
}
|
280
|
-
|
281
|
-
for (var i = 0; i < handles.length; i++) {
|
282
|
-
var val = percentage.is(settings.range, place(handles[i], pos)).toFixed(res);
|
283
|
-
if (typeof settings.serialization.to[i] == 'string') {
|
284
|
-
handles[i].data('input',
|
285
|
-
slider.append('<input type="hidden" name="' + settings.serialization.to[i] + '">').find('input:last')
|
286
|
-
.val(val)
|
287
|
-
.change(function (a) {
|
288
|
-
a.stopPropagation();
|
289
|
-
}));
|
290
|
-
} else if (settings.serialization.to[i] == false) {
|
291
|
-
handles[i].data('input', {
|
292
|
-
val : function (a) {
|
293
|
-
if (typeof a != 'undefined') {
|
294
|
-
this.handle.data('noUiVal', a);
|
295
|
-
} else {
|
296
|
-
return this.handle.data('noUiVal');
|
297
|
-
}
|
298
|
-
},
|
299
|
-
handle : handles[i]
|
300
|
-
});
|
301
|
-
} else {
|
302
|
-
handles[i].data('input', settings.serialization.to[i].data('handleNR', i).val(val).change(function () {
|
303
|
-
var arr = [null, null];
|
304
|
-
arr[$(this).data('handleNR')] = $(this).val();
|
305
|
-
slider.val(arr);
|
306
|
-
}));
|
307
788
|
}
|
308
|
-
|
309
|
-
|
310
|
-
$(this).data('setup', {
|
311
|
-
settings : settings,
|
312
|
-
handles : handles,
|
313
|
-
pos : pos,
|
314
|
-
res : res
|
789
|
+
|
315
790
|
});
|
316
791
|
|
317
792
|
});
|
318
|
-
},
|
319
|
-
val : function () {
|
320
|
-
|
321
|
-
if (typeof arguments[0] !== 'undefined') {
|
322
|
-
|
323
|
-
var val = typeof arguments[0] == 'number' ? [arguments[0]] : arguments[0];
|
324
|
-
|
325
|
-
return this.each(function () {
|
326
793
|
|
327
|
-
|
794
|
+
}
|
328
795
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
}
|
334
|
-
}
|
335
|
-
});
|
796
|
+
// Or, if the function was called without arguments,
|
797
|
+
// act as a 'getter';
|
798
|
+
|
799
|
+
var re = [];
|
336
800
|
|
337
|
-
|
801
|
+
// Loop the handles, and get the value from the input
|
802
|
+
// for every handle on its' own.
|
803
|
+
$.each($(this).data(clsList[12]), function(i, handle){
|
804
|
+
re.push( handle.data('store').val() );
|
805
|
+
});
|
338
806
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
re.push(parseFloat(handles[i].data('input').val()));
|
343
|
-
}
|
344
|
-
return re.length == 1 ? re[0] : re;
|
807
|
+
// If the slider has just one handle, return a single value.
|
808
|
+
// Otherwise, return an array.
|
809
|
+
return ( re.length === 1 ? re[0] : re) ;
|
345
810
|
|
346
|
-
}
|
347
|
-
},
|
348
|
-
disabled : function () {
|
349
|
-
return flag ? $(this).addClass('disabled') : $(this).removeClass('disabled');
|
350
|
-
}
|
351
811
|
}
|
352
812
|
|
353
|
-
//
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
return this.
|
358
|
-
|
813
|
+
// Overwrite the native jQuery val() function
|
814
|
+
// with a simple handler. noUiSlider will use the internal
|
815
|
+
// value method, anything else will use the standard method.
|
816
|
+
$.fn.val = function(){
|
817
|
+
return this.hasClass(clsList[6])
|
818
|
+
? val.apply(this, arguments)
|
819
|
+
: $VAL.apply(this, arguments);
|
820
|
+
};
|
359
821
|
|
360
|
-
return
|
822
|
+
return create.apply(this, arguments);
|
361
823
|
|
362
|
-
}
|
824
|
+
};
|
363
825
|
|
364
|
-
}
|
826
|
+
}(jQuery));
|