Skip to content

Commit a5bb92a

Browse files
committed
noUiSlider 14.5.0
1 parent ad6ccad commit a5bb92a

File tree

6 files changed

+141
-36
lines changed

6 files changed

+141
-36
lines changed

CHANGELOG.MD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
### 14.5.0 (*2020-05-20*)
4+
- Added: Support for `margin`, `padding` and `limit` on non-linear sliders (#911, #1030, #1031, #1071);
5+
36
### 14.4.0 (*2020-05-06*)
47
- Added: `getOrigins` and `getTooltips` methods;
58
- Added: Default styling to support merging overlapping tooltips (#1032);

distribute/nouislider.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! nouislider - 14.4.0 - 5/6/2020 */
1+
/*! nouislider - 14.5.0 - 5/11/2020 */
22
/* Functional styling;
33
* These styles are required for noUiSlider to function.
44
* You don't need to change these rules to apply your design.

distribute/nouislider.js

Lines changed: 133 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! nouislider - 14.4.0 - 5/6/2020 */
1+
/*! nouislider - 14.5.0 - 5/11/2020 */
22
(function(factory) {
33
if (typeof define === "function" && define.amd) {
44
// AMD. Register as an anonymous module.
@@ -13,7 +13,7 @@
1313
})(function() {
1414
"use strict";
1515

16-
var VERSION = "14.4.0";
16+
var VERSION = "14.5.0";
1717

1818
//region Helper Methods
1919

@@ -206,13 +206,13 @@
206206
}
207207

208208
// (percentage) How many percent is this value of this range?
209-
function fromPercentage(range, value) {
210-
return (value * 100) / (range[1] - range[0]);
209+
function fromPercentage(range, value, startRange) {
210+
return (value * 100) / (range[startRange + 1] - range[startRange]);
211211
}
212212

213213
// (percentage) Where is this value on this range?
214214
function toPercentage(range, value) {
215-
return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0]);
215+
return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0], 0);
216216
}
217217

218218
// (value) How much is this percentage on this range?
@@ -348,7 +348,7 @@
348348

349349
// Factor to range ratio
350350
that.xSteps[i] =
351-
fromPercentage([that.xVal[i], that.xVal[i + 1]], n) / subRangeRatio(that.xPct[i], that.xPct[i + 1]);
351+
fromPercentage([that.xVal[i], that.xVal[i + 1]], n, 0) / subRangeRatio(that.xPct[i], that.xPct[i + 1]);
352352

353353
var totalSteps = (that.xVal[i + 1] - that.xVal[i]) / that.xNumSteps[i];
354354
var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1);
@@ -406,14 +406,107 @@
406406
}
407407
}
408408

