nouislider-rails 6.0.1 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/nouislider/rails/version.rb +1 -1
- data/nouislider-rails.gemspec +1 -1
- data/vendor/assets/javascripts/Link.js +389 -0
- data/vendor/assets/javascripts/jquery.nouislider.js +1056 -1454
- data/vendor/assets/stylesheets/jquery.nouislider.css +79 -79
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c836710318e117437b0d7f90ee0208a50214103
|
4
|
+
data.tar.gz: c2f2a7fac403d92f029e1490ba3986e55e040f97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7107eca155b0c8861b5993e252a65b57200c2ee09d211697fed7e898ba71173fe45ecdc280ae984c53e33eb74e64d7c96dd50dbc975adb929158107ca0305f9c
|
7
|
+
data.tar.gz: 5cde020e4e9a4858e4d0ef526d511c90f728bc03754ba033cebb889ad60874ed3de015d0109a43b552de315c3e28385d5964d22585ee53f8310576db675808b2
|
data/nouislider-rails.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Charles Lee"]
|
10
10
|
spec.email = ["chug2k@gmail.com"]
|
11
11
|
spec.summary = "jquery-nouislider.js for the Rails asset pipeline."
|
12
|
-
spec.description = "Currently tracking 6.
|
12
|
+
spec.description = "Currently tracking 6.1 of jquery-noUiSlider: https://github.com/leongersen/noUiSlider). All credit and thanks to @leongersen for the awesome library."
|
13
13
|
spec.homepage = "https://github.com/chug2k/nouislider-rails"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -0,0 +1,389 @@
|
|
1
|
+
/**@preserve
|
2
|
+
$.Link (part of noUiSlider) - WTFPL */
|
3
|
+
|
4
|
+
/*jslint browser: true */
|
5
|
+
/*jslint sub: true */
|
6
|
+
/*jslint white: true */
|
7
|
+
|
8
|
+
(function( $ ){
|
9
|
+
|
10
|
+
'use strict';
|
11
|
+
|
12
|
+
// Throw an error if formatting options are incompatible.
|
13
|
+
function throwEqualError( F, a, b ) {
|
14
|
+
if ( (F[a] || F[b]) && (F[a] === F[b]) ) {
|
15
|
+
throw new Error("(Link) '"+a+"' can't match '"+b+"'.'");
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
// Test in an object is an instance of jQuery or Zepto.
|
20
|
+
function isInstance ( a ) {
|
21
|
+
return a instanceof $ || ( $['zepto'] && $['zepto']['isZ'](a) );
|
22
|
+
}
|
23
|
+
|
24
|
+
var
|
25
|
+
/** @const */ Formatting = [
|
26
|
+
/* 0 */ 'decimals'
|
27
|
+
/* 1 */ ,'mark'
|
28
|
+
/* 2 */ ,'thousand'
|
29
|
+
/* 3 */ ,'prefix'
|
30
|
+
/* 4 */ ,'postfix'
|
31
|
+
/* 5 */ ,'encoder'
|
32
|
+
/* 6 */ ,'decoder'
|
33
|
+
/* 7 */ ,'negative'
|
34
|
+
/* 8 */ ,'negativeBefore'
|
35
|
+
/* 9 */ ,'to'
|
36
|
+
/* 10 */ ,'from'
|
37
|
+
],
|
38
|
+
/** @const */ FormatDefaults = [
|
39
|
+
/* 0 */ 2
|
40
|
+
/* 1 */ ,'.'
|
41
|
+
/* 2 */ ,''
|
42
|
+
/* 3 */ ,''
|
43
|
+
/* 4 */ ,''
|
44
|
+
/* 5 */ ,function(a){ return a; }
|
45
|
+
/* 6 */ ,function(a){ return a; }
|
46
|
+
/* 7 */ ,'-'
|
47
|
+
/* 8 */ ,''
|
48
|
+
/* 9 */ ,function(a){ return a; }
|
49
|
+
/* 10 */ ,function(a){ return a; }
|
50
|
+
];
|
51
|
+
|
52
|
+
|
53
|
+
/** @constructor */
|
54
|
+
function Format( options ){
|
55
|
+
|
56
|
+
// If no settings where provided, the defaults will be loaded.
|
57
|
+
if ( options === undefined ){
|
58
|
+
options = {};
|
59
|
+
}
|
60
|
+
|
61
|
+
if ( typeof options !== 'object' ){
|
62
|
+
throw new Error("(Format) 'format' option must be an object.");
|
63
|
+
}
|
64
|
+
|
65
|
+
var settings = {};
|
66
|
+
|
67
|
+
// Copy all values into a new object.
|
68
|
+
$(Formatting).each(function(i, val){
|
69
|
+
|
70
|
+
if ( options[val] === undefined ){
|
71
|
+
|
72
|
+
settings[val] = FormatDefaults[i];
|
73
|
+
|
74
|
+
// When we aren't loading defaults, validate the entry.
|
75
|
+
} else if ( (typeof options[val]) === (typeof FormatDefaults[i]) ) {
|
76
|
+
|
77
|
+
// Support for up to 7 decimals.
|
78
|
+
// More can't be guaranteed due to floating point issues.
|
79
|
+
if ( val === 'decimals' ){
|
80
|
+
if ( options[val] < 0 || options[val] > 7 ){
|
81
|
+
throw new Error("(Format) 'format.decimals' option must be between 0 and 7.");
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
settings[val] = options[val];
|
86
|
+
|
87
|
+
// If the value isn't valid, emit an error.
|
88
|
+
} else {
|
89
|
+
throw new Error("(Format) 'format."+val+"' must be a " + typeof FormatDefaults[i] + ".");
|
90
|
+
}
|
91
|
+
});
|
92
|
+
|
93
|
+
// Some values can't be extracted from a
|
94
|
+
// string if certain combinations are present.
|
95
|
+
throwEqualError(settings, 'mark', 'thousand');
|
96
|
+
throwEqualError(settings, 'prefix', 'negative');
|
97
|
+
throwEqualError(settings, 'prefix', 'negativeBefore');
|
98
|
+
|
99
|
+
this.settings = settings;
|
100
|
+
}
|
101
|
+
|
102
|
+
// Shorthand for internal value get
|
103
|
+
Format.prototype.v = function ( a ) {
|
104
|
+
return this.settings[a];
|
105
|
+
};
|
106
|
+
|
107
|
+
Format.prototype.to = function ( number ) {
|
108
|
+
|
109
|
+
function reverse ( a ) {
|
110
|
+
return a.split('').reverse().join('');
|
111
|
+
}
|
112
|
+
|
113
|
+
number = this.v('encoder')( number );
|
114
|
+
|
115
|
+
var decimals = this.v('decimals'),
|
116
|
+
negative = '', preNegative = '', base = '', mark = '';
|
117
|
+
|
118
|
+
// Rounding away decimals might cause a value of -0
|
119
|
+
// when using very small ranges. Remove those cases.
|
120
|
+
if ( parseFloat(number.toFixed(decimals)) === 0 ) {
|
121
|
+
number = '0';
|
122
|
+
}
|
123
|
+
|
124
|
+
if ( number < 0 ) {
|
125
|
+
negative = this.v('negative');
|
126
|
+
preNegative = this.v('negativeBefore');
|
127
|
+
}
|
128
|
+
|
129
|
+
// Round to proper decimal count
|
130
|
+
number = Math.abs(number).toFixed(decimals).toString();
|
131
|
+
number = number.split('.');
|
132
|
+
|
133
|
+
// Group numbers in sets of three.
|
134
|
+
if ( this.v('thousand') ) {
|
135
|
+
base = reverse(number[0]).match(/.{1,3}/g);
|
136
|
+
base = reverse(base.join(reverse( this.v('thousand') )));
|
137
|
+
} else {
|
138
|
+
base = number[0];
|
139
|
+
}
|
140
|
+
|
141
|
+
// Ignore the decimal separator if decimals are set to 0.
|
142
|
+
if ( this.v('mark') && number.length > 1 ) {
|
143
|
+
mark = this.v('mark') + number[1];
|
144
|
+
}
|
145
|
+
|
146
|
+
// Return the finalized formatted number.
|
147
|
+
return this.v('to')(preNegative +
|
148
|
+
this.v('prefix') +
|
149
|
+
negative +
|
150
|
+
base +
|
151
|
+
mark +
|
152
|
+
this.v('postfix'));
|
153
|
+
};
|
154
|
+
|
155
|
+
Format.prototype.from = function ( input ) {
|
156
|
+
|
157
|
+
function esc(s){
|
158
|
+
return s.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, '\\$&');
|
159
|
+
}
|
160
|
+
|
161
|
+
var isNeg;
|
162
|
+
// The set request might want to ignore this handle.
|
163
|
+
// Test for 'undefined' too, as a two-handle slider
|
164
|
+
// can still be set with an integer.
|
165
|
+
if ( input === null || input === undefined ) {
|
166
|
+
return false;
|
167
|
+
}
|
168
|
+
|
169
|
+
input = this.v('from')(input);
|
170
|
+
|
171
|
+
// Remove formatting and set period for float parsing.
|
172
|
+
input = input.toString();
|
173
|
+
|
174
|
+
// Replace the preNegative indicator.
|
175
|
+
isNeg = input.replace(new RegExp('^' + esc( this.v('negativeBefore') )), '');
|
176
|
+
|
177
|
+
// Check if the value changed by removing the negativeBefore symbol.
|
178
|
+
if( input !== isNeg ) {
|
179
|
+
input = isNeg;
|
180
|
+
isNeg = '-';
|
181
|
+
} else {
|
182
|
+
isNeg = '';
|
183
|
+
}
|
184
|
+
|
185
|
+
// If prefix is set and the number is actually prefixed.
|
186
|
+
input = input.replace(new RegExp('^'+esc( this.v('prefix') )), '');
|
187
|
+
|
188
|
+
// Only replace if a negative sign is set.
|
189
|
+
if ( this.v('negative') ) {
|
190
|
+
|
191
|
+
// Reset isNeg to prevent double '-' insertion.
|
192
|
+
isNeg = '';
|
193
|
+
|
194
|
+
// Reset the negative sign to '-'
|
195
|
+
input = input.replace(new RegExp('^'+esc( this.v('negative') )), '-');
|
196
|
+
}
|
197
|
+
|
198
|
+
// Clean the input string
|
199
|
+
input = input
|
200
|
+
// If postfix is set and the number is postfixed.
|
201
|
+
.replace( new RegExp(esc( this.v('postfix') ) + '$'), '')
|
202
|
+
// Remove the separator every three digits.
|
203
|
+
.replace( new RegExp(esc( this.v('thousand') ), 'g'), '')
|
204
|
+
// Set the decimal separator back to period.
|
205
|
+
.replace( this.v('mark'), '.');
|
206
|
+
|
207
|
+
// Run the user defined decoder. Returns input by default.
|
208
|
+
input = this.v('decoder')( parseFloat( isNeg + input ) );
|
209
|
+
|
210
|
+
// Ignore invalid input
|
211
|
+
if (isNaN( input )) {
|
212
|
+
return false;
|
213
|
+
}
|
214
|
+
|
215
|
+
return input;
|
216
|
+
};
|
217
|
+
|
218
|
+
|
219
|
+
/** @expose */
|
220
|
+
/** @constructor */
|
221
|
+
function Link ( entry, update ) {
|
222
|
+
|
223
|
+
if ( typeof entry !== "object" ) {
|
224
|
+
$.error("(Link) Initialize with an object.");
|
225
|
+
}
|
226
|
+
|
227
|
+
// Make sure Link isn't called as a function, in which case
|
228
|
+
// the 'this' scope would be the window.
|
229
|
+
return new Link.prototype.init( entry['target']||function(){}, entry['method'], entry['format']||{}, update );
|
230
|
+
}
|
231
|
+
|
232
|
+
Link.prototype.setTooltip = function ( target, method ) {
|
233
|
+
|
234
|
+
// By default, use the 'html' method.
|
235
|
+
this.method = method || 'html';
|
236
|
+
|
237
|
+
// Use jQuery to create the element
|
238
|
+
this.el = $( target.replace('-tooltip-', '') || '<div/>' )[0];
|
239
|
+
};
|
240
|
+
|
241
|
+
Link.prototype.setHidden = function ( target ) {
|
242
|
+
|
243
|
+
this.method = 'val';
|
244
|
+
|
245
|
+
this.el = document.createElement('input');
|
246
|
+
this.el.name = target;
|
247
|
+
this.el.type = 'hidden';
|
248
|
+
};
|
249
|
+
|
250
|
+
Link.prototype.setField = function ( target ) {
|
251
|
+
|
252
|
+
// Returns nulled array.
|
253
|
+
function at(a,b,c){
|
254
|
+
return [c?a:b, c?b:a];
|
255
|
+
}
|
256
|
+
|
257
|
+
// In IE < 9, .bind() isn't available, need this link in .change().
|
258
|
+
var that = this;
|
259
|
+
|
260
|
+
// Default to .val if this is an input element.
|
261
|
+
this.method = 'val';
|
262
|
+
// Set the slider to a new value on change.
|
263
|
+
this.target = target.on('change', function( e ){
|
264
|
+
that.obj.val(
|
265
|
+
at(null, $(e.target).val(), that.N),
|
266
|
+
{ 'link': that, 'set': true }
|
267
|
+
);
|
268
|
+
});
|
269
|
+
};
|
270
|
+
|
271
|
+
|
272
|
+
// Initialisor
|
273
|
+
/** @constructor */
|
274
|
+
Link.prototype.init = function ( target, method, format, update ) {
|
275
|
+
|
276
|
+
// Write all formatting to this object.
|
277
|
+
// No validation needed, as we'll merge these with the parent
|
278
|
+
// format options first.
|
279
|
+
this.formatting = format;
|
280
|
+
|
281
|
+
// Store the update option.
|
282
|
+
this.update = !update;
|
283
|
+
|
284
|
+
// If target is a string, a new hidden input will be created.
|
285
|
+
if ( typeof target === 'string' && target.indexOf('-tooltip-') === 0 ) {
|
286
|
+
this.setTooltip( target, method );
|
287
|
+
return;
|
288
|
+
}
|
289
|
+
|
290
|
+
// If the string doesn't begin with '-', which is reserved, add a new hidden input.
|
291
|
+
if ( typeof target === 'string' && target.indexOf('-') !== 0 ) {
|
292
|
+
this.setHidden( target );
|
293
|
+
return;
|
294
|
+
}
|
295
|
+
|
296
|
+
// The target can also be a function, which will be called.
|
297
|
+
if ( typeof target === 'function' ) {
|
298
|
+
this.target = false;
|
299
|
+
this.method = target;
|
300
|
+
return;
|
301
|
+
}
|
302
|
+
|
303
|
+
if ( isInstance(target) ) {
|
304
|
+
// If a jQuery/Zepto input element is provided, but no method is set,
|
305
|
+
// the element can assume it needs to respond to 'change'...
|
306
|
+
|
307
|
+
if ( !method ) {
|
308
|
+
|
309
|
+
if ( target.is('input, select, textarea') ) {
|
310
|
+
this.setField( target );
|
311
|
+
return;
|
312
|
+
}
|
313
|
+
|
314
|
+
// If no method is set, and we are not auto-binding an input, default to 'html'.
|
315
|
+
method = 'html';
|
316
|
+
}
|
317
|
+
|
318
|
+
// The method must exist on the element.
|
319
|
+
if ( typeof method === 'function' || (typeof method === 'string' && target[method]) ) {
|
320
|
+
this.method = method;
|
321
|
+
this.target = target;
|
322
|
+
return;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
// Nothing matched, throw error.
|
327
|
+
throw new RangeError("(Link) Invalid Link.");
|
328
|
+
};
|
329
|
+
|
330
|
+
// Provides external items with the slider value.
|
331
|
+
Link.prototype.write = function ( value, handle, slider, update ) {
|
332
|
+
|
333
|
+
// Don't synchronize this Link.
|
334
|
+
if ( this.update && update === false ) {
|
335
|
+
return;
|
336
|
+
}
|
337
|
+
|
338
|
+
this.actual = value;
|
339
|
+
|
340
|
+
// Format values for display.
|
341
|
+
value = this.format( value );
|
342
|
+
|
343
|
+
// Store the numerical value.
|
344
|
+
this.saved = value;
|
345
|
+
|
346
|
+
// Branch between serialization to a function or an object.
|
347
|
+
if ( typeof this.method === 'function' ) {
|
348
|
+
// When target is undefined, the target was a function.
|
349
|
+
// In that case, provided the slider as the calling scope.
|
350
|
+
// Use [0] to get the DOM element, not the $ instance.
|
351
|
+
this.method.call( this.target[0] || slider[0], value, handle, slider );
|
352
|
+
} else {
|
353
|
+
this.target[ this.method ]( value, handle, slider );
|
354
|
+
}
|
355
|
+
};
|
356
|
+
|
357
|
+
// Set formatting options.
|
358
|
+
Link.prototype.setFormatting = function ( options ) {
|
359
|
+
this.formatting = new Format($.extend({},
|
360
|
+
options,
|
361
|
+
this.formatting instanceof Format ? this.formatting.settings : this.formatting
|
362
|
+
));
|
363
|
+
};
|
364
|
+
|
365
|
+
Link.prototype.setObject = function ( obj ) {
|
366
|
+
this.obj = obj;
|
367
|
+
};
|
368
|
+
|
369
|
+
Link.prototype.setIndex = function ( index ) {
|
370
|
+
this.N = index;
|
371
|
+
};
|
372
|
+
|
373
|
+
// Parses slider value to user defined display.
|
374
|
+
Link.prototype.format = function ( a ) {
|
375
|
+
return this.formatting.to(a);
|
376
|
+
};
|
377
|
+
|
378
|
+
// Converts a formatted value back to a real number.
|
379
|
+
Link.prototype.getValue = function ( a ) {
|
380
|
+
return this.formatting.from(a);
|
381
|
+
};
|
382
|
+
|
383
|
+
// We can now test for Link.init to be an instance of Link.
|
384
|
+
Link.prototype.init.prototype = Link.prototype;
|
385
|
+
|
386
|
+
/** @expose */
|
387
|
+
$.Link = Link;
|
388
|
+
|
389
|
+
}( window['jQuery'] || window['Zepto'] ));
|
@@ -1,1650 +1,1252 @@
|
|
1
|
-
|
1
|
+
/**@preserve
|
2
|
+
$.fn.noUiSlider - WTFPL - refreshless.com/nouislider/ */
|
2
3
|
|
3
4
|
/*jslint browser: true */
|
4
|
-
/*jslint devel: true */
|
5
|
-
/*jslint continue: true */
|
6
|
-
/*jslint plusplus: true */
|
7
5
|
/*jslint sub: true */
|
8
6
|
/*jslint white: true */
|
9
|
-
|
10
|
-
|
11
|
-
// @externs_url http://refreshless.com/externs/jquery-1.8.js
|
12
|
-
// @compilation_level ADVANCED_OPTIMIZATIONS
|
13
|
-
// @warning_level VERBOSE
|
14
|
-
// ==/ClosureCompiler==
|
7
|
+
/*jslint continue: true */
|
8
|
+
/*jslint plusplus: true */
|
15
9
|
|
16
10
|
(function( $ ){
|
17
11
|
|
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
|
-
/* 1 */ ,'mark'
|
66
|
-
/* 2 */ ,'thousand'
|
67
|
-
/* 3 */ ,'prefix'
|
68
|
-
/* 4 */ ,'postfix'
|
69
|
-
/* 5 */ ,'encoder'
|
70
|
-
/* 6 */ ,'decoder'
|
71
|
-
/* 7 */ ,'negative'
|
72
|
-
/* 8 */ ,'negativeBefore'
|
73
|
-
],
|
74
|
-
/** @const */ FormatDefaults = [
|
75
|
-
/* 0 */ 2
|
76
|
-
/* 1 */ ,'.'
|
77
|
-
/* 2 */ ,''
|
78
|
-
/* 3 */ ,''
|
79
|
-
/* 4 */ ,''
|
80
|
-
/* 5 */ ,function(a){ return a; }
|
81
|
-
/* 6 */ ,function(a){ return a; }
|
82
|
-
/* 7 */ ,'-'
|
83
|
-
/* 8 */ ,''
|
84
|
-
];
|
85
|
-
|
86
|
-
|
87
|
-
// Error handling
|
88
|
-
|
89
|
-
function throwError( message ){
|
90
|
-
throw new RangeError('noUiSlider: ' + message);
|
91
|
-
}
|
92
|
-
|
93
|
-
// Throw an error if formatting options are incompatible.
|
94
|
-
function throwEqualError( F, a, b ) {
|
95
|
-
if ( (F[a] || F[b]) && (F[a] === F[b]) ) {
|
96
|
-
throwError("(Link) '"+a+"' can't match '"+b+"'.'");
|
97
|
-
}
|
98
|
-
}
|
12
|
+
'use strict';
|
13
|
+
|
14
|
+
var
|
15
|
+
// Cache the document selector;
|
16
|
+
/** @const */
|
17
|
+
doc = $(document),
|
18
|
+
// Namespace for binding and unbinding slider events;
|
19
|
+
/** @const */
|
20
|
+
namespace = '.nui',
|
21
|
+
// Determine the events to bind. IE11 implements pointerEvents without
|
22
|
+
// a prefix, which breaks compatibility with the IE10 implementation.
|
23
|
+
/** @const */
|
24
|
+
actions = window.navigator['pointerEnabled'] ? {
|
25
|
+
start: 'pointerdown',
|
26
|
+
move: 'pointermove',
|
27
|
+
end: 'pointerup'
|
28
|
+
} : window.navigator['msPointerEnabled'] ? {
|
29
|
+
start: 'MSPointerDown',
|
30
|
+
move: 'MSPointerMove',
|
31
|
+
end: 'MSPointerUp'
|
32
|
+
} : {
|
33
|
+
start: 'mousedown touchstart',
|
34
|
+
move: 'mousemove touchmove',
|
35
|
+
end: 'mouseup touchend'
|
36
|
+
},
|
37
|
+
// Re-usable list of classes;
|
38
|
+
/** @const */
|
39
|
+
Classes = [
|
40
|
+
/* 0 */ 'noUi-target'
|
41
|
+
/* 1 */ ,'noUi-base'
|
42
|
+
/* 2 */ ,'noUi-origin'
|
43
|
+
/* 3 */ ,'noUi-handle'
|
44
|
+
/* 4 */ ,'noUi-horizontal'
|
45
|
+
/* 5 */ ,'noUi-vertical'
|
46
|
+
/* 6 */ ,'noUi-background'
|
47
|
+
/* 7 */ ,'noUi-connect'
|
48
|
+
/* 8 */ ,'noUi-ltr'
|
49
|
+
/* 9 */ ,'noUi-rtl'
|
50
|
+
/* 10 */ ,'noUi-dragable'
|
51
|
+
/* 11 */ ,''
|
52
|
+
/* 12 */ ,'noUi-state-drag'
|
53
|
+
/* 13 */ ,''
|
54
|
+
/* 14 */ ,'noUi-state-tap'
|
55
|
+
/* 15 */ ,'noUi-active'
|
56
|
+
/* 16 */ ,'noUi-extended'
|
57
|
+
/* 17 */ ,'noUi-stacking'
|
58
|
+
];
|
99
59
|
|
100
60
|
|
101
61
|
// General helpers
|
102
62
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
63
|
+
// Limits a value to 0 - 100
|
64
|
+
function limit ( a ) {
|
65
|
+
return Math.max(Math.min(a, 100), 0);
|
66
|
+
}
|
107
67
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
68
|
+
// Round a value to the closest 'to'.
|
69
|
+
function closest ( value, to ) {
|
70
|
+
return Math.round(value / to) * to;
|
71
|
+
}
|
112
72
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
73
|
+
// Determine the size of a sub-range in relation to a full range.
|
74
|
+
function subRangeRatio ( pa, pb ) {
|
75
|
+
return (100 / (pb - pa));
|
76
|
+
}
|
117
77
|
|
118
78
|
|
119
79
|
// Type validation
|
120
80
|
|
121
|
-
|
122
|
-
|
123
|
-
|
81
|
+
// Checks whether a value is numerical.
|
82
|
+
function isNumeric ( a ) {
|
83
|
+
return typeof a === 'number' && !isNaN( a ) && isFinite( a );
|
84
|
+
}
|
124
85
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
// Checks whether a value is numerical.
|
131
|
-
function isNumeric ( a ) {
|
132
|
-
return typeof a === 'number' && !isNaN( a ) && isFinite( a );
|
133
|
-
}
|
134
|
-
|
135
|
-
// Wraps a variable as an array, if it isn't one yet.
|
136
|
-
function asArray ( a ) {
|
137
|
-
return $.isArray(a) ? a : [a];
|
138
|
-
}
|
86
|
+
// Wraps a variable as an array, if it isn't one yet.
|
87
|
+
function asArray ( a ) {
|
88
|
+
return $.isArray(a) ? a : [a];
|
89
|
+
}
|
139
90
|
|
140
91
|
|
141
92
|
// Class handling
|
142
93
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
// Tests if element has a class, adds it if not. Returns original state.
|
152
|
-
function getsClass ( element, className ) {
|
153
|
-
|
154
|
-
var has = element.hasClass(className);
|
155
|
-
|
156
|
-
if ( !has ) {
|
157
|
-
element.addClass( className );
|
158
|
-
}
|
159
|
-
|
160
|
-
return has;
|
161
|
-
}
|
94
|
+
// Sets a class and removes it after [duration] ms.
|
95
|
+
function addClassFor ( element, className, duration ) {
|
96
|
+
element.addClass(className);
|
97
|
+
setTimeout(function(){
|
98
|
+
element.removeClass(className);
|
99
|
+
}, duration);
|
100
|
+
}
|
162
101
|
|
163
102
|
|
164
103
|
// Value calculation
|
165
104
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
105
|
+
// (percentage) How many percent is this value of this range?
|
106
|
+
function fromPercentage ( range, value ) {
|
107
|
+
return (value * 100) / ( range[1] - range[0] );
|
108
|
+
}
|
170
109
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
110
|
+
// (percentage) Where is this value on this range?
|
111
|
+
function toPercentage ( range, value ) {
|
112
|
+
return fromPercentage( range, range[0] < 0 ?
|
113
|
+
value + Math.abs(range[0]) :
|
114
|
+
value - range[0] );
|
115
|
+
}
|
177
116
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
117
|
+
// (value) How much is this percentage on this range?
|
118
|
+
function isPercentage ( range, value ) {
|
119
|
+
return ((value * ( range[1] - range[0] )) / 100) + range[0];
|
120
|
+
}
|
182
121
|
|
183
|
-
|
184
|
-
|
122
|
+
// (percentage)
|
123
|
+
function toStepping ( options, value ) {
|
185
124
|
|
186
|
-
|
187
|
-
|
188
|
-
|
125
|
+
if ( value >= options.xVal.slice(-1)[0] ){
|
126
|
+
return 100;
|
127
|
+
}
|
189
128
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
129
|
+
var j = 1, va, vb, pa, pb;
|
130
|
+
while ( value >= options.xVal[j] ){
|
131
|
+
j++;
|
132
|
+
}
|
194
133
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
134
|
+
va = options.xVal[j-1];
|
135
|
+
vb = options.xVal[j];
|
136
|
+
pa = options.xPct[j-1];
|
137
|
+
pb = options.xPct[j];
|
199
138
|
|
200
|
-
|
201
|
-
|
139
|
+
return pa + (toPercentage([va, vb], value) / subRangeRatio (pa, pb));
|
140
|
+
}
|
202
141
|
|
203
|
-
|
204
|
-
|
142
|
+
// (value)
|
143
|
+
function fromStepping ( options, value ) {
|
205
144
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
145
|
+
// There is no range group that fits 100
|
146
|
+
if ( value >= 100 ){
|
147
|
+
return options.xVal.slice(-1)[0];
|
148
|
+
}
|
210
149
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
150
|
+
var j = 1, va, vb, pa, pb;
|
151
|
+
while ( value >= options.xPct[j] ){
|
152
|
+
j++;
|
153
|
+
}
|
215
154
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
155
|
+
va = options.xVal[j-1];
|
156
|
+
vb = options.xVal[j];
|
157
|
+
pa = options.xPct[j-1];
|
158
|
+
pb = options.xPct[j];
|
220
159
|
|
221
|
-
|
222
|
-
|
160
|
+
return isPercentage([va, vb], (value - pa) * subRangeRatio (pa, pb));
|
161
|
+
}
|
223
162
|
|
224
|
-
|
225
|
-
|
163
|
+
// (percentage) Get the step that applies at a certain value.
|
164
|
+
function getStep ( options, value ){
|
226
165
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
166
|
+
var j = 1, a, b;
|
167
|
+
while ( value >= options.xPct[j] ){
|
168
|
+
j++;
|
169
|
+
}
|
231
170
|
|
232
|
-
|
171
|
+
if ( options.snap ) {
|
233
172
|
|
234
|
-
|
235
|
-
|
173
|
+
a = options.xPct[j-1];
|
174
|
+
b = options.xPct[j];
|
236
175
|
|
237
|
-
|
238
|
-
|
239
|
-
|
176
|
+
if ((value - a) > ((b-a)/2)){
|
177
|
+
return b;
|
178
|
+
}
|
240
179
|
|
241
|
-
|
242
|
-
|
180
|
+
return a;
|
181
|
+
}
|
243
182
|
|
244
|
-
|
245
|
-
|
246
|
-
|
183
|
+
if ( !options.xSteps[j-1] ){
|
184
|
+
return value;
|
185
|
+
}
|
247
186
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
187
|
+
return options.xPct[j-1] + closest(
|
188
|
+
value - options.xPct[j-1],
|
189
|
+
options.xSteps[j-1]
|
190
|
+
);
|
191
|
+
}
|
253
192
|
|
254
193
|
|
255
194
|
// Event handling
|
256
195
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
// Prevent scrolling and panning on touch events, while
|
261
|
-
// attempting to slide. The tap event also depends on this.
|
262
|
-
e.preventDefault();
|
263
|
-
|
264
|
-
// Filter the event to register the type, which can be
|
265
|
-
// touch, mouse or pointer. Offset changes need to be
|
266
|
-
// made on an event specific basis.
|
267
|
-
var touch = e.type.indexOf('touch') === 0
|
268
|
-
,mouse = e.type.indexOf('mouse') === 0
|
269
|
-
,pointer = e.type.indexOf('pointer') === 0
|
270
|
-
,x,y, event = e;
|
271
|
-
|
272
|
-
// IE10 implemented pointer events with a prefix;
|
273
|
-
if ( e.type.indexOf('MSPointer') === 0 ) {
|
274
|
-
pointer = true;
|
275
|
-
}
|
276
|
-
|
277
|
-
// Get the originalEvent, if the event has been wrapped
|
278
|
-
// by jQuery. Zepto doesn't wrap the event.
|
279
|
-
if ( e.originalEvent ) {
|
280
|
-
e = e.originalEvent;
|
281
|
-
}
|
196
|
+
// Provide a clean event with standardized offset values.
|
197
|
+
function fixEvent ( e ) {
|
282
198
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
x = e.changedTouches[0].pageX;
|
287
|
-
y = e.changedTouches[0].pageY;
|
288
|
-
}
|
199
|
+
// Prevent scrolling and panning on touch events, while
|
200
|
+
// attempting to slide. The tap event also depends on this.
|
201
|
+
e.preventDefault();
|
289
202
|
|
290
|
-
|
203
|
+
// Filter the event to register the type, which can be
|
204
|
+
// touch, mouse or pointer. Offset changes need to be
|
205
|
+
// made on an event specific basis.
|
206
|
+
var touch = e.type.indexOf('touch') === 0
|
207
|
+
,mouse = e.type.indexOf('mouse') === 0
|
208
|
+
,pointer = e.type.indexOf('pointer') === 0
|
209
|
+
,x,y, event = e;
|
291
210
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
window.pageYOffset = document.documentElement.scrollTop;
|
297
|
-
}
|
211
|
+
// IE10 implemented pointer events with a prefix;
|
212
|
+
if ( e.type.indexOf('MSPointer') === 0 ) {
|
213
|
+
pointer = true;
|
214
|
+
}
|
298
215
|
|
299
|
-
|
300
|
-
|
301
|
-
|
216
|
+
// Get the originalEvent, if the event has been wrapped
|
217
|
+
// by jQuery. Zepto doesn't wrap the event.
|
218
|
+
if ( e.originalEvent ) {
|
219
|
+
e = e.originalEvent;
|
220
|
+
}
|
302
221
|
|
303
|
-
|
304
|
-
|
222
|
+
if ( touch ) {
|
223
|
+
// noUiSlider supports one movement at a time,
|
224
|
+
// so we can select the first 'changedTouch'.
|
225
|
+
x = e.changedTouches[0].pageX;
|
226
|
+
y = e.changedTouches[0].pageY;
|
227
|
+
}
|
305
228
|
|
306
|
-
|
307
|
-
}
|
308
|
-
|
309
|
-
|
310
|
-
// Organize formatting in an object.
|
311
|
-
|
312
|
-
/** @constructor */
|
313
|
-
function Format( options ){
|
229
|
+
if ( mouse || pointer ) {
|
314
230
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
throwError("(Format) 'format' option must be an object.");
|
322
|
-
}
|
323
|
-
|
324
|
-
var settings = {};
|
325
|
-
|
326
|
-
// Copy all values into a new object.
|
327
|
-
$(Formatting).each(function(i, val){
|
328
|
-
|
329
|
-
if ( options[val] === undefined ){
|
330
|
-
|
331
|
-
settings[val] = FormatDefaults[i];
|
332
|
-
|
333
|
-
// When we aren't loading defaults, validate the entry.
|
334
|
-
} else if ( typeMatch(options[val], FormatDefaults[i]) ) {
|
335
|
-
|
336
|
-
// Support for up to 7 decimals.
|
337
|
-
// More can't be guaranteed due to floating point issues.
|
338
|
-
if ( val === 'decimals' ){
|
339
|
-
if ( options[val] < 0 || options[val] > 7 ){
|
340
|
-
throwError("(Format) 'format.decimals' option must be between 0 and 7.");
|
341
|
-
}
|
342
|
-
}
|
343
|
-
|
344
|
-
settings[val] = options[val];
|
345
|
-
|
346
|
-
// If the value isn't valid, emit an error.
|
347
|
-
} else {
|
348
|
-
throwError("(Format) 'format."+val+"' must be a " + typeof FormatDefaults[i] + ".");
|
349
|
-
}
|
350
|
-
});
|
351
|
-
|
352
|
-
// Some values can't be extracted from a
|
353
|
-
// string if certain combinations are present.
|
354
|
-
throwEqualError(settings, 'mark', 'thousand');
|
355
|
-
throwEqualError(settings, 'prefix', 'negative');
|
356
|
-
throwEqualError(settings, 'prefix', 'negativeBefore');
|
357
|
-
|
358
|
-
this.settings = settings;
|
359
|
-
}
|
360
|
-
|
361
|
-
// Shorthand for internal value get
|
362
|
-
Format.prototype.v = function ( a ) {
|
363
|
-
return this.settings[a];
|
364
|
-
};
|
365
|
-
|
366
|
-
Format.prototype.to = function ( number ) {
|
367
|
-
|
368
|
-
function reverse ( a ) {
|
369
|
-
return a.split('').reverse().join('');
|
370
|
-
}
|
371
|
-
|
372
|
-
number = this.v('encoder')( number );
|
373
|
-
|
374
|
-
var negative = '', preNegative = '', base = '', mark = '';
|
375
|
-
|
376
|
-
if ( number < 0 ) {
|
377
|
-
negative = this.v('negative');
|
378
|
-
preNegative = this.v('negativeBefore');
|
379
|
-
}
|
231
|
+
// Polyfill the pageXOffset and pageYOffset
|
232
|
+
// variables for IE7 and IE8;
|
233
|
+
if( !pointer && window.pageXOffset === undefined ){
|
234
|
+
window.pageXOffset = document.documentElement.scrollLeft;
|
235
|
+
window.pageYOffset = document.documentElement.scrollTop;
|
236
|
+
}
|
380
237
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
// Rounding away decimals might cause a value of -0
|
386
|
-
// when using very small ranges. Remove those cases.
|
387
|
-
if ( parseFloat(number) === 0 ) {
|
388
|
-
number[0] = '0';
|
389
|
-
}
|
390
|
-
|
391
|
-
// Group numbers in sets of three.
|
392
|
-
if ( this.v('thousand') ) {
|
393
|
-
base = reverse(number[0]).match(/.{1,3}/g);
|
394
|
-
base = reverse(base.join(reverse( this.v('thousand') )));
|
395
|
-
} else {
|
396
|
-
base = number[0];
|
397
|
-
}
|
238
|
+
x = e.clientX + window.pageXOffset;
|
239
|
+
y = e.clientY + window.pageYOffset;
|
240
|
+
}
|
398
241
|
|
399
|
-
|
400
|
-
|
401
|
-
mark = this.v('mark') + number[1];
|
402
|
-
}
|
242
|
+
event.points = [x, y];
|
243
|
+
event.cursor = mouse;
|
403
244
|
|
404
|
-
|
405
|
-
|
406
|
-
this.v('prefix') +
|
407
|
-
negative +
|
408
|
-
base +
|
409
|
-
mark +
|
410
|
-
this.v('postfix');
|
411
|
-
};
|
412
|
-
|
413
|
-
Format.prototype.from = function ( input ) {
|
414
|
-
|
415
|
-
function esc(s){
|
416
|
-
return s.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, '\\$&');
|
417
|
-
}
|
418
|
-
|
419
|
-
var isNeg;
|
420
|
-
// The set request might want to ignore this handle.
|
421
|
-
// Test for 'undefined' too, as a two-handle slider
|
422
|
-
// can still be set with an integer.
|
423
|
-
if( input === null || input === undefined ) {
|
424
|
-
return false;
|
425
|
-
}
|
426
|
-
|
427
|
-
// Remove formatting and set period for float parsing.
|
428
|
-
input = input.toString();
|
429
|
-
|
430
|
-
// Replace the preNegative indicator.
|
431
|
-
isNeg = input.replace(new RegExp('^' + esc( this.v('negativeBefore') )), '');
|
432
|
-
|
433
|
-
// Check if the value changed by removing the negativeBefore symbol.
|
434
|
-
if( input !== isNeg ) {
|
435
|
-
input = isNeg;
|
436
|
-
isNeg = '-';
|
437
|
-
} else {
|
438
|
-
isNeg = '';
|
439
|
-
}
|
440
|
-
|
441
|
-
// If prefix is set and the number is actually prefixed.
|
442
|
-
input = input.replace(new RegExp('^'+esc( this.v('prefix') )), '');
|
443
|
-
|
444
|
-
// Only replace if a negative sign is set.
|
445
|
-
if ( this.v['negative'] ) {
|
446
|
-
|
447
|
-
// Reset isNeg to prevent double '-' insertion.
|
448
|
-
isNeg = '';
|
449
|
-
|
450
|
-
// Reset the negative sign to '-'
|
451
|
-
input = input.replace(new RegExp('^'+esc( this.v('negative') )), '-');
|
452
|
-
}
|
453
|
-
|
454
|
-
// Clean the input string
|
455
|
-
input = input
|
456
|
-
// If postfix is set and the number is postfixed.
|
457
|
-
.replace( new RegExp(esc( this.v('postfix') ) + '$'), '')
|
458
|
-
// Remove the separator every three digits.
|
459
|
-
.replace( new RegExp(esc( this.v('thousand') ), 'g'), '')
|
460
|
-
// Set the decimal separator back to period.
|
461
|
-
.replace( this.v('mark'), '.');
|
462
|
-
|
463
|
-
// Run the user defined decoder. Returns input by default.
|
464
|
-
input = this.v('decoder')( parseFloat( isNeg + input ) );
|
465
|
-
|
466
|
-
// Ignore invalid input
|
467
|
-
if (isNaN( input )) {
|
468
|
-
return false;
|
469
|
-
}
|
470
|
-
|
471
|
-
return input;
|
472
|
-
};
|
473
|
-
|
474
|
-
|
475
|
-
// Serialization target
|
476
|
-
|
477
|
-
/** @constructor */
|
478
|
-
function Link( entry, update ){
|
479
|
-
|
480
|
-
// Make sure Link isn't called as a function, in which case
|
481
|
-
// the 'this' scope would be the window.
|
482
|
-
if ( !(this instanceof Link) ) {
|
483
|
-
throw new Error( "Link: " +
|
484
|
-
"Don't use Link as a function. " +
|
485
|
-
"Use the 'new' keyword.");
|
486
|
-
}
|
487
|
-
|
488
|
-
if ( !entry ) {
|
489
|
-
throw new RangeError("Link: missing parameters.");
|
490
|
-
}
|
491
|
-
|
492
|
-
// Write all formatting to this object.
|
493
|
-
// No validation needed, as we'll merge these with the parent
|
494
|
-
// format options first.
|
495
|
-
this.formatting = entry['format'] || {};
|
496
|
-
|
497
|
-
// Store the update option.
|
498
|
-
this.update = !update;
|
499
|
-
|
500
|
-
// In IE < 9, .bind() isn't available, need this link in .change().
|
501
|
-
var that = this,
|
245
|
+
return event;
|
246
|
+
}
|
502
247
|
|
503
|
-
// Get values from the input.
|
504
|
-
target = entry['target'] || function(){},
|
505
|
-
method = entry['method'],
|
506
248
|
|
507
|
-
|
508
|
-
isTooltip = ( typeof target === 'string' && target.indexOf('-tooltip-') === 0 ),
|
509
|
-
isHidden = ( typeof target === 'string' && target.indexOf('-') !== 0 ),
|
510
|
-
isMethod = ( typeof target === 'function' ),
|
511
|
-
is$ = ( isInstance(target) ),
|
512
|
-
isInput = ( is$ && target.is('input, select, textarea') ),
|
513
|
-
methodIsFunction = ( is$ && typeof method === 'function' ),
|
514
|
-
methodIsName = ( is$ && typeof method === 'string' && target[method] );
|
515
|
-
|
516
|
-
// If target is a string, a new hidden input will be created.
|
517
|
-
if ( isTooltip ) {
|
518
|
-
|
519
|
-
// By default, use the 'html' method.
|
520
|
-
this.method = method || 'html';
|
521
|
-
|
522
|
-
// Use jQuery to create the element
|
523
|
-
this.el = $( target.replace('-tooltip-', '') || '<div/>' )[0];
|
524
|
-
|
525
|
-
return;
|
526
|
-
}
|
527
|
-
|
528
|
-
// If the string doesn't begin with '-', which is reserved, add a new hidden input.
|
529
|
-
if ( isHidden ) {
|
530
|
-
|
531
|
-
this.method = 'val';
|
249
|
+
// Input validation
|
532
250
|
|
533
|
-
|
534
|
-
|
535
|
-
|
251
|
+
function testStep ( parsed, entry ) {
|
252
|
+
|
253
|
+
if ( !isNumeric( entry ) ) {
|
254
|
+
throw new Error("noUiSlider: 'step' is not numeric.");
|
255
|
+
}
|
256
|
+
|
257
|
+
// The step option can still be used to set stepping
|
258
|
+
// for linear sliders. Overwritten if set in 'range'.
|
259
|
+
parsed.xSteps[0] = entry;
|
260
|
+
}
|
261
|
+
|
262
|
+
function testRange ( parsed, entry ) {
|
263
|
+
|
264
|
+
// Filter incorrect input.
|
265
|
+
if ( typeof entry !== 'object' || $.isArray(entry) ) {
|
266
|
+
throw new Error("noUiSlider: 'range' is not an object.");
|
267
|
+
}
|
268
|
+
|
269
|
+
// Loop all entries.
|
270
|
+
$.each( entry, function ( index, value ) {
|
271
|
+
|
272
|
+
var percentage;
|
273
|
+
|
274
|
+
// Wrap numerical input in an array.
|
275
|
+
if ( typeof value === "number" ) {
|
276
|
+
value = [value];
|
277
|
+
}
|
278
|
+
|
279
|
+
// Reject any invalid input.
|
280
|
+
if ( !$.isArray( value ) ){
|
281
|
+
throw new Error("noUiSlider: 'range' contains invalid value.");
|
282
|
+
}
|
283
|
+
|
284
|
+
// Covert min/max syntax to 0 and 100.
|
285
|
+
if ( index === 'min' ) {
|
286
|
+
percentage = 0;
|
287
|
+
} else if ( index === 'max' ) {
|
288
|
+
percentage = 100;
|
289
|
+
} else {
|
290
|
+
percentage = parseFloat( index );
|
291
|
+
}
|
292
|
+
|
293
|
+
// Check for correct input.
|
294
|
+
if ( !isNumeric( percentage ) || !isNumeric( value[0] ) ) {
|
295
|
+
throw new Error("noUiSlider: 'range' value isn't numeric.");
|
296
|
+
}
|
297
|
+
|
298
|
+
// Store values.
|
299
|
+
parsed.xPct.push( percentage );
|
300
|
+
parsed.xVal.push( value[0] );
|
301
|
+
|
302
|
+
// NaN will evaluate to false too, but to keep
|
303
|
+
// logging clear, set step explicitly. Make sure
|
304
|
+
// not to override the 'step' setting with false.
|
305
|
+
if ( !percentage ) {
|
306
|
+
if ( !isNaN( value[1] ) ) {
|
307
|
+
parsed.xSteps[0] = value[1];
|
308
|
+
}
|
309
|
+
} else {
|
310
|
+
parsed.xSteps.push( isNaN(value[1]) ? false : value[1] );
|
311
|
+
}
|
312
|
+
});
|
313
|
+
|
314
|
+
$.each(parsed.xSteps, function(i,n){
|
315
|
+
|
316
|
+
// Ignore 'false' stepping.
|
317
|
+
if ( !n ) {
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
|
321
|
+
// Check if step fits. Not required, but this might serve some goal.
|
322
|
+
// !((parsed.xVal[i+1] - parsed.xVal[i]) % n);
|
323
|
+
|
324
|
+
// Factor to range ratio
|
325
|
+
parsed.xSteps[i] = fromPercentage([
|
326
|
+
parsed.xVal[i]
|
327
|
+
,parsed.xVal[i+1]
|
328
|
+
], n) / subRangeRatio (
|
329
|
+
parsed.xPct[i],
|
330
|
+
parsed.xPct[i+1] );
|
331
|
+
});
|
332
|
+
}
|
333
|
+
|
334
|
+
function testStart ( parsed, entry ) {
|
335
|
+
|
336
|
+
if ( typeof entry === "number" ) {
|
337
|
+
entry = [entry];
|
338
|
+
}
|
339
|
+
|
340
|
+
// Validate input. Values aren't tested, the internal Link will do
|
341
|
+
// that and provide a valid location.
|
342
|
+
if ( !$.isArray( entry ) || !entry.length || entry.length > 2 ) {
|
343
|
+
throw new Error("noUiSlider: 'start' option is incorrect.");
|
344
|
+
}
|
345
|
+
|
346
|
+
// Store the number of handles.
|
347
|
+
parsed.handles = entry.length;
|
348
|
+
|
349
|
+
// When the slider is initialized, the .val method will
|
350
|
+
// be called with the start options.
|
351
|
+
parsed.start = entry;
|
352
|
+
}
|
353
|
+
|
354
|
+
function testSnap ( parsed, entry ) {
|
355
|
+
|
356
|
+
// Enforce 100% stepping within subranges.
|
357
|
+
parsed.snap = entry;
|
358
|
+
|
359
|
+
if ( typeof entry !== 'boolean' ){
|
360
|
+
throw new Error("noUiSlider: 'snap' option must be a boolean.");
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
function testConnect ( parsed, entry ) {
|
365
|
+
|
366
|
+
if ( entry === 'lower' && parsed.handles === 1 ) {
|
367
|
+
parsed.connect = 1;
|
368
|
+
} else if ( entry === 'upper' && parsed.handles === 1 ) {
|
369
|
+
parsed.connect = 2;
|
370
|
+
} else if ( entry === true && parsed.handles === 2 ) {
|
371
|
+
parsed.connect = 3;
|
372
|
+
} else if ( entry === false ) {
|
373
|
+
parsed.connect = 0;
|
374
|
+
} else {
|
375
|
+
throw new Error("noUiSlider: 'connect' option doesn't match handle count.");
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
function testOrientation ( parsed, entry ) {
|
380
|
+
|
381
|
+
// Set orientation to an a numerical value for easy
|
382
|
+
// array selection.
|
383
|
+
switch ( entry ){
|
384
|
+
case 'horizontal':
|
385
|
+
parsed.ort = 0;
|
386
|
+
break;
|
387
|
+
case 'vertical':
|
388
|
+
parsed.ort = 1;
|
389
|
+
break;
|
390
|
+
default:
|
391
|
+
throw new Error("noUiSlider: 'orientation' option is invalid.");
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
function testMargin ( parsed, entry ) {
|
396
|
+
|
397
|
+
if ( parsed.xPct.length > 2 ) {
|
398
|
+
throw new Error("noUiSlider: 'margin' option is only supported on linear sliders.");
|
399
|
+
}
|
400
|
+
|
401
|
+
// Parse value to range and store. As xVal is checked
|
402
|
+
// to be no bigger than 2, use it as range.
|
403
|
+
parsed.margin = fromPercentage(parsed.xVal, entry);
|
404
|
+
|
405
|
+
if ( !isNumeric(entry) ){
|
406
|
+
throw new Error("noUiSlider: 'margin' option must be numeric.");
|
407
|
+
}
|
408
|
+
}
|
409
|
+
|
410
|
+
function testDirection ( parsed, entry ) {
|
411
|
+
|
412
|
+
// Set direction as a numerical value for easy parsing.
|
413
|
+
// Invert connection for RTL sliders, so that the proper
|
414
|
+
// handles get the connect/background classes.
|
415
|
+
switch ( entry ) {
|
416
|
+
case 'ltr':
|
417
|
+
parsed.dir = 0;
|
418
|
+
break;
|
419
|
+
case 'rtl':
|
420
|
+
parsed.dir = 1;
|
421
|
+
parsed.connect = [0,2,1,3][parsed.connect];
|
422
|
+
break;
|
423
|
+
default:
|
424
|
+
throw new Error("noUiSlider: 'direction' option was not recognized.");
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
function testBehaviour ( parsed, entry ) {
|
429
|
+
|
430
|
+
// Make sure the input is a string.
|
431
|
+
if ( typeof entry !== 'string' ) {
|
432
|
+
throw new Error("noUiSlider: 'behaviour' must be a string containing options.");
|
433
|
+
}
|
434
|
+
|
435
|
+
// Check if the string contains any keywords.
|
436
|
+
// None are required.
|
437
|
+
var tap = entry.indexOf('tap') >= 0,
|
438
|
+
extend = entry.indexOf('extend') >= 0,
|
439
|
+
drag = entry.indexOf('drag') >= 0,
|
440
|
+
fixed = entry.indexOf('fixed') >= 0,
|
441
|
+
snap = entry.indexOf('snap') >= 0;
|
442
|
+
|
443
|
+
parsed.events = {
|
444
|
+
tap: tap || snap,
|
445
|
+
extend: extend,
|
446
|
+
drag: drag,
|
447
|
+
fixed: fixed,
|
448
|
+
snap: snap
|
449
|
+
};
|
450
|
+
}
|
451
|
+
|
452
|
+
function testSerialization ( parsed, entry, sliders ) {
|
453
|
+
|
454
|
+
parsed.ser = [ entry['lower'], entry['upper'] ];
|
455
|
+
parsed.formatting = entry['format'];
|
456
|
+
|
457
|
+
$.each( parsed.ser, function( index, linkInstances ){
|
458
|
+
|
459
|
+
// Check if the provided option is an array.
|
460
|
+
if ( !$.isArray(linkInstances) ) {
|
461
|
+
throw new Error("noUiSlider: 'serialization."+(!index ? 'lower' : 'upper')+"' must be an array.");
|
462
|
+
}
|
463
|
+
|
464
|
+
$.each(linkInstances, function(){
|
465
|
+
|
466
|
+
// Check if entry is a Link.
|
467
|
+
if ( !(this instanceof $.Link) ) {
|
468
|
+
throw new Error("noUiSlider: 'serialization."+(!index ? 'lower' : 'upper')+"' can only contain Link instances.");
|
469
|
+
}
|
470
|
+
|
471
|
+
// Assign properties.
|
472
|
+
this.setIndex ( index );
|
473
|
+
this.setObject( sliders );
|
474
|
+
this.setFormatting( entry['format'] );
|
475
|
+
});
|
476
|
+
});
|
477
|
+
|
478
|
+
// If the slider has two handles and is RTL,
|
479
|
+
// reverse the serialization input. For one handle,
|
480
|
+
// lower is still lower.
|
481
|
+
if ( parsed.dir && parsed.handles > 1 ) {
|
482
|
+
parsed.ser.reverse();
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
486
|
+
// Test all developer settings and parse to assumption-safe values.
|
487
|
+
function test ( options, sliders ){
|
488
|
+
|
489
|
+
/* Every input option is tested and parsed. This'll prevent
|
490
|
+
endless validation in internal methods. These tests are
|
491
|
+
structured with an item for every option available. An
|
492
|
+
option can be marked as required by setting the 'r' flag.
|
493
|
+
The testing function is provided with three arguments:
|
494
|
+
- The provided value for the option;
|
495
|
+
- A reference to the options object;
|
496
|
+
- The name for the option;
|
497
|
+
|
498
|
+
The testing function returns false when an error is detected,
|
499
|
+
or true when everything is OK. It can also modify the option
|
500
|
+
object, to make sure all values can be correctly looped elsewhere. */
|
501
|
+
|
502
|
+
var parsed = {
|
503
|
+
xPct: []
|
504
|
+
,xVal: []
|
505
|
+
,xSteps: [ false ]
|
506
|
+
,margin: 0
|
507
|
+
}, tests;
|
508
|
+
|
509
|
+
tests = {
|
510
|
+
'step': { r: false, t: testStep },
|
511
|
+
'range': { r: true, t: testRange },
|
512
|
+
'start': { r: true, t: testStart },
|
513
|
+
'snap': { r: false, t: testSnap },
|
514
|
+
'connect': { r: true, t: testConnect },
|
515
|
+
'orientation': { r: false, t: testOrientation },
|
516
|
+
'margin': { r: false, t: testMargin },
|
517
|
+
'direction': { r: true, t: testDirection },
|
518
|
+
'behaviour': { r: true, t: testBehaviour },
|
519
|
+
'serialization': { r: true, t: testSerialization }
|
520
|
+
};
|
521
|
+
|
522
|
+
// Set defaults where applicable.
|
523
|
+
options = $.extend({
|
524
|
+
'connect': false,
|
525
|
+
'direction': 'ltr',
|
526
|
+
'behaviour': 'tap',
|
527
|
+
'orientation': 'horizontal'
|
528
|
+
}, options);
|
529
|
+
|
530
|
+
// Make sure the test for serialization runs.
|
531
|
+
options['serialization'] = $.extend({
|
532
|
+
'lower': []
|
533
|
+
,'upper': []
|
534
|
+
,'format': {}
|
535
|
+
}, options['serialization']);
|
536
|
+
|
537
|
+
// Run all options through a testing mechanism to ensure correct
|
538
|
+
// input. It should be noted that options might get modified to
|
539
|
+
// be handled properly. E.g. wrapping integers in arrays.
|
540
|
+
$.each( tests, function( name, test ){
|
541
|
+
|
542
|
+
if ( options[name] === undefined ) {
|
543
|
+
|
544
|
+
if ( test.r ) {
|
545
|
+
throw new Error("noUiSlider: '" + name + "' is required.");
|
546
|
+
}
|
547
|
+
|
548
|
+
return true;
|
549
|
+
}
|
550
|
+
|
551
|
+
test.t( parsed, options[name], sliders );
|
552
|
+
});
|
553
|
+
|
554
|
+
// Pre-define the styles.
|
555
|
+
parsed.style = parsed.ort ? 'top' : 'left';
|
556
|
+
|
557
|
+
return parsed;
|
558
|
+
}
|
536
559
|
|
537
|
-
return;
|
538
|
-
}
|
539
560
|
|
540
|
-
|
541
|
-
if ( isMethod ) {
|
542
|
-
this.target = false;
|
543
|
-
this.method = target;
|
544
|
-
return;
|
545
|
-
}
|
561
|
+
// DOM additions
|
546
562
|
|
547
|
-
|
548
|
-
|
563
|
+
// Append a handle to the base.
|
564
|
+
function addHandle ( options, index ) {
|
565
|
+
|
566
|
+
var handle = $('<div><div/></div>').addClass( Classes[2] ),
|
567
|
+
additions = [ '-lower', '-upper' ];
|
549
568
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
this.method = method;
|
554
|
-
return;
|
555
|
-
}
|
569
|
+
if ( options.dir ) {
|
570
|
+
additions.reverse();
|
571
|
+
}
|
556
572
|
|
557
|
-
|
558
|
-
|
559
|
-
|
573
|
+
handle.children().addClass(
|
574
|
+
Classes[3] + " " + Classes[3]+additions[index]
|
575
|
+
);
|
560
576
|
|
561
|
-
|
562
|
-
|
563
|
-
this.target = target;
|
577
|
+
return handle;
|
578
|
+
}
|
564
579
|
|
565
|
-
|
566
|
-
|
580
|
+
// Create a copy of an element-creating Link.
|
581
|
+
function addElement ( handle, link ) {
|
582
|
+
|
583
|
+
// If the Link requires creation of a new element,
|
584
|
+
// create this element and return a new Link instance.
|
585
|
+
if ( link.el ) {
|
567
586
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
587
|
+
link = new $.Link({
|
588
|
+
'target': $(link.el).clone().appendTo( handle ),
|
589
|
+
'method': link.method,
|
590
|
+
'format': link.formatting
|
591
|
+
}, true);
|
592
|
+
}
|
572
593
|
|
573
|
-
|
594
|
+
// Otherwise, return the reference.
|
595
|
+
return link;
|
596
|
+
}
|
574
597
|
|
575
|
-
|
576
|
-
|
598
|
+
// Loop all links for a handle.
|
599
|
+
function addElements ( elements, handle, formatting ) {
|
577
600
|
|
578
|
-
|
579
|
-
}
|
601
|
+
var index, list = [], standard = new $.Link({}, true);
|
580
602
|
|
581
|
-
|
582
|
-
|
603
|
+
// Use the Link interface to provide unified
|
604
|
+
// formatting for the .val() method.
|
605
|
+
standard.setFormatting(formatting);
|
583
606
|
|
584
|
-
|
585
|
-
|
586
|
-
this.target = target;
|
607
|
+
// The list now contains at least one element.
|
608
|
+
list.push( standard );
|
587
609
|
|
588
|
-
|
589
|
-
|
590
|
-
|
610
|
+
// Loop all links in either 'lower' or 'upper'.
|
611
|
+
for ( index = 0; index < elements.length; index++ ) {
|
612
|
+
list.push(addElement(handle, elements[index]));
|
613
|
+
}
|
591
614
|
|
592
|
-
|
593
|
-
|
615
|
+
return list;
|
616
|
+
}
|
594
617
|
|
595
|
-
|
596
|
-
|
618
|
+
// Go over all Links and assign them to a handle.
|
619
|
+
function addLinks ( options, handles ) {
|
597
620
|
|
598
|
-
|
599
|
-
if ( this.update && update === false ) {
|
600
|
-
return;
|
601
|
-
}
|
621
|
+
var index, links = [];
|
602
622
|
|
603
|
-
|
604
|
-
|
623
|
+
// Copy the links into a new array, instead of modifying
|
624
|
+
// the 'options.ser' list. This allows replacement of the invalid
|
625
|
+
// '.el' Links, while the others are still passed by reference.
|
626
|
+
for ( index = 0; index < options.handles; index++ ) {
|
605
627
|
|
606
|
-
|
607
|
-
|
628
|
+
// Append a new array.
|
629
|
+
links[index] = addElements(
|
630
|
+
options.ser[index],
|
631
|
+
handles[index].children(),
|
632
|
+
options.formatting
|
633
|
+
);
|
634
|
+
}
|
608
635
|
|
609
|
-
|
610
|
-
|
636
|
+
return links;
|
637
|
+
}
|
611
638
|
|
612
|
-
|
613
|
-
|
614
|
-
// When target is undefined, the target was a function.
|
615
|
-
// In that case, provided the slider as the calling scope.
|
616
|
-
// Use [0] to get the DOM element, not the $ instance.
|
617
|
-
this.method.call( this.target[0] || slider[0], value, handle, slider );
|
618
|
-
} else {
|
619
|
-
this.target[ this.method ]( value, handle, slider );
|
620
|
-
}
|
621
|
-
};
|
639
|
+
// Add the proper connection classes.
|
640
|
+
function addConnection ( connect, target, handles ) {
|
622
641
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
642
|
+
// Apply the required connection classes to the elements
|
643
|
+
// that need them. Some classes are made up for several
|
644
|
+
// segments listed in the class list, to allow easy
|
645
|
+
// renaming and provide a minor compression benefit.
|
646
|
+
switch ( connect ) {
|
647
|
+
case 1: target.addClass( Classes[7] );
|
648
|
+
handles[0].addClass( Classes[6] );
|
649
|
+
break;
|
650
|
+
case 3: handles[1].addClass( Classes[6] );
|
651
|
+
/* falls through */
|
652
|
+
case 2: handles[0].addClass( Classes[7] );
|
653
|
+
/* falls through */
|
654
|
+
case 0: target.addClass(Classes[6]);
|
655
|
+
break;
|
656
|
+
}
|
657
|
+
}
|
627
658
|
|
628
|
-
|
629
|
-
|
630
|
-
return this.formatting.from(a);
|
631
|
-
};
|
659
|
+
// Add handles and loop Link elements.
|
660
|
+
function addHandles ( options, base ) {
|
632
661
|
|
662
|
+
var index, handles = [];
|
633
663
|
|
634
|
-
//
|
664
|
+
// Append handles.
|
665
|
+
for ( index = 0; index < options.handles; index++ ) {
|
635
666
|
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
throwError("'step' is not numeric.");
|
640
|
-
}
|
641
|
-
|
642
|
-
// The step option can still be used to set stepping
|
643
|
-
// for linear sliders. Overwritten if set in 'range'.
|
644
|
-
parsed.xSteps[0] = entry;
|
645
|
-
}
|
646
|
-
|
647
|
-
function testRange ( parsed, entry ) {
|
648
|
-
|
649
|
-
// Filter incorrect input.
|
650
|
-
if ( typeof entry !== 'object' || $.isArray(entry) ) {
|
651
|
-
throwError("'range' is not an object.");
|
652
|
-
}
|
653
|
-
|
654
|
-
// Loop all entries.
|
655
|
-
$.each( entry, function ( index, value ) {
|
656
|
-
|
657
|
-
var percentage;
|
658
|
-
|
659
|
-
// Wrap numerical input in an array.
|
660
|
-
if ( typeof value === "number" ) {
|
661
|
-
value = [value];
|
662
|
-
}
|
663
|
-
|
664
|
-
// Reject any invalid input.
|
665
|
-
if ( !$.isArray( value ) ){
|
666
|
-
throwError("'range' contains invalid value.");
|
667
|
-
}
|
668
|
-
|
669
|
-
// Covert min/max syntax to 0 and 100.
|
670
|
-
if ( index === 'min' ) {
|
671
|
-
percentage = 0;
|
672
|
-
} else if ( index === 'max' ) {
|
673
|
-
percentage = 100;
|
674
|
-
} else {
|
675
|
-
percentage = parseFloat( index );
|
676
|
-
}
|
677
|
-
|
678
|
-
// Check for correct input.
|
679
|
-
if ( !isNumeric( percentage ) || !isNumeric( value[0] ) ) {
|
680
|
-
throwError("'range' value isn't numeric.");
|
681
|
-
}
|
682
|
-
|
683
|
-
// Store values.
|
684
|
-
parsed.xPct.push( percentage );
|
685
|
-
parsed.xVal.push( value[0] );
|
686
|
-
|
687
|
-
// NaN will evaluate to false too, but to keep
|
688
|
-
// logging clear, set step explicitly. Make sure
|
689
|
-
// not to override the 'step' setting with false.
|
690
|
-
if ( !percentage ) {
|
691
|
-
if ( !isNaN( value[1] ) ) {
|
692
|
-
parsed.xSteps[0] = value[1];
|
693
|
-
}
|
694
|
-
} else {
|
695
|
-
parsed.xSteps.push( isNaN(value[1]) ? false : value[1] );
|
696
|
-
}
|
697
|
-
});
|
698
|
-
|
699
|
-
$.each(parsed.xSteps, function(i,n){
|
700
|
-
|
701
|
-
// Ignore 'false' stepping.
|
702
|
-
if ( !n ) {
|
703
|
-
return true;
|
704
|
-
}
|
705
|
-
|
706
|
-
// Check if step fits. Not required, but this might serve some goal.
|
707
|
-
// !((parsed.xVal[i+1] - parsed.xVal[i]) % n);
|
708
|
-
|
709
|
-
// Factor to range ratio
|
710
|
-
parsed.xSteps[i] = fromPercentage([
|
711
|
-
parsed.xVal[i]
|
712
|
-
,parsed.xVal[i+1]
|
713
|
-
], n) / subRangeRatio (
|
714
|
-
parsed.xPct[i],
|
715
|
-
parsed.xPct[i+1] );
|
716
|
-
});
|
717
|
-
}
|
718
|
-
|
719
|
-
function testStart ( parsed, entry ) {
|
720
|
-
|
721
|
-
if ( typeof entry === "number" ) {
|
722
|
-
entry = [entry];
|
723
|
-
}
|
724
|
-
|
725
|
-
// Validate input. Values aren't tested, the internal Link will do
|
726
|
-
// that and provide a valid location.
|
727
|
-
if ( !$.isArray( entry ) || !entry.length || entry.length > 2 ) {
|
728
|
-
throwError("'start' option is incorrect.");
|
729
|
-
}
|
730
|
-
|
731
|
-
// Store the number of handles.
|
732
|
-
parsed.handles = entry.length;
|
733
|
-
|
734
|
-
// When the slider is initialized, the .val method will
|
735
|
-
// be called with the start options.
|
736
|
-
parsed.start = entry;
|
737
|
-
}
|
738
|
-
|
739
|
-
function testSnap ( parsed, entry ) {
|
740
|
-
|
741
|
-
// Enforce 100% stepping within subranges.
|
742
|
-
parsed.snap = entry;
|
743
|
-
|
744
|
-
if ( typeof entry !== 'boolean' ){
|
745
|
-
throwError("'snap' option must be a boolean.");
|
746
|
-
}
|
747
|
-
}
|
748
|
-
|
749
|
-
function testConnect ( parsed, entry ) {
|
750
|
-
|
751
|
-
if ( entry === 'lower' && parsed.handles === 1 ) {
|
752
|
-
parsed.connect = 1;
|
753
|
-
} else if ( entry === 'upper' && parsed.handles === 1 ) {
|
754
|
-
parsed.connect = 2;
|
755
|
-
} else if ( entry === true && parsed.handles === 2 ) {
|
756
|
-
parsed.connect = 3;
|
757
|
-
} else if ( entry === false ) {
|
758
|
-
parsed.connect = 0;
|
759
|
-
} else {
|
760
|
-
throwError("'connect' option was doesn't match handle count.");
|
761
|
-
}
|
762
|
-
}
|
763
|
-
|
764
|
-
function testOrientation ( parsed, entry ) {
|
765
|
-
|
766
|
-
// Set orientation to an a numerical value for easy
|
767
|
-
// array selection.
|
768
|
-
switch ( entry ){
|
769
|
-
case 'horizontal':
|
770
|
-
parsed.ort = 0;
|
771
|
-
break;
|
772
|
-
case 'vertical':
|
773
|
-
parsed.ort = 1;
|
774
|
-
break;
|
775
|
-
default:
|
776
|
-
throwError("'orientation' option is invalid.");
|
777
|
-
}
|
778
|
-
}
|
779
|
-
|
780
|
-
function testMargin ( parsed, entry ) {
|
781
|
-
|
782
|
-
if ( parsed.xPct.length > 2 ) {
|
783
|
-
throwError("'margin' option is only supported on linear sliders.");
|
784
|
-
}
|
785
|
-
|
786
|
-
// Parse value to range and store. As xVal is checked
|
787
|
-
// to be no bigger than 2, use it as range.
|
788
|
-
parsed.margin = fromPercentage(parsed.xVal, entry);
|
789
|
-
|
790
|
-
if ( !isNumeric(entry) ){
|
791
|
-
throwError("'margin' option must be numeric.");
|
792
|
-
}
|
793
|
-
}
|
794
|
-
|
795
|
-
function testDirection ( parsed, entry ) {
|
796
|
-
|
797
|
-
// Set direction as a numerical value for easy parsing.
|
798
|
-
// Invert connection for RTL sliders, so that the proper
|
799
|
-
// handles get the connect/background classes.
|
800
|
-
switch ( entry ) {
|
801
|
-
case 'ltr':
|
802
|
-
parsed.dir = 0;
|
803
|
-
break;
|
804
|
-
case 'rtl':
|
805
|
-
parsed.dir = 1;
|
806
|
-
parsed.connect = [0,2,1,3][parsed.connect];
|
807
|
-
break;
|
808
|
-
default:
|
809
|
-
throwError("'direction' option was not recognized.");
|
810
|
-
}
|
811
|
-
}
|
812
|
-
|
813
|
-
function testBehaviour ( parsed, entry ) {
|
814
|
-
|
815
|
-
// Make sure the input is a string.
|
816
|
-
if ( typeof entry !== 'string' ) {
|
817
|
-
throwError("'behaviour' must be a string containing options.");
|
818
|
-
}
|
819
|
-
|
820
|
-
// Check if the string contains any keywords.
|
821
|
-
// None are required.
|
822
|
-
var tap = entry.indexOf('tap') >= 0,
|
823
|
-
extend = entry.indexOf('extend') >= 0,
|
824
|
-
drag = entry.indexOf('drag') >= 0,
|
825
|
-
fixed = entry.indexOf('fixed') >= 0,
|
826
|
-
snap = entry.indexOf('snap') >= 0;
|
827
|
-
|
828
|
-
parsed.events = {
|
829
|
-
tap: tap || snap,
|
830
|
-
extend: extend,
|
831
|
-
drag: drag,
|
832
|
-
fixed: fixed,
|
833
|
-
snap: snap
|
834
|
-
};
|
835
|
-
}
|
836
|
-
|
837
|
-
function testSerialization ( parsed, entry, sliders ) {
|
838
|
-
|
839
|
-
parsed.ser = [ entry['lower'], entry['upper'] ];
|
840
|
-
parsed.formatting = new Format( entry['format'] );
|
841
|
-
|
842
|
-
$.each( parsed.ser, function( i, a ){
|
843
|
-
|
844
|
-
// Check if the provided option is an array.
|
845
|
-
if ( !$.isArray(a) ) {
|
846
|
-
throwError("'serialization."+(!i?'lower':'upper')+"' must be an array.");
|
847
|
-
}
|
848
|
-
|
849
|
-
$.each(a, function(){
|
850
|
-
|
851
|
-
// Check if entry is a Link.
|
852
|
-
if ( !(this instanceof Link) ) {
|
853
|
-
throwError("'serialization."+(!i?'lower':'upper')+"' can only contain Link instances.");
|
854
|
-
}
|
855
|
-
|
856
|
-
// Assign other properties.
|
857
|
-
this.N = i;
|
858
|
-
this.obj = sliders;
|
859
|
-
this.scope = this.scope || sliders;
|
860
|
-
|
861
|
-
// Run internal validator.
|
862
|
-
this.formatting = new Format($.extend({}
|
863
|
-
,entry['format']
|
864
|
-
,this.formatting
|
865
|
-
));
|
866
|
-
});
|
867
|
-
});
|
868
|
-
|
869
|
-
// If the slider has two handles and is RTL,
|
870
|
-
// reverse the serialization input. For one handle,
|
871
|
-
// lower is still lower.
|
872
|
-
if ( parsed.dir && parsed.handles > 1 ) {
|
873
|
-
parsed.ser.reverse();
|
874
|
-
}
|
875
|
-
}
|
876
|
-
|
877
|
-
// Test all developer settings and parse to assumption-safe values.
|
878
|
-
function test ( options, sliders ){
|
879
|
-
|
880
|
-
/* Every input option is tested and parsed. This'll prevent
|
881
|
-
endless validation in internal methods. These tests are
|
882
|
-
structured with an item for every option available. An
|
883
|
-
option can be marked as required by setting the 'r' flag.
|
884
|
-
The testing function is provided with three arguments:
|
885
|
-
- The provided value for the option;
|
886
|
-
- A reference to the options object;
|
887
|
-
- The name for the option;
|
888
|
-
|
889
|
-
The testing function returns false when an error is detected,
|
890
|
-
or true when everything is OK. It can also modify the option
|
891
|
-
object, to make sure all values can be correctly looped elsewhere. */
|
892
|
-
|
893
|
-
var parsed = {
|
894
|
-
xPct: []
|
895
|
-
,xVal: []
|
896
|
-
,xSteps: [ false ]
|
897
|
-
,margin: 0
|
898
|
-
}, tests;
|
899
|
-
|
900
|
-
tests = {
|
901
|
-
'step': { r: false, t: testStep },
|
902
|
-
'range': { r: true, t: testRange },
|
903
|
-
'start': { r: true, t: testStart },
|
904
|
-
'snap': { r: false, t: testSnap },
|
905
|
-
'connect': { r: true, t: testConnect },
|
906
|
-
'orientation': { r: false, t: testOrientation },
|
907
|
-
'margin': { r: false, t: testMargin },
|
908
|
-
'direction': { r: true, t: testDirection },
|
909
|
-
'behaviour': { r: true, t: testBehaviour },
|
910
|
-
'serialization': { r: true, t: testSerialization }
|
911
|
-
};
|
912
|
-
|
913
|
-
// Set defaults where applicable.
|
914
|
-
options = $.extend({
|
915
|
-
'connect': false
|
916
|
-
,'direction': 'ltr'
|
917
|
-
,'behaviour': 'tap'
|
918
|
-
,'orientation': 'horizontal'
|
919
|
-
}, options);
|
920
|
-
|
921
|
-
// Make sure the test for serialization runs.
|
922
|
-
options['serialization'] = $.extend({
|
923
|
-
'lower': []
|
924
|
-
,'upper': []
|
925
|
-
,'format': {}
|
926
|
-
}, options['serialization']);
|
927
|
-
|
928
|
-
// Run all options through a testing mechanism to ensure correct
|
929
|
-
// input. It should be noted that options might get modified to
|
930
|
-
// be handled properly. E.g. wrapping integers in arrays.
|
931
|
-
$.each( tests, function( name, test ){
|
932
|
-
|
933
|
-
if ( options[name] === undefined ) {
|
934
|
-
if ( test.r ) {
|
935
|
-
throwError("'" + name + "' is required.");
|
936
|
-
} else {
|
937
|
-
return true;
|
938
|
-
}
|
939
|
-
}
|
940
|
-
|
941
|
-
test.t( parsed, options[name], sliders );
|
942
|
-
});
|
943
|
-
|
944
|
-
// Pre-define the styles.
|
945
|
-
parsed.style = parsed.ort ? 'top' : 'left';
|
946
|
-
|
947
|
-
return parsed;
|
948
|
-
}
|
667
|
+
// Keep a list of all added handles.
|
668
|
+
handles.push( addHandle( options, index ).appendTo(base) );
|
669
|
+
}
|
949
670
|
|
671
|
+
return handles;
|
672
|
+
}
|
950
673
|
|
951
|
-
//
|
674
|
+
// Initialize a single slider.
|
675
|
+
function addSlider ( options, target ) {
|
952
676
|
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
handle.children().addClass(
|
964
|
-
Classes[3] + " " + Classes[3]+additions[index]
|
965
|
-
);
|
966
|
-
|
967
|
-
return handle;
|
968
|
-
}
|
969
|
-
|
970
|
-
// Create a copy of an element-creating Link.
|
971
|
-
function addElement ( handle, link ) {
|
972
|
-
|
973
|
-
// If the Link requires creation of a new element,
|
974
|
-
// create this element and return a new Link instance.
|
975
|
-
if ( link.el ) {
|
976
|
-
link = new Link({
|
977
|
-
'target': $(link.el).clone().appendTo( handle ),
|
978
|
-
'method': link.method,
|
979
|
-
'format': link.formatting
|
980
|
-
}, true);
|
981
|
-
}
|
982
|
-
|
983
|
-
// Otherwise, return the reference.
|
984
|
-
return link;
|
985
|
-
}
|
986
|
-
|
987
|
-
// Loop all links for a handle.
|
988
|
-
function addElements ( elements, handle, formatting ) {
|
989
|
-
|
990
|
-
var index, list = [];
|
991
|
-
|
992
|
-
// Use the Link interface to provide unified
|
993
|
-
// formatting for the .val() method.
|
994
|
-
list.push(
|
995
|
-
new Link({
|
996
|
-
'format': formatting
|
997
|
-
}, true)
|
998
|
-
);
|
999
|
-
|
1000
|
-
// Loop all links in either 'lower' or 'upper'.
|
1001
|
-
for ( index = 0; index < elements.length; index++ ) {
|
1002
|
-
list.push(addElement(handle, elements[index]));
|
1003
|
-
}
|
1004
|
-
|
1005
|
-
return list;
|
1006
|
-
}
|
1007
|
-
|
1008
|
-
// Go over all Links and assign them to a handle.
|
1009
|
-
function addLinks ( options, handles ) {
|
1010
|
-
|
1011
|
-
var index, links = [];
|
1012
|
-
|
1013
|
-
// Copy the links into a new array, instead of modifying
|
1014
|
-
// the 'options.ser' list. This allows replacement of the invalid
|
1015
|
-
// '.el' Links, while the others are still passed by reference.
|
1016
|
-
for ( index = 0; index < options.handles; index++ ) {
|
1017
|
-
|
1018
|
-
// Append a new array.
|
1019
|
-
links[index] = addElements(
|
1020
|
-
options.ser[index],
|
1021
|
-
handles[index].children(),
|
1022
|
-
options.formatting
|
1023
|
-
);
|
1024
|
-
}
|
1025
|
-
|
1026
|
-
return links;
|
1027
|
-
}
|
1028
|
-
|
1029
|
-
// Add the proper connection classes.
|
1030
|
-
function addConnection ( connect, target, handles ) {
|
1031
|
-
|
1032
|
-
// Apply the required connection classes to the elements
|
1033
|
-
// that need them. Some classes are made up for several
|
1034
|
-
// segments listed in the class list, to allow easy
|
1035
|
-
// renaming and provide a minor compression benefit.
|
1036
|
-
switch ( connect ) {
|
1037
|
-
case 1: target.addClass( Classes[7] );
|
1038
|
-
handles[0].addClass( Classes[6] );
|
1039
|
-
break;
|
1040
|
-
case 3: handles[1].addClass( Classes[6] );
|
1041
|
-
/* falls through */
|
1042
|
-
case 2: handles[0].addClass( Classes[7] );
|
1043
|
-
/* falls through */
|
1044
|
-
case 0: target.addClass(Classes[6]);
|
1045
|
-
break;
|
1046
|
-
}
|
1047
|
-
}
|
1048
|
-
|
1049
|
-
// Add handles and loop Link elements.
|
1050
|
-
function addHandles ( options, base ) {
|
1051
|
-
|
1052
|
-
var index, handles = [];
|
1053
|
-
|
1054
|
-
// Append handles.
|
1055
|
-
for ( index = 0; index < options.handles; index++ ) {
|
1056
|
-
|
1057
|
-
// Keep a list of all added handles.
|
1058
|
-
handles.push( addHandle( options, index ).appendTo(base) );
|
1059
|
-
}
|
1060
|
-
|
1061
|
-
return handles;
|
1062
|
-
}
|
1063
|
-
|
1064
|
-
// Initialize a single slider.
|
1065
|
-
function addSlider ( options, target ) {
|
1066
|
-
|
1067
|
-
// Apply classes and data to the target.
|
1068
|
-
target.addClass([
|
1069
|
-
Classes[0],
|
1070
|
-
Classes[8 + options.dir],
|
1071
|
-
Classes[4 + options.ort]
|
1072
|
-
].join(' '));
|
1073
|
-
|
1074
|
-
return $('<div/>').appendTo(target).addClass( Classes[1] );
|
1075
|
-
}
|
677
|
+
// Apply classes and data to the target.
|
678
|
+
target.addClass([
|
679
|
+
Classes[0],
|
680
|
+
Classes[8 + options.dir],
|
681
|
+
Classes[4 + options.ort]
|
682
|
+
].join(' '));
|
683
|
+
|
684
|
+
return $('<div/>').appendTo(target).addClass( Classes[1] );
|
685
|
+
}
|
1076
686
|
|
1077
687
|
|
1078
688
|
// Slider scope
|
1079
689
|
|
1080
|
-
|
690
|
+
function closure ( target, options, originalOptions ){
|
1081
691
|
|
1082
692
|
// Internal variables
|
1083
693
|
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
694
|
+
// All variables local to 'closure' are marked $.
|
695
|
+
var $Target = $(target),
|
696
|
+
$Locations = [-1, -1],
|
697
|
+
$Base,
|
698
|
+
$Serialization,
|
699
|
+
$Handles;
|
1090
700
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
701
|
+
// Shorthand for base dimensions.
|
702
|
+
function baseSize ( ) {
|
703
|
+
return $Base[['width', 'height'][options.ort]]();
|
704
|
+
}
|
1095
705
|
|
1096
706
|
|
1097
707
|
// External event handling
|
1098
708
|
|
1099
|
-
|
709
|
+
function fireEvents ( events ) {
|
1100
710
|
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
711
|
+
// Use the external api to get the values.
|
712
|
+
// Wrap the values in an array, as .trigger takes
|
713
|
+
// only one additional argument.
|
714
|
+
var index, values = [ $Target.val() ];
|
1105
715
|
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
716
|
+
for ( index = 0; index < events.length; index++ ){
|
717
|
+
$Target.trigger(events[index], values);
|
718
|
+
}
|
719
|
+
}
|
1110
720
|
|
1111
721
|
|
1112
722
|
// Handle placement
|
1113
723
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
724
|
+
// Test suggested values and apply margin, step.
|
725
|
+
function setHandle ( handle, to, delimit ) {
|
726
|
+
|
727
|
+
var n = handle[0] !== $Handles[0][0] ? 1 : 0,
|
728
|
+
lower = $Locations[0] + options.margin,
|
729
|
+
upper = $Locations[1] - options.margin;
|
730
|
+
|
731
|
+
// Don't delimit range dragging.
|
732
|
+
if ( delimit && $Handles.length > 1 ) {
|
733
|
+
to = n ? Math.max( to, lower ) : Math.min( to, upper );
|
734
|
+
}
|
735
|
+
|
736
|
+
// Handle the step option.
|
737
|
+
if ( to < 100 ){
|
738
|
+
to = getStep(options, to);
|
739
|
+
}
|
740
|
+
|
741
|
+
// Limit to 0/100 for .val input, trim anything beyond 7 digits, as
|
742
|
+
// JavaScript has some issues in its floating point implementation.
|
743
|
+
to = limit(parseFloat(to.toFixed(7)));
|
744
|
+
|
745
|
+
// Return falsy if handle can't move. False for 0 or 100 limit,
|
746
|
+
// '0' for limiting by another handle.
|
747
|
+
if ( to === $Locations[n] ) {
|
748
|
+
if ( $Handles.length === 1 ) {
|
749
|
+
return false;
|
750
|
+
}
|
751
|
+
return ( to === lower || to === upper ) ? 0 : false;
|
752
|
+
}
|
753
|
+
|
754
|
+
// Set the handle to the new position.
|
755
|
+
handle.css( options.style, to + '%' );
|
756
|
+
|
757
|
+
// Force proper handle stacking
|
758
|
+
if ( handle.is(':first-child') ) {
|
759
|
+
handle.toggleClass(Classes[17], to > 50 );
|
760
|
+
}
|
761
|
+
|
762
|
+
// Update locations.
|
763
|
+
$Locations[n] = to;
|
764
|
+
|
765
|
+
// Invert the value if this is a right-to-left slider.
|
766
|
+
if ( options.dir ) {
|
767
|
+
to = 100 - to;
|
768
|
+
}
|
769
|
+
|
770
|
+
// Write values to serialization Links.
|
771
|
+
// Convert the value to the correct relative representation.
|
772
|
+
// Convert the value to the slider stepping/range.
|
773
|
+
$($Serialization[n]).each(function(){
|
774
|
+
this.write( fromStepping( options, to ), handle.children(), $Target );
|
775
|
+
});
|
776
|
+
|
777
|
+
return true;
|
778
|
+
}
|
779
|
+
|
780
|
+
// Delimit proposed values for handle positions.
|
781
|
+
function getPositions ( a, b, delimit ) {
|
782
|
+
|
783
|
+
// Add movement to current position.
|
784
|
+
var c = a + b[0], d = a + b[1];
|
785
|
+
|
786
|
+
// Only alter the other position on drag,
|
787
|
+
// not on standard sliding.
|
788
|
+
if ( delimit ) {
|
789
|
+
if ( c < 0 ) {
|
790
|
+
d += Math.abs(c);
|
791
|
+
}
|
792
|
+
if ( d > 100 ) {
|
793
|
+
c -= ( d - 100 );
|
794
|
+
}
|
795
|
+
|
796
|
+
// Limit values to 0 and 100.
|
797
|
+
return [limit(c), limit(d)];
|
798
|
+
}
|
799
|
+
|
800
|
+
return [c,d];
|
801
|
+
}
|
802
|
+
|
803
|
+
// Handles movement by tapping.
|
804
|
+
function jump ( handle, to, instant ) {
|
805
|
+
|
806
|
+
if ( !instant ) {
|
807
|
+
// Flag the slider as it is now in a transitional state.
|
808
|
+
// Transition takes 300 ms, so re-enable the slider afterwards.
|
809
|
+
addClassFor( $Target, Classes[14], 300 );
|
810
|
+
}
|
811
|
+
|
812
|
+
// Move the handle to the new position.
|
813
|
+
setHandle( handle, to, false );
|
814
|
+
|
815
|
+
fireEvents(['slide', 'set', 'change']);
|
816
|
+
}
|
1151
817
|
|
1152
|
-
// Update locations.
|
1153
|
-
$Locations[n] = to;
|
1154
818
|
|
1155
|
-
|
1156
|
-
if ( options.dir ) {
|
1157
|
-
to = 100 - to;
|
1158
|
-
}
|
819
|
+
// Events
|
1159
820
|
|
1160
|
-
|
1161
|
-
|
1162
|
-
$($Serialization[n]).each(function(){
|
1163
|
-
this.write( options, to, handle.children(), $Target );
|
1164
|
-
});
|
821
|
+
// Handler for attaching events trough a proxy.
|
822
|
+
function attach ( events, element, callback, data ) {
|
1165
823
|
|
1166
|
-
|
1167
|
-
|
824
|
+
// Add the noUiSlider namespace to all events.
|
825
|
+
events = events.replace( /\s/g, namespace + ' ' ) + namespace;
|
1168
826
|
|
1169
|
-
|
1170
|
-
|
827
|
+
// Bind a closure on the target.
|
828
|
+
return element.on( events, function( e ){
|
1171
829
|
|
1172
|
-
|
1173
|
-
|
830
|
+
// jQuery and Zepto handle unset attributes differently.
|
831
|
+
var disabled = $Target.attr('disabled');
|
832
|
+
disabled = !( disabled === undefined || disabled === null );
|
1174
833
|
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
if ( d > 100 ) {
|
1182
|
-
c -= ( d - 100 );
|
1183
|
-
}
|
834
|
+
// Test if there is anything that should prevent an event
|
835
|
+
// from being handled, such as a disabled state or an active
|
836
|
+
// 'tap' transition.
|
837
|
+
if( $Target.hasClass( Classes[14] ) || disabled ) {
|
838
|
+
return false;
|
839
|
+
}
|
1184
840
|
|
1185
|
-
|
1186
|
-
|
1187
|
-
}
|
841
|
+
e = fixEvent(e);
|
842
|
+
e.calcPoint = e.points[ options.ort ];
|
1188
843
|
|
1189
|
-
|
1190
|
-
|
844
|
+
// Call the event handler with the event [ and additional data ].
|
845
|
+
callback ( e, data );
|
846
|
+
});
|
847
|
+
}
|
1191
848
|
|
1192
|
-
|
1193
|
-
|
849
|
+
// Handle movement on document for handle and range drag.
|
850
|
+
function move ( event, data ) {
|
1194
851
|
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
addClassFor( $Target, Classes[14], 300 );
|
1199
|
-
}
|
852
|
+
var handles = data.handles || $Handles, positions, state = false,
|
853
|
+
proposal = ((event.calcPoint - data.start) * 100) / baseSize(),
|
854
|
+
h = handles[0][0] !== $Handles[0][0] ? 1 : 0;
|
1200
855
|
|
1201
|
-
|
1202
|
-
|
856
|
+
// Calculate relative positions for the handles.
|
857
|
+
positions = getPositions( proposal, data.positions, handles.length > 1);
|
1203
858
|
|
1204
|
-
|
1205
|
-
}
|
859
|
+
state = setHandle ( handles[0], positions[h], handles.length === 1 );
|
1206
860
|
|
861
|
+
if ( handles.length > 1 ) {
|
862
|
+
state = setHandle ( handles[1], positions[h?0:1], false ) || state;
|
863
|
+
}
|
1207
864
|
|
1208
|
-
//
|
865
|
+
// Fire the 'slide' event if any handle moved.
|
866
|
+
if ( state ) {
|
867
|
+
fireEvents(['slide']);
|
868
|
+
}
|
869
|
+
}
|
1209
870
|
|
1210
|
-
|
1211
|
-
|
871
|
+
// Unbind move events on document, call callbacks.
|
872
|
+
function end ( event ) {
|
1212
873
|
|
1213
|
-
|
1214
|
-
|
874
|
+
// The handle is no longer active, so remove the class.
|
875
|
+
$('.' + Classes[15]).removeClass(Classes[15]);
|
1215
876
|
|
1216
|
-
|
1217
|
-
|
877
|
+
// Remove cursor styles and text-selection events bound to the body.
|
878
|
+
if ( event.cursor ) {
|
879
|
+
$('body').css('cursor', '').off( namespace );
|
880
|
+
}
|
1218
881
|
|
1219
|
-
|
1220
|
-
|
1221
|
-
disabled = !( disabled === undefined || disabled === null );
|
882
|
+
// Unbind the move and end events, which are added on 'start'.
|
883
|
+
doc.off( namespace );
|
1222
884
|
|
1223
|
-
|
1224
|
-
|
1225
|
-
// 'tap' transition.
|
1226
|
-
if( $Target.hasClass( Classes[14] ) || disabled ) {
|
1227
|
-
return false;
|
1228
|
-
}
|
885
|
+
// Remove dragging class.
|
886
|
+
$Target.removeClass(Classes[12]);
|
1229
887
|
|
1230
|
-
|
1231
|
-
|
888
|
+
// Fire the change and set events.
|
889
|
+
fireEvents(['set', 'change']);
|
890
|
+
}
|
1232
891
|
|
1233
|
-
|
1234
|
-
|
1235
|
-
});
|
1236
|
-
}
|
892
|
+
// Bind move events on document.
|
893
|
+
function start ( event, data ) {
|
1237
894
|
|
1238
|
-
|
1239
|
-
|
895
|
+
// Mark the handle as 'active' so it can be styled.
|
896
|
+
if( data.handles.length === 1 ) {
|
897
|
+
data.handles[0].children().addClass(Classes[15]);
|
898
|
+
}
|
1240
899
|
|
1241
|
-
|
1242
|
-
|
1243
|
-
h = handles[0][0] !== $Handles[0][0] ? 1 : 0;
|
900
|
+
// A drag should never propagate up to the 'tap' event.
|
901
|
+
event.stopPropagation();
|
1244
902
|
|
1245
|
-
|
1246
|
-
|
903
|
+
// Attach the move event.
|
904
|
+
attach ( actions.move, doc, move, {
|
905
|
+
start: event.calcPoint,
|
906
|
+
handles: data.handles,
|
907
|
+
positions: [
|
908
|
+
$Locations[0],
|
909
|
+
$Locations[$Handles.length - 1]
|
910
|
+
]
|
911
|
+
});
|
1247
912
|
|
1248
|
-
|
913
|
+
// Unbind all movement when the drag ends.
|
914
|
+
attach ( actions.end, doc, end, null );
|
1249
915
|
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
916
|
+
// Text selection isn't an issue on touch devices,
|
917
|
+
// so adding cursor styles can be skipped.
|
918
|
+
if ( event.cursor ) {
|
1253
919
|
|
1254
|
-
|
1255
|
-
|
1256
|
-
fireEvents(['slide']);
|
1257
|
-
}
|
1258
|
-
}
|
920
|
+
// Prevent the 'I' cursor and extend the range-drag cursor.
|
921
|
+
$('body').css('cursor', $(event.target).css('cursor'));
|
1259
922
|
|
1260
|
-
|
1261
|
-
|
923
|
+
// Mark the target with a dragging state.
|
924
|
+
if ( $Handles.length > 1 ) {
|
925
|
+
$Target.addClass(Classes[12]);
|
926
|
+
}
|
1262
927
|
|
1263
|
-
|
1264
|
-
|
928
|
+
// Prevent text selection when dragging the handles.
|
929
|
+
$('body').on('selectstart' + namespace, false);
|
930
|
+
}
|
931
|
+
}
|
1265
932
|
|
1266
|
-
|
1267
|
-
|
1268
|
-
$('body').css('cursor', '').off( namespace );
|
1269
|
-
}
|
933
|
+
// Move closest handle to tapped location.
|
934
|
+
function tap ( event ) {
|
1270
935
|
|
1271
|
-
|
1272
|
-
doc.off( namespace );
|
936
|
+
var location = event.calcPoint, total = 0, to;
|
1273
937
|
|
1274
|
-
|
1275
|
-
|
938
|
+
// The tap event shouldn't propagate up and cause 'edge' to run.
|
939
|
+
event.stopPropagation();
|
1276
940
|
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
941
|
+
// Add up the handle offsets.
|
942
|
+
$.each( $Handles, function(){
|
943
|
+
total += this.offset()[ options.style ];
|
944
|
+
});
|
1280
945
|
|
1281
|
-
|
1282
|
-
|
946
|
+
// Find the handle closest to the tapped position.
|
947
|
+
total = ( location < total/2 || $Handles.length === 1 ) ? 0 : 1;
|
1283
948
|
|
1284
|
-
|
1285
|
-
if( data.handles.length === 1 ) {
|
1286
|
-
data.handles[0].children().addClass(Classes[15]);
|
1287
|
-
}
|
949
|
+
location -= $Base.offset()[ options.style ];
|
1288
950
|
|
1289
|
-
|
1290
|
-
|
951
|
+
// Calculate the new position.
|
952
|
+
to = ( location * 100 ) / baseSize();
|
1291
953
|
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
handles: data.handles,
|
1296
|
-
positions: [
|
1297
|
-
$Locations[0],
|
1298
|
-
$Locations[$Handles.length - 1]
|
1299
|
-
]
|
1300
|
-
});
|
954
|
+
// Find the closest handle and calculate the tapped point.
|
955
|
+
// The set handle to the new position.
|
956
|
+
jump( $Handles[total], to, options.events.snap );
|
1301
957
|
|
1302
|
-
|
1303
|
-
|
958
|
+
if ( options.events.snap ) {
|
959
|
+
start(event, { handles: [$Handles[total]] });
|
960
|
+
}
|
961
|
+
}
|
1304
962
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
if ( event.cursor ) {
|
963
|
+
// Move handle to edges when target gets tapped.
|
964
|
+
function edge ( event ) {
|
1308
965
|
|
1309
|
-
|
1310
|
-
|
966
|
+
var i = event.calcPoint < $Base.offset()[ options.style ],
|
967
|
+
to = i ? 0 : 100;
|
1311
968
|
|
1312
|
-
|
1313
|
-
if ( $Handles.length > 1 ) {
|
1314
|
-
$Target.addClass(Classes[12]);
|
1315
|
-
}
|
969
|
+
i = i ? 0 : $Handles.length - 1;
|
1316
970
|
|
1317
|
-
|
1318
|
-
|
1319
|
-
}
|
1320
|
-
}
|
971
|
+
jump( $Handles[i], to, false );
|
972
|
+
}
|
1321
973
|
|
1322
|
-
|
1323
|
-
|
974
|
+
// Attach events to several slider parts.
|
975
|
+
function events ( behaviour ) {
|
1324
976
|
|
1325
|
-
|
977
|
+
var i, drag;
|
1326
978
|
|
1327
|
-
|
1328
|
-
|
979
|
+
// Attach the standard drag event to the handles.
|
980
|
+
if ( !behaviour.fixed ) {
|
1329
981
|
|
1330
|
-
|
1331
|
-
$.each( $Handles, function(){
|
1332
|
-
total += this.offset()[ options.style ];
|
1333
|
-
});
|
982
|
+
for ( i = 0; i < $Handles.length; i++ ) {
|
1334
983
|
|
1335
|
-
|
1336
|
-
|
984
|
+
// These events are only bound to the visual handle
|
985
|
+
// element, not the 'real' origin element.
|
986
|
+
attach ( actions.start, $Handles[i].children(), start, {
|
987
|
+
handles: [ $Handles[i] ]
|
988
|
+
});
|
989
|
+
}
|
990
|
+
}
|
1337
991
|
|
1338
|
-
|
992
|
+
// Attach the tap event to the slider base.
|
993
|
+
if ( behaviour.tap ) {
|
994
|
+
attach ( actions.start, $Base, tap, {
|
995
|
+
handles: $Handles
|
996
|
+
});
|
997
|
+
}
|
1339
998
|
|
1340
|
-
|
1341
|
-
|
999
|
+
// Extend tapping behaviour to target
|
1000
|
+
if ( behaviour.extend ) {
|
1342
1001
|
|
1343
|
-
|
1344
|
-
// The set handle to the new position.
|
1345
|
-
jump( $Handles[total], to, options.events.snap );
|
1002
|
+
$Target.addClass( Classes[16] );
|
1346
1003
|
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1004
|
+
if ( behaviour.tap ) {
|
1005
|
+
attach ( actions.start, $Target, edge, {
|
1006
|
+
handles: $Handles
|
1007
|
+
});
|
1008
|
+
}
|
1009
|
+
}
|
1351
1010
|
|
1352
|
-
|
1353
|
-
|
1011
|
+
// Make the range dragable.
|
1012
|
+
if ( behaviour.drag ){
|
1354
1013
|
|
1355
|
-
|
1356
|
-
to = i ? 0 : 100;
|
1014
|
+
drag = $Base.find( '.' + Classes[7] ).addClass( Classes[10] );
|
1357
1015
|
|
1358
|
-
|
1016
|
+
// When the range is fixed, the entire range can
|
1017
|
+
// be dragged by the handles. The handle in the first
|
1018
|
+
// origin will propagate the start event upward,
|
1019
|
+
// but it needs to be bound manually on the other.
|
1020
|
+
if ( behaviour.fixed ) {
|
1021
|
+
drag = drag.add($Base.children().not( drag ).children());
|
1022
|
+
}
|
1359
1023
|
|
1360
|
-
|
1361
|
-
|
1024
|
+
attach ( actions.start, drag, start, {
|
1025
|
+
handles: $Handles
|
1026
|
+
});
|
1027
|
+
}
|
1028
|
+
}
|
1362
1029
|
|
1363
|
-
// Attach events to several slider parts.
|
1364
|
-
function events ( behaviour ) {
|
1365
1030
|
|
1366
|
-
|
1031
|
+
// Initialize slider
|
1367
1032
|
|
1368
|
-
|
1369
|
-
|
1033
|
+
// Throw an error if the slider was already initialized.
|
1034
|
+
if ( $Target.hasClass(Classes[0]) ) {
|
1035
|
+
throw new Error('Slider was already initialized.');
|
1036
|
+
}
|
1370
1037
|
|
1371
|
-
|
1038
|
+
// Create the base element, initialise HTML and set classes.
|
1039
|
+
// Add handles and links.
|
1040
|
+
$Base = addSlider( options, $Target );
|
1041
|
+
$Handles = addHandles( options, $Base );
|
1042
|
+
$Serialization = addLinks( options, $Handles );
|
1372
1043
|
|
1373
|
-
|
1374
|
-
|
1375
|
-
attach ( actions.start, $Handles[i].children(), start, {
|
1376
|
-
handles: [ $Handles[i] ]
|
1377
|
-
});
|
1378
|
-
}
|
1379
|
-
}
|
1044
|
+
// Set the connect classes.
|
1045
|
+
addConnection ( options.connect, $Target, $Handles );
|
1380
1046
|
|
1381
|
-
|
1382
|
-
|
1383
|
-
attach ( actions.start, $Base, tap, {
|
1384
|
-
handles: $Handles
|
1385
|
-
});
|
1386
|
-
}
|
1047
|
+
// Attach user events.
|
1048
|
+
events( options.events );
|
1387
1049
|
|
1388
|
-
// Extend tapping behaviour to target
|
1389
|
-
if ( behaviour.extend ) {
|
1390
1050
|
|
1391
|
-
|
1051
|
+
// Methods
|
1392
1052
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1053
|
+
// Set the slider value.
|
1054
|
+
/** @expose */
|
1055
|
+
target.vSet = function ( ) {
|
1056
|
+
|
1057
|
+
var args = Array.prototype.slice.call( arguments, 0 ),
|
1058
|
+
callback, link, update, animate,
|
1059
|
+
i, count, actual, to, values = asArray( args[0] );
|
1060
|
+
|
1061
|
+
// Extract modifiers for value method.
|
1062
|
+
if ( typeof args[1] === 'object' ) {
|
1063
|
+
callback = args[1]['set'];
|
1064
|
+
link = args[1]['link'];
|
1065
|
+
update = args[1]['update'];
|
1066
|
+
animate = args[1]['animate'];
|
1067
|
+
|
1068
|
+
// Support the 'true' option.
|
1069
|
+
} else if ( args[1] === true ) {
|
1070
|
+
callback = true;
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
// The RTL settings is implemented by reversing the front-end,
|
1074
|
+
// internal mechanisms are the same.
|
1075
|
+
if ( options.dir && options.handles > 1 ) {
|
1076
|
+
values.reverse();
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
// Animation is optional.
|
1080
|
+
if ( animate ) {
|
1081
|
+
addClassFor( $Target, Classes[14], 300 );
|
1082
|
+
}
|
1083
|
+
|
1084
|
+
// Determine how often to set the handles.
|
1085
|
+
count = $Handles.length > 1 ? 3 : 1;
|
1086
|
+
if ( values.length === 1 ) {
|
1087
|
+
count = 1;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
// If there are multiple handles to be set run the setting
|
1091
|
+
// mechanism twice for the first handle, to make sure it
|
1092
|
+
// can be bounced of the second one properly.
|
1093
|
+
for ( i = 0; i < count; i++ ) {
|
1094
|
+
|
1095
|
+
to = link || $Serialization[i%2][0];
|
1096
|
+
to = to.getValue( values[i%2] );
|
1097
|
+
|
1098
|
+
if ( to === false ) {
|
1099
|
+
continue;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
// Calculate the new handle position
|
1103
|
+
to = toStepping( options, to );
|
1104
|
+
|
1105
|
+
// Invert the value if this is a right-to-left slider.
|
1106
|
+
if ( options.dir ) {
|
1107
|
+
to = 100 - to;
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
// Force delimitation.
|
1111
|
+
if ( setHandle( $Handles[i%2], to, true ) === true ) {
|
1112
|
+
continue;
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
// Reset the input if it doesn't match the slider.
|
1116
|
+
$($Serialization[i%2]).each(function(index){
|
1117
|
+
|
1118
|
+
if (!index) {
|
1119
|
+
actual = this.actual;
|
1120
|
+
return true;
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
this.write(
|
1124
|
+
actual,
|
1125
|
+
$Handles[i%2].children(),
|
1126
|
+
$Target,
|
1127
|
+
update
|
1128
|
+
);
|
1129
|
+
});
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
// Optionally fire the 'set' event.
|
1133
|
+
if( callback === true ) {
|
1134
|
+
fireEvents(['set']);
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
return this;
|
1138
|
+
};
|
1139
|
+
|
1140
|
+
// Get the slider value.
|
1141
|
+
/** @expose */
|
1142
|
+
target.vGet = function ( ) {
|
1143
|
+
|
1144
|
+
var i, retour = [];
|
1145
|
+
|
1146
|
+
// Get the value from all handles.
|
1147
|
+
for ( i = 0; i < options.handles; i++ ){
|
1148
|
+
retour[i] = $Serialization[i][0].saved;
|
1149
|
+
}
|
1150
|
+
|
1151
|
+
// If only one handle is used, return a single value.
|
1152
|
+
if ( retour.length === 1 ){
|
1153
|
+
return retour[0];
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
if ( options.dir ) {
|
1157
|
+
return retour.reverse();
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
return retour;
|
1161
|
+
};
|
1162
|
+
|
1163
|
+
// Destroy the slider and unbind all events.
|
1164
|
+
/** @expose */
|
1165
|
+
target.destroy = function ( ) {
|
1166
|
+
|
1167
|
+
// Loop all linked serialization objects and unbind all
|
1168
|
+
// events in the noUiSlider namespace.
|
1169
|
+
$.each($Serialization, function(){
|
1170
|
+
$.each(this, function(){
|
1171
|
+
// Won't remove 'change' when bound implicitly.
|
1172
|
+
if ( this.target ) {
|
1173
|
+
this.target.off( namespace );
|
1174
|
+
}
|
1175
|
+
});
|
1176
|
+
});
|
1177
|
+
|
1178
|
+
// Unbind events on the slider, remove all classes and child elements.
|
1179
|
+
$(this).off(namespace)
|
1180
|
+
.removeClass(Classes.join(' '))
|
1181
|
+
.empty();
|
1182
|
+
|
1183
|
+
// Return the original options from the closure.
|
1184
|
+
return originalOptions;
|
1185
|
+
};
|
1399
1186
|
|
1400
|
-
// Make the range dragable.
|
1401
|
-
if ( behaviour.drag ){
|
1402
1187
|
|
1403
|
-
|
1188
|
+
// Value setting
|
1404
1189
|
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
// but it needs to be bound manually on the other.
|
1409
|
-
if ( behaviour.fixed ) {
|
1410
|
-
drag = drag.add($Base.children().not( drag ).children());
|
1411
|
-
}
|
1190
|
+
// Use the public value method to set the start values.
|
1191
|
+
$Target.val( options.start );
|
1192
|
+
}
|
1412
1193
|
|
1413
|
-
attach ( actions.start, drag, start, {
|
1414
|
-
handles: $Handles
|
1415
|
-
});
|
1416
|
-
}
|
1417
|
-
}
|
1418
1194
|
|
1195
|
+
// Access points
|
1419
1196
|
|
1420
|
-
//
|
1197
|
+
// Run the standard initializer
|
1198
|
+
function initialize ( originalOptions ) {
|
1421
1199
|
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1200
|
+
// Throw error if group is empty.
|
1201
|
+
if ( !this.length ){
|
1202
|
+
throw new Error("noUiSlider: Can't initialize slider on empty selection.");
|
1203
|
+
}
|
1426
1204
|
|
1427
|
-
|
1428
|
-
|
1429
|
-
$Base = addSlider( options, $Target );
|
1430
|
-
$Handles = addHandles( options, $Base );
|
1431
|
-
$Serialization = addLinks( options, $Handles );
|
1205
|
+
// Test the options once, not for every slider.
|
1206
|
+
var options = test( originalOptions, this );
|
1432
1207
|
|
1433
|
-
|
1434
|
-
|
1208
|
+
// Loop all items, and provide a new closed-scope environment.
|
1209
|
+
return this.each(function(){
|
1210
|
+
closure(this, options, originalOptions);
|
1211
|
+
});
|
1212
|
+
}
|
1435
1213
|
|
1436
|
-
|
1437
|
-
|
1214
|
+
// Destroy the slider, then re-enter initialization.
|
1215
|
+
function rebuild ( options ) {
|
1438
1216
|
|
1217
|
+
return this.each(function(){
|
1439
1218
|
|
1440
|
-
//
|
1219
|
+
// Get the current values from the slider,
|
1220
|
+
// including the initialization options.
|
1221
|
+
var values = $(this).val(),
|
1222
|
+
originalOptions = this.destroy(),
|
1441
1223
|
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
var i, to;
|
1446
|
-
|
1447
|
-
// The RTL settings is implemented by reversing the front-end,
|
1448
|
-
// internal mechanisms are the same.
|
1449
|
-
if ( options.dir && options.handles > 1 ) {
|
1450
|
-
values.reverse();
|
1451
|
-
}
|
1452
|
-
|
1453
|
-
// Animation is optional.
|
1454
|
-
if ( animate ) {
|
1455
|
-
addClassFor( $Target, Classes[14], 300 );
|
1456
|
-
}
|
1457
|
-
|
1458
|
-
// If there are multiple handles to be set run the setting
|
1459
|
-
// mechanism twice for the first handle, to make sure it
|
1460
|
-
// can be bounced of the second one properly.
|
1461
|
-
for ( i = 0; i < ( $Handles.length > 1 ? 3 : 1 ); i++ ) {
|
1462
|
-
|
1463
|
-
to = link || $Serialization[i%2][0];
|
1464
|
-
to = to.valueOf( values[i%2] );
|
1465
|
-
|
1466
|
-
if ( to === false ) {
|
1467
|
-
continue;
|
1468
|
-
}
|
1469
|
-
|
1470
|
-
// Calculate the new handle position
|
1471
|
-
to = toStepping( options, to );
|
1472
|
-
|
1473
|
-
// Invert the value if this is a right-to-left slider.
|
1474
|
-
if ( options.dir ) {
|
1475
|
-
to = 100 - to;
|
1476
|
-
}
|
1477
|
-
|
1478
|
-
// Force delimitation.
|
1479
|
-
if ( setHandle( $Handles[i%2], to, true ) === true ) {
|
1480
|
-
continue;
|
1481
|
-
}
|
1482
|
-
|
1483
|
-
// Reset the input if it doesn't match the slider.
|
1484
|
-
$($Serialization[i%2]).each(function(){
|
1485
|
-
this.write(
|
1486
|
-
options,
|
1487
|
-
$Locations[i%2],
|
1488
|
-
$Handles[i%2].children(),
|
1489
|
-
$Target,
|
1490
|
-
update
|
1491
|
-
);
|
1492
|
-
});
|
1493
|
-
}
|
1494
|
-
|
1495
|
-
// Optionally fire the 'set' event.
|
1496
|
-
if( callback === true ) {
|
1497
|
-
fireEvents(['set']);
|
1498
|
-
}
|
1499
|
-
|
1500
|
-
return this;
|
1501
|
-
};
|
1502
|
-
|
1503
|
-
// Get the slider value.
|
1504
|
-
target.vGet = function ( ){
|
1505
|
-
|
1506
|
-
var i, retour = [];
|
1507
|
-
|
1508
|
-
// Get the value from all handles.
|
1509
|
-
for ( i = 0; i < options.handles; i++ ){
|
1510
|
-
retour[i] = $Serialization[i][0].saved;
|
1511
|
-
}
|
1512
|
-
|
1513
|
-
// If only one handle is used, return a single value.
|
1514
|
-
if ( retour.length === 1 ){
|
1515
|
-
return retour[0];
|
1516
|
-
}
|
1517
|
-
|
1518
|
-
if ( options.dir && options.handles > 1 ) {
|
1519
|
-
return retour.reverse();
|
1520
|
-
}
|
1521
|
-
|
1522
|
-
return retour;
|
1523
|
-
};
|
1524
|
-
|
1525
|
-
// Destroy the slider and unbind all events.
|
1526
|
-
target.destroy = function ( ){
|
1527
|
-
|
1528
|
-
// Loop all linked serialization objects and unbind all
|
1529
|
-
// events in the noUiSlider namespace.
|
1530
|
-
$.each($Serialization, function(){
|
1531
|
-
$.each(this, function(){
|
1532
|
-
// Won't remove 'change' when bound implicitly.
|
1533
|
-
if ( this.target ) {
|
1534
|
-
this.target.off( namespace );
|
1535
|
-
}
|
1536
|
-
});
|
1537
|
-
});
|
1538
|
-
|
1539
|
-
// Unbind events on the slider, remove all classes and child elements.
|
1540
|
-
$(this).off(namespace)
|
1541
|
-
.removeClass(Classes.join(' '))
|
1542
|
-
.empty();
|
1543
|
-
|
1544
|
-
// Return the original options from the closure.
|
1545
|
-
return originalOptions;
|
1546
|
-
};
|
1224
|
+
// Extend the previous options with the newly provided ones.
|
1225
|
+
newOptions = $.extend( {}, originalOptions, options );
|
1547
1226
|
|
1227
|
+
// Run the standard initializer.
|
1228
|
+
$(this).noUiSlider( newOptions );
|
1548
1229
|
|
1549
|
-
//
|
1230
|
+
// If the start option hasn't changed,
|
1231
|
+
// reset the previous values.
|
1232
|
+
if ( originalOptions.start === newOptions.start ) {
|
1233
|
+
$(this).val(values);
|
1234
|
+
}
|
1235
|
+
});
|
1236
|
+
}
|
1550
1237
|
|
1551
|
-
// Use the public value method to set the start values.
|
1552
|
-
$Target.val( options.start );
|
1553
|
-
}
|
1554
1238
|
|
1239
|
+
// Remap the serialization constructor for legacy support.
|
1240
|
+
/** @expose */
|
1241
|
+
$.noUiSlider = { 'Link': $.Link };
|
1555
1242
|
|
1556
|
-
//
|
1243
|
+
// Extend jQuery/Zepto with the noUiSlider method.
|
1244
|
+
/** @expose */
|
1245
|
+
$.fn.noUiSlider = function ( options, re ) {
|
1246
|
+
return ( re ? rebuild : initialize ).call(this, options);
|
1247
|
+
};
|
1557
1248
|
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
// Throw error if group is empty.
|
1562
|
-
if ( !this.length ){
|
1563
|
-
throwError("Can't initialize slider on empty selection.");
|
1564
|
-
}
|
1565
|
-
|
1566
|
-
// Test the options once, not for every slider.
|
1567
|
-
var options = test( originalOptions, this );
|
1568
|
-
|
1569
|
-
// Loop all items, and provide a new closed-scope environment.
|
1570
|
-
return this.each(function(){
|
1571
|
-
closure(this, options, originalOptions);
|
1572
|
-
});
|
1573
|
-
}
|
1574
|
-
|
1575
|
-
// Destroy the slider, then re-enter initialization.
|
1576
|
-
function rebuild ( options ) {
|
1577
|
-
|
1578
|
-
return this.each(function(){
|
1579
|
-
|
1580
|
-
// Get the current values from the slider,
|
1581
|
-
// including the initialization options.
|
1582
|
-
var values = $(this).val(),
|
1583
|
-
originalOptions = this.destroy(),
|
1584
|
-
|
1585
|
-
// Extend the previous options with the newly provided ones.
|
1586
|
-
newOptions = $.extend( {}, originalOptions, options );
|
1587
|
-
|
1588
|
-
// Run the standard initializer.
|
1589
|
-
$(this).noUiSlider( newOptions );
|
1590
|
-
|
1591
|
-
// If the start option hasn't changed,
|
1592
|
-
// reset the previous values.
|
1593
|
-
if ( originalOptions.start === newOptions.start ) {
|
1594
|
-
$(this).val(values);
|
1595
|
-
}
|
1596
|
-
});
|
1597
|
-
}
|
1598
|
-
|
1599
|
-
|
1600
|
-
// Expose serialization constructor.
|
1601
|
-
/** @expose */
|
1602
|
-
$.noUiSlider = { 'Link': Link };
|
1603
|
-
|
1604
|
-
// Extend jQuery/Zepto with the noUiSlider method.
|
1605
|
-
/** @expose */
|
1606
|
-
$.fn.noUiSlider = function ( options, re ) {
|
1607
|
-
return ( re ? rebuild : initialize ).call(this, options);
|
1608
|
-
};
|
1609
|
-
|
1610
|
-
$.fn.val = function ( ) {
|
1611
|
-
|
1612
|
-
// Convert the function arguments to an array.
|
1613
|
-
var args = Array.prototype.slice.call( arguments, 0 ),
|
1614
|
-
set, link, update, animate;
|
1615
|
-
|
1616
|
-
// Test if there are arguments, and if not, call the 'get' method.
|
1617
|
-
if ( !args.length ) {
|
1618
|
-
|
1619
|
-
// Determine whether to use the native val method.
|
1620
|
-
if ( this.hasClass(Classes[0]) ) {
|
1621
|
-
return this[0].vGet();
|
1622
|
-
}
|
1623
|
-
|
1624
|
-
return $val.apply( this );
|
1625
|
-
}
|
1626
|
-
|
1627
|
-
// Extract modifiers for value method.
|
1628
|
-
if ( typeof args[1] === 'object' ) {
|
1629
|
-
set = args[1]['set'];
|
1630
|
-
link = args[1]['link'];
|
1631
|
-
update = args[1]['update'];
|
1632
|
-
animate = args[1]['animate'];
|
1633
|
-
|
1634
|
-
// Support the 'true' option.
|
1635
|
-
} else if ( args[1] === true ) {
|
1636
|
-
set = true;
|
1637
|
-
}
|
1638
|
-
|
1639
|
-
// Loop all individual items, and handle setting appropriately.
|
1640
|
-
return this.each(function(){
|
1641
|
-
|
1642
|
-
if ( $(this).hasClass(Classes[0]) ) {
|
1643
|
-
this.vSet( asArray(args[0]), set, link, update, animate );
|
1644
|
-
} else {
|
1645
|
-
$val.apply( $(this), args );
|
1646
|
-
}
|
1647
|
-
});
|
1648
|
-
};
|
1249
|
+
// Attach a classbased val handler.
|
1250
|
+
$.classVal(Classes[0], 'vGet', 'vSet', false);
|
1649
1251
|
|
1650
1252
|
}( window['jQuery'] || window['Zepto'] ));
|