Skip to content

Commit b725812

Browse files
authored
feat(range): Add a pushRange option (#341)
As described in #311
1 parent 6d479af commit b725812

File tree

11 files changed

+292
-67
lines changed

11 files changed

+292
-67
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 5.1.0 (2016-07-02)
2+
## Features
3+
- Add a `pushRange` option (#341).
4+
15
# 5.0.1 (2016-07-01)
26
## Fix
37
- Switch from using opacity to visibility to show/hide elements (#362).

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ The default options are:
190190
maxLimit: null,
191191
minRange: null,
192192
maxRange: null,
193+
pushRange: false,
193194
id: null,
194195
translate: null,
195196
getLegend: null,
@@ -243,6 +244,8 @@ The default options are:
243244

244245
**maxRange** - _Number (defaults to null)_: The maximum range authorized on the slider. *Applies to range slider only.*
245246

247+
**pushRange** - _Boolean (defaults to false)_: Set to true to have a push behavior. When the min handle goes above the max, the max is moved as well (and vice-versa). The range between min and max is defined by the `step` option (defaults to 1) and can also be override by the `minRange` option. *Applies to range slider only.*
248+
246249
**translate** - _Function(value, sliderId, label)_: Custom translate function. Use this if you want to translate values displayed on the slider.
247250
`sliderId` can be used to determine the slider for which we are translating the value. `label` is a string that can take the following values:
248251
- *'model'*: the model label

demo/demo.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) {
5454
}
5555
};
5656

57+
//Range slider with minRange and pushRange config
58+
$scope.minPushRangeSlider = {
59+
minValue: 40,
60+
maxValue: 60,
61+
options: {
62+
floor: 0,
63+
ceil: 100,
64+
minRange: 10,
65+
pushRange: true
66+
}
67+
};
68+
5769
//Slider with selection bar
5870
$scope.slider_visible_bar = {
5971
value: 10,

demo/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ <h2>Range slider with noSwitching=true</h2>
6262
></rzslider>
6363
</article>
6464

65+
<article>
66+
<h2>Range slider with minimum range of 10 and pushRange option</h2>
67+
<rzslider
68+
rz-slider-model="minPushRangeSlider.minValue"
69+
rz-slider-high="minPushRangeSlider.maxValue"
70+
rz-slider-options="minPushRangeSlider.options"
71+
></rzslider>
72+
</article>
73+
6574
<article>
6675
<h2>Slider with visible selection bar</h2>
6776
<rzslider

dist/rzslider.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*! angularjs-slider - v5.0.1 -
22
(c) Rafal Zajac <[email protected]>, Valentin Hervieu <[email protected]>, Jussi Saarivirta <[email protected]>, Angelin Sirbu <[email protected]> -
33
https://github.com/angular-slider/angularjs-slider -
4-
2016-07-01 */
4+
2016-07-02 */
55
.rzslider {
66
position: relative;
77
display: inline-block;

dist/rzslider.js

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*! angularjs-slider - v5.0.1 -
22
(c) Rafal Zajac <[email protected]>, Valentin Hervieu <[email protected]>, Jussi Saarivirta <[email protected]>, Angelin Sirbu <[email protected]> -
33
https://github.com/angular-slider/angularjs-slider -
4-
2016-07-01 */
4+
2016-07-02 */
55
/*jslint unparam: true */
66
/*global angular: false, console: false, define, module */
77
(function(root, factory) {
@@ -33,6 +33,7 @@
3333
precision: 0,
3434
minRange: null,
3535
maxRange: null,
36+
pushRange: false,
3637
minLimit: null,
3738
maxLimit: null,
3839
id: null,
@@ -1906,40 +1907,47 @@
19061907

19071908
newValue = this.applyMinMaxLimit(newValue);
19081909
if (this.range) {
1909-
newValue = this.applyMinMaxRange(newValue);
1910-
/* This is to check if we need to switch the min and max handles */
1911-
if (this.tracking === 'lowValue' && newValue > this.highValue) {
1912-
if (this.options.noSwitching && this.highValue !== this.minValue) {
1913-
newValue = this.applyMinMaxRange(this.highValue);
1914-
}
1915-
else {
1916-
this.lowValue = this.highValue;
1917-
this.applyLowValue();
1918-
this.updateHandles(this.tracking, this.maxH.rzsp);
1919-
this.updateAriaAttributes();
1920-
this.tracking = 'highValue';
1921-
this.minH.removeClass('rz-active');
1922-
this.maxH.addClass('rz-active');
1923-
if (this.options.keyboardSupport)
1924-
this.focusElement(this.maxH);
1925-
}
1910+
if (this.options.pushRange) {
1911+
newValue = this.applyPushRange(newValue);
19261912
valueChanged = true;
1927-
} else if (this.tracking === 'highValue' && newValue < this.lowValue) {
1928-
if (this.options.noSwitching && this.lowValue !== this.maxValue) {
1929-
newValue = this.applyMinMaxRange(this.lowValue);
1913+
}
1914+
else {
1915+
newValue = this.applyMinMaxRange(newValue);
1916+
/* This is to check if we need to switch the min and max handles */
1917+
if (this.tracking === 'lowValue' && newValue > this.highValue) {
1918+
if (this.options.noSwitching && this.highValue !== this.minValue) {
1919+
newValue = this.applyMinMaxRange(this.highValue);
1920+
}
1921+
else {
1922+
this.lowValue = this.highValue;
1923+
this.applyLowValue();
1924+
this.updateHandles(this.tracking, this.maxH.rzsp);
1925+
this.updateAriaAttributes();
1926+
this.tracking = 'highValue';
1927+
this.minH.removeClass('rz-active');
1928+
this.maxH.addClass('rz-active');
1929+
if (this.options.keyboardSupport)
1930+
this.focusElement(this.maxH);
1931+
}
1932+
valueChanged = true;
19301933
}
1931-
else {
1932-
this.highValue = this.lowValue;
1933-
this.applyHighValue();
1934-
this.updateHandles(this.tracking, this.minH.rzsp);
1935-
this.updateAriaAttributes();
1936-
this.tracking = 'lowValue';
1937-
this.maxH.removeClass('rz-active');
1938-
this.minH.addClass('rz-active');
1939-
if (this.options.keyboardSupport)
1940-
this.focusElement(this.minH);
1934+
else if (this.tracking === 'highValue' && newValue < this.lowValue) {
1935+
if (this.options.noSwitching && this.lowValue !== this.maxValue) {
1936+
newValue = this.applyMinMaxRange(this.lowValue);
1937+
}
1938+
else {
1939+
this.highValue = this.lowValue;
1940+
this.applyHighValue();
1941+
this.updateHandles(this.tracking, this.minH.rzsp);
1942+
this.updateAriaAttributes();
1943+
this.tracking = 'lowValue';
1944+
this.maxH.removeClass('rz-active');
1945+
this.minH.addClass('rz-active');
1946+
if (this.options.keyboardSupport)
1947+
this.focusElement(this.minH);
1948+
}
1949+
valueChanged = true;
19411950
}
1942-
valueChanged = true;
19431951
}
19441952
}
19451953

@@ -1988,6 +1996,27 @@
19881996
return newValue;
19891997
},
19901998

1999+
applyPushRange: function(newValue) {
2000+
var difference = this.tracking === 'lowValue' ? this.highValue - newValue : newValue - this.lowValue,
2001+
range = this.options.minRange !== null ? this.options.minRange : this.options.step;
2002+
if (difference < range) {
2003+
if (this.tracking === 'lowValue') {
2004+
this.highValue = Math.min(newValue + range, this.maxValue);
2005+
newValue = this.highValue - range;
2006+
this.applyHighValue();
2007+
this.updateHandles('highValue', this.valueToOffset(this.highValue));
2008+
}
2009+
else {
2010+
this.lowValue = Math.max(newValue - range, this.minValue);
2011+
newValue = this.lowValue + range;
2012+
this.applyLowValue();
2013+
this.updateHandles('lowValue', this.valueToOffset(this.lowValue));
2014+
}
2015+
this.updateAriaAttributes();
2016+
}
2017+
return newValue;
2018+
},
2019+
19912020
/**
19922021
* Apply the model values using scope.$apply.
19932022
* We wrap it with the internalChange flag to avoid the watchers to be called

dist/rzslider.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.

dist/rzslider.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.

src/rzslider.js

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
precision: 0,
3838
minRange: null,
3939
maxRange: null,
40+
pushRange: false,
4041
minLimit: null,
4142
maxLimit: null,
4243
id: null,
@@ -1910,40 +1911,47 @@
19101911

19111912
newValue = this.applyMinMaxLimit(newValue);
19121913
if (this.range) {
1913-
newValue = this.applyMinMaxRange(newValue);
1914-
/* This is to check if we need to switch the min and max handles */
1915-
if (this.tracking === 'lowValue' && newValue > this.highValue) {
1916-
if (this.options.noSwitching && this.highValue !== this.minValue) {
1917-
newValue = this.applyMinMaxRange(this.highValue);
1918-
}
1919-
else {
1920-
this.lowValue = this.highValue;
1921-
this.applyLowValue();
1922-
this.updateHandles(this.tracking, this.maxH.rzsp);
1923-
this.updateAriaAttributes();
1924-
this.tracking = 'highValue';
1925-
this.minH.removeClass('rz-active');
1926-
this.maxH.addClass('rz-active');
1927-
if (this.options.keyboardSupport)
1928-
this.focusElement(this.maxH);
1929-
}
1914+
if (this.options.pushRange) {
1915+
newValue = this.applyPushRange(newValue);
19301916
valueChanged = true;
1931-
} else if (this.tracking === 'highValue' && newValue < this.lowValue) {
1932-
if (this.options.noSwitching && this.lowValue !== this.maxValue) {
1933-
newValue = this.applyMinMaxRange(this.lowValue);
1917+
}
1918+
else {
1919+
newValue = this.applyMinMaxRange(newValue);
1920+
/* This is to check if we need to switch the min and max handles */
1921+
if (this.tracking === 'lowValue' && newValue > this.highValue) {
1922+
if (this.options.noSwitching && this.highValue !== this.minValue) {
1923+
newValue = this.applyMinMaxRange(this.highValue);
1924+
}
1925+
else {
1926+
this.lowValue = this.highValue;
1927+
this.applyLowValue();
1928+
this.updateHandles(this.tracking, this.maxH.rzsp);
1929+
this.updateAriaAttributes();
1930+
this.tracking = 'highValue';
1931+
this.minH.removeClass('rz-active');
1932+
this.maxH.addClass('rz-active');
1933+
if (this.options.keyboardSupport)
1934+
this.focusElement(this.maxH);
1935+
}
1936+
valueChanged = true;
19341937
}
1935-
else {
1936-
this.highValue = this.lowValue;
1937-
this.applyHighValue();
1938-
this.updateHandles(this.tracking, this.minH.rzsp);
1939-
this.updateAriaAttributes();
1940-
this.tracking = 'lowValue';
1941-
this.maxH.removeClass('rz-active');
1942-
this.minH.addClass('rz-active');
1943-
if (this.options.keyboardSupport)
1944-
this.focusElement(this.minH);
1938+
else if (this.tracking === 'highValue' && newValue < this.lowValue) {
1939+
if (this.options.noSwitching && this.lowValue !== this.maxValue) {
1940+
newValue = this.applyMinMaxRange(this.lowValue);
1941+
}
1942+
else {
1943+
this.highValue = this.lowValue;
1944+
this.applyHighValue();
1945+
this.updateHandles(this.tracking, this.minH.rzsp);
1946+
this.updateAriaAttributes();
1947+
this.tracking = 'lowValue';
1948+
this.maxH.removeClass('rz-active');
1949+
this.minH.addClass('rz-active');
1950+
if (this.options.keyboardSupport)
1951+
this.focusElement(this.minH);
1952+
}
1953+
valueChanged = true;
19451954
}
1946-
valueChanged = true;
19471955
}
19481956
}
19491957

@@ -1992,6 +2000,27 @@
19922000
return newValue;
19932001
},
19942002

2003+
applyPushRange: function(newValue) {
2004+
var difference = this.tracking === 'lowValue' ? this.highValue - newValue : newValue - this.lowValue,
2005+
range = this.options.minRange !== null ? this.options.minRange : this.options.step;
2006+
if (difference < range) {
2007+
if (this.tracking === 'lowValue') {
2008+
this.highValue = Math.min(newValue + range, this.maxValue);
2009+
newValue = this.highValue - range;
2010+
this.applyHighValue();
2011+
this.updateHandles('highValue', this.valueToOffset(this.highValue));
2012+
}
2013+
else {
2014+
this.lowValue = Math.max(newValue - range, this.minValue);
2015+
newValue = this.lowValue + range;
2016+
this.applyLowValue();
2017+
this.updateHandles('lowValue', this.valueToOffset(this.lowValue));
2018+
}
2019+
this.updateAriaAttributes();
2020+
}
2021+
return newValue;
2022+
},
2023+
19952024
/**
19962025
* Apply the model values using scope.$apply.
19972026
* We wrap it with the internalChange flag to avoid the watchers to be called

tests/specs/helper.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@
108108
$timeout.flush();
109109
};
110110

111+
h.mouseMoveToValue = function(value) {
112+
var offset = h.slider.valueToOffset(value) + h.slider.handleHalfDim + h.slider.sliderElem.rzsp;
113+
h.fireMousemove(offset);
114+
};
115+
111116
return h;
112117
});
113118
}());

0 commit comments

Comments
 (0)