409-
Spectrum.prototype.getMargin = function(value) {
410-
var step = this.xNumSteps[0];
409+
Spectrum.prototype.getDistance = function(value) {
410+
var index;
411+
var distances = [];
412+
413+
for (index = 0; index < this.xNumSteps.length - 1; index++) {
414+
// last "range" can't contain step size as it is purely an endpoint.
415+
var step = this.xNumSteps[index];
416+
417+
if (step && (value / step) % 1 !== 0) {
418+
throw new Error(
419+
"noUiSlider (" +
420+
VERSION +
421+
"): 'limit', 'margin' and 'padding' of " +
422+
this.xPct[index] +
423+
"% range must be divisible by step."
424+
);
425+
}
426+
427+
// Calculate percentual distance in current range of limit, margin or padding
428+
distances[index] = fromPercentage(this.xVal, value, index);
429+
}
430+
431+
return distances;
432+
};
433+
434+
// Calculate the percentual distance over the whole scale of ranges.
435+
// direction: 0 = backwards / 1 = forwards
436+
Spectrum.prototype.getAbsoluteDistance = function(value, distances, direction) {
437+
var xPct_index = 0;
438+
439+
// Calculate range where to start calculation
440+
if (value < this.xPct[this.xPct.length - 1]) {
441+
while (value > this.xPct[xPct_index + 1]) {
442+
xPct_index++;
443+
}
444+
} else if (value === this.xPct[this.xPct.length - 1]) {
445+
xPct_index = this.xPct.length - 2;
446+
}
447+
448+
// If looking backwards and the value is exactly at a range separator then look one range further
449+
if (!direction && value === this.xPct[xPct_index + 1]) {
450+
xPct_index++;
451+
}
452+
453+
var start_factor;
454+
var rest_factor = 1;
455+
456+
var rest_rel_distance = distances[xPct_index];
457+
458+
var range_pct = 0;
411459

412-
if (step && (value / step) % 1 !== 0) {
413-
throw new Error("noUiSlider (" + VERSION + "): 'limit', 'margin' and 'padding' must be divisible by step.");
460+
var rel_range_distance = 0;
461+
var abs_distance_counter = 0;
462+
var range_counter = 0;
463+
464+
// Calculate what part of the start range the value is
465+
if (direction) {
466+
start_factor = (value - this.xPct[xPct_index]) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]);
467+
} else {
468+
start_factor = (this.xPct[xPct_index + 1] - value) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]);
469+
}
470+
471+
// Do until the complete distance across ranges is calculated
472+
while (rest_rel_distance > 0) {
473+
// Calculate the percentage of total range
474+
range_pct = this.xPct[xPct_index + 1 + range_counter] - this.xPct[xPct_index + range_counter];
475+
476+
// Detect if the margin, padding or limit is larger then the current range and calculate
477+
if (distances[xPct_index + range_counter] * rest_factor + 100 - start_factor * 100 > 100) {
478+
// If larger then take the percentual distance of the whole range
479+
rel_range_distance = range_pct * start_factor;
480+
// Rest factor of relative percentual distance still to be calculated
481+
rest_factor = (rest_rel_distance - 100 * start_factor) / distances[xPct_index + range_counter];
482+
// Set start factor to 1 as for next range it does not apply.
483+
start_factor = 1;
484+
} else {
485+
// If smaller or equal then take the percentual distance of the calculate percentual part of that range
486+
rel_range_distance = ((distances[xPct_index + range_counter] * range_pct) / 100) * rest_factor;
487+
// No rest left as the rest fits in current range
488+
rest_factor = 0;
489+
}
490+
491+
if (direction) {
492+
abs_distance_counter = abs_distance_counter - rel_range_distance;
493+
// Limit range to first range when distance becomes outside of minimum range
494+
if (this.xPct.length + range_counter >= 1) {
495+
range_counter--;
496+
}
497+
} else {
498+
abs_distance_counter = abs_distance_counter + rel_range_distance;
499+
// Limit range to last range when distance becomes outside of maximum range
500+
if (this.xPct.length - range_counter >= 1) {
501+
range_counter++;
502+
}
503+
}
504+
505+
// Rest of relative percentual distance still to be calculated
506+
rest_rel_distance = distances[xPct_index + range_counter] * rest_factor;
414507
}
415508

416-
return this.xPct.length === 2 ? fromPercentage(this.xVal, value) : false;
509+
return value + abs_distance_counter;
417510
};
418511

419512
Spectrum.prototype.toStepping = function(value) {
@@ -678,19 +771,15 @@
678771
return;
679772
}
680773

681-
parsed.margin = parsed.spectrum.getMargin(entry);
682-
683-
if (!parsed.margin) {
684-
throw new Error("noUiSlider (" + VERSION + "): 'margin' option is only supported on linear sliders.");
685-
}
774+
parsed.margin = parsed.spectrum.getDistance(entry);
686775
}
687776

