diff --git a/documentation/slider-options.php b/documentation/slider-options.php index 36b559f4..ba5efc26 100644 --- a/documentation/slider-options.php +++ b/documentation/slider-options.php @@ -82,7 +82,7 @@

The connect option can be used to control the bar between the handles or the edges of the slider.

-

If you are using one handle, set the value to either 'upper' or 'lower'. +

If you are using one handle, set the value to either 'upper' or 'lower'.

@@ -129,7 +129,7 @@
-

When using two handles, the minimum distance between the handles can be set using the margin option. The margin value is relative to the value set in 'range'. This option is only available on linear sliders.

+

When using two handles or more, the minimum distance between the handles can be set using the margin option. The margin value is relative to the value set in 'range'. This option is only available on linear sliders.

@@ -139,12 +139,21 @@
+

When using more than 2 handles, you can specify custom margin for each range.

+ +
+
+ +
+
Default
none
Accepted values -
number
+
number,
+ array[number] +
@@ -156,6 +165,9 @@
+ +
+
diff --git a/documentation/slider-options/margin-array.js b/documentation/slider-options/margin-array.js new file mode 100644 index 00000000..74da63e4 --- /dev/null +++ b/documentation/slider-options/margin-array.js @@ -0,0 +1,12 @@ +var marginSlider2 = document.getElementById('slider-margin2'); + +noUiSlider.create(marginSlider2, { + start: [10, 50, 90], + margin: [15, 30], + tooltips: true, + step: 1, + range: { + 'min': 0, + 'max': 100 + } +}); diff --git a/src/nouislider.js b/src/nouislider.js index 9bb9cf71..db76f0da 100644 --- a/src/nouislider.js +++ b/src/nouislider.js @@ -625,8 +625,27 @@ } function testMargin(parsed, entry) { + if (Array.isArray(entry)) { + testMarginArray(parsed, entry); + } else { + testMarginNumeric(parsed, entry); + } + } + + function testMarginArray(parsed, entry) { + if (!entry.length || entry.length !== parsed.handles - 1) { + throw new Error("noUiSlider (" + VERSION + "): 'margin' option doesn't match handle count."); + } + + parsed.margin = []; + for (var i = 0; i < entry.length; ++i) { + testMarginNumeric(parsed, entry[i]); + } + } + + function testMarginNumeric(parsed, entry) { if (!isNumeric(entry)) { - throw new Error("noUiSlider (" + VERSION + "): 'margin' option must be numeric."); + throw new Error("noUiSlider (" + VERSION + "): 'margin' option must be either number or array of numbers."); } // Issue #582 @@ -634,9 +653,14 @@ return; } - parsed.margin = parsed.spectrum.getMargin(entry); + var parsedMargin = parsed.spectrum.getMargin(entry); + if (Array.isArray(parsed.margin)) { + parsed.margin.push(parsedMargin); + } else { + parsed.margin = parsedMargin; + } - if (!parsed.margin) { + if (!parsedMargin) { throw new Error("noUiSlider (" + VERSION + "): 'margin' option is only supported on linear sliders."); } } @@ -1963,12 +1987,16 @@ // For sliders with multiple handles, limit movement to the other handle. // Apply the margin option by adding it to the handle positions. if (scope_Handles.length > 1 && !options.events.unconstrained) { + var margin; + if (lookBackward && handleNumber > 0) { - to = Math.max(to, reference[handleNumber - 1] + options.margin); + margin = getMargin(handleNumber, false); + to = Math.max(to, reference[handleNumber - 1] + margin); } if (lookForward && handleNumber < scope_Handles.length - 1) { - to = Math.min(to, reference[handleNumber + 1] - options.margin); + margin = getMargin(handleNumber, true); + to = Math.min(to, reference[handleNumber + 1] - margin); } } @@ -2010,6 +2038,22 @@ return to; } + function getMargin(handleNumber, lookForward) { + if (!Array.isArray(options.margin)) return options.margin; + + var i; + + if (handleNumber === 0) { + i = 0; + } else if (options.margin.length === handleNumber) { + i = handleNumber - 1; + } else { + i = lookForward ? handleNumber : handleNumber - 1; + } + + return options.margin[i]; + } + // Uses slider orientation to create CSS rules. a = base value; function inRuleOrder(v, a) { var o = options.ort;