688777
function testLimit(parsed, entry) {
689778
if (!isNumeric(entry)) {
690779
throw new Error("noUiSlider (" + VERSION + "): 'limit' option must be numeric.");
691780
}
692781

693-
parsed.limit = parsed.spectrum.getMargin(entry);
782+
parsed.limit = parsed.spectrum.getDistance(entry);
694783

695784
if (!parsed.limit || parsed.handles < 2) {
696785
throw new Error(
@@ -702,6 +791,8 @@
702791
}
703792

704793
function testPadding(parsed, entry) {
794+
var index;
795+
705796
if (!isNumeric(entry) && !Array.isArray(entry)) {
706797
throw new Error(
707798
"noUiSlider (" + VERSION + "): 'padding' option must be numeric or array of exactly 2 numbers."
@@ -722,18 +813,21 @@
722813
entry = [entry, entry];
723814
}
724815

725-
// 'getMargin' returns false for invalid values.
726-
parsed.padding = [parsed.spectrum.getMargin(entry[0]), parsed.spectrum.getMargin(entry[1])];
816+
// 'getDistance' returns false for invalid values.
817+
parsed.padding = [parsed.spectrum.getDistance(entry[0]), parsed.spectrum.getDistance(entry[1])];
727818

728-
if (parsed.padding[0] === false || parsed.padding[1] === false) {
729-
throw new Error("noUiSlider (" + VERSION + "): 'padding' option is only supported on linear sliders.");
819+
for (index = 0; index < parsed.spectrum.xNumSteps.length - 1; index++) {
820+
// last "range" can't contain step size as it is purely an endpoint.
821+
if (parsed.padding[0][index] < 0 || parsed.padding[1][index] < 0) {
822+
throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number(s).");
823+
}
730824
}
731825

732-
if (parsed.padding[0] < 0 || parsed.padding[1] < 0) {
733-
throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number(s).");
734-
}
826+
var totalPadding = entry[0] + entry[1];
827+
var firstValue = parsed.spectrum.xVal[0];
828+
var lastValue = parsed.spectrum.xVal[parsed.spectrum.xVal.length - 1];
735829

736-
if (parsed.padding[0] + parsed.padding[1] > 100) {
830+
if (totalPadding / (lastValue - firstValue) > 1) {
737831
throw new Error("noUiSlider (" + VERSION + "): 'padding' option must not exceed 100% of the range.");
738832
}
739833
}
@@ -2008,15 +2102,19 @@
20082102

20092103
// Split out the handle positioning logic so the Move event can use it, too
20102104
function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue) {
2105+
var distance;
2106+
20112107
// For sliders with multiple handles, limit movement to the other handle.
20122108
// Apply the margin option by adding it to the handle positions.
20132109
if (scope_Handles.length > 1 && !options.events.unconstrained) {
20142110
if (lookBackward && handleNumber > 0) {
2015-
to = Math.max(to, reference[handleNumber - 1] + options.margin);
2111+
distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.margin, 0);
2112+
to = Math.max(to, distance);
20162113
}
20172114

20182115
if (lookForward && handleNumber < scope_Handles.length - 1) {
2019-
to = Math.min(to, reference[handleNumber + 1] - options.margin);
2116+
distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.margin, 1);
2117+
to = Math.min(to, distance);
20202118
}
20212119
}
20222120

@@ -2025,23 +2123,27 @@
20252123
// handles would be unmovable.
20262124
if (scope_Handles.length > 1 && options.limit) {
20272125
if (lookBackward && handleNumber > 0) {
2028-
to = Math.min(to, reference[handleNumber - 1] + options.limit);
2126+
distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.limit, 0);
2127+
to = Math.min(to, distance);
20292128
}
20302129

20312130
if (lookForward && handleNumber < scope_Handles.length - 1) {
2032-
to = Math.max(to, reference[handleNumber + 1] - options.limit);
2131+
distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.limit, 1);
2132+
to = Math.max(to, distance);
20332133
}
20342134
}
20352135

20362136
// The padding option keeps the handles a certain distance from the
20372137
// edges of the slider. Padding must be > 0.
20382138
if (options.padding) {
20392139
if (handleNumber === 0) {
2040-
to = Math.max(to, options.padding[0]);
2140+
distance = scope_Spectrum.getAbsoluteDistance(0, options.padding[0], 0);
2141+
to = Math.max(to, distance);
20412142
}
20422143

20432144
if (handleNumber === scope_Handles.length - 1) {
2044-
to = Math.min(to, 100 - options.padding[1]);
2145+
distance = scope_Spectrum.getAbsoluteDistance(100, options.padding[1], 1);
2146+
to = Math.min(to, distance);
20452147
}
20462148
}
20472149

distribute/nouislider.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

distribute/nouislider.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nouislider",
3-
"version": "14.4.0",
3+
"version": "14.5.0",
44
"main": "distribute/nouislider.js",
55
"style": "distribute/nouislider.min.css",
66
"license": "MIT",

0 commit comments

Comments
 (0)