Skip to content

Commit e256412

Browse files
mehmetxbozkurtmehmet.bozkurtValentinH
authored
Multiple restrictedRange feature and the feature that to skip restrictedRanges with arrow keys added. (#681)
Co-authored-by: mehmet.bozkurt <[email protected]> Co-authored-by: Valentin Hervieu <[email protected]>
1 parent c03e361 commit e256412

12 files changed

+344
-89
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ temp/
55
tests/coverage/
66
yarn.lock
77
cypress/videos
8-
npm-debug.log
8+
npm-debug.log
9+
.history/

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ The default options are:
244244
minLimit: null,
245245
maxLimit: null,
246246
restrictedRange: null,
247+
skipRestrictedRangesWithArrowKeys: null,
247248
minRange: null,
248249
maxRange: null,
249250
pushRange: false,
@@ -312,7 +313,9 @@ The default options are:
312313

313314
**maxLimit** - _Number (defaults to null)_: The maximum value authorized on the slider.
314315

315-
**restrictedRange** - _Object (defaults to null)_: Has two _Number_ properties, _from_ and _to_ that determine the bounds of an area that is not authorized for values. _Applies to range slider only._
316+
**restrictedRange** - _Object (defaults to null)_: Has two _Number_ properties, _from_ and _to_ that determine the bounds of an area that is not authorized for values. Can also use an array. _Applies to range slider only._
317+
318+
**skipRestrictedRangesWithArrowKeys** - _Boolean (defaults to null)_: Set to true to skip restricted ranges with arrow keys.
316319

317320
**minRange** - _Number (defaults to null)_: The minimum range authorized on the slider. _Applies to range slider only._
318321

demo/demo.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $uibModal) {
6565
},
6666
}
6767

68+
// Restricted range with multiple array and the feature skipRestrictedRangesWithArrowKeys
69+
$scope.multipleRestrictedRangeSlider = {
70+
minValue: 10,
71+
maxValue: 90,
72+
options: {
73+
restrictedRange: [
74+
{ from: 20, to: 30 },
75+
{ from: 50, to: 60 },
76+
{ from: 75, to: 85 },
77+
],
78+
skipRestrictedRangesWithArrowKeys: true,
79+
floor: 0,
80+
ceil: 100,
81+
step: 1,
82+
},
83+
}
84+
6885
//Range slider with minRange and maxRange config
6986
$scope.minMaxRangeSlider = {
7087
minValue: 40,

demo/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ <h2>Range slider with restricted area from 30 to 70</h2>
6363
></rzslider>
6464
</article>
6565

66+
<article>
67+
<h2>Range slider with multiple restricted area from 20 to 30, 50 to 60 and 75 to 85
68+
<br />
69+
and the feature that skip restricted ranges with arrow keys
70+
</h2>
71+
<rzslider
72+
rz-slider-model="multipleRestrictedRangeSlider.minValue"
73+
rz-slider-high="multipleRestrictedRangeSlider.maxValue"
74+
rz-slider-options="multipleRestrictedRangeSlider.options"
75+
></rzslider>
76+
</article>
77+
6678
<article>
6779
<h2>Range slider with minimum range of 10 and maximum of 50</h2>
6880
<rzslider

dist/rzslider.css

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

dist/rzslider.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ declare module "angular" {
2929
* Object(defaults to null): Has two _Number_ properties, _from_ and _to_ that determine
3030
* the bounds of an area that is not authorized for values. _Applies to range slider only._
3131
*/
32-
restrictedRange?: { from: number, to: number }
33-
/** Number (defaults to null): The minimum range authorized on the slider. Applies to range slider only. */
32+
restrictedRange?: { from: number, to: number } | Array<{from: number, to: number}>;
33+
/** Number (defaults to null): The minimum range authorized on the slider. Applies to range slider only. Can also use an array.*/
34+
skipRestrictedRangesWithArrowKeys?: boolean
35+
/** Set to true to skip restricted ranges with arrow keys. */
3436
minRange?: number;
3537
/** Number (defaults to null): The maximum range authorized on the slider. Applies to range slider only. */
3638
maxRange?: number;

dist/rzslider.js

Lines changed: 147 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*! angularjs-slider - v7.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-
2021-09-07 */
4+
2022-05-26 */
55
/*jslint unparam: true */
66
/*global angular: false, console: false, define, module */
77
;(function(root, factory) {
@@ -37,6 +37,7 @@
3737
minRange: null,
3838
maxRange: null,
3939
restrictedRange: null,
40+
skipRestrictedRangesWithArrowKeys: null,
4041
pushRange: false,
4142
minLimit: null,
4243
maxLimit: null,
@@ -520,8 +521,8 @@
520521
},
521522

522523
/*
523-
* Reflow the slider when the low handle changes (called with throttle)
524-
*/
524+
* Reflow the slider when the low handle changes (called with throttle)
525+
*/
525526
onLowHandleChange: function() {
526527
this.syncLowValue()
527528
if (this.range) this.syncHighValue()
@@ -536,8 +537,8 @@
536537
},
537538

538539
/*
539-
* Reflow the slider when the high handle changes (called with throttle)
540-
*/
540+
* Reflow the slider when the high handle changes (called with throttle)
541+
*/
541542
onHighHandleChange: function() {
542543
this.syncLowValue()
543544
this.syncHighValue()
@@ -665,6 +666,40 @@
665666
}
666667
},
667668

669+
/**
670+
* Check if the restrictedRange option using multiple or not
671+
*
672+
* Run only once during initialization and only in case 4
673+
*
674+
* @returns {undefined}
675+
*/
676+
677+
ensureRestrictedBarIsArray: function(elem) {
678+
var jElem = angular.element(elem)
679+
this.restrictedBar = []
680+
if (this.options.restrictedRange) {
681+
// this.options.restrictedRange converting to an array even if it's not entered as array.
682+
this.options.restrictedRange = !Array.isArray(
683+
this.options.restrictedRange
684+
)
685+
? [this.options.restrictedRange]
686+
: this.options.restrictedRange
687+
this.restrictedBar[0] = jElem
688+
var mainDiv = elem.parentElement
689+
for (var i = 1; i < this.options.restrictedRange.length; i++) {
690+
var sp = document.createElement('span')
691+
sp.setAttribute('class', 'rz-bar-wrapper')
692+
sp.innerHTML =
693+
'<span class="rz-bar rz-restricted" ng-style="restrictionStyle"></span>'
694+
mainDiv.appendChild(sp)
695+
this.restrictedBar[i] = angular.element(sp)
696+
}
697+
} else {
698+
elem.style.visibility = 'hidden'
699+
this.restrictedBar = null
700+
}
701+
},
702+
668703
/**
669704
* Set the slider children to variables for easy access
670705
*
@@ -693,7 +728,7 @@
693728
this.selBar = jElem
694729
break
695730
case 4:
696-
this.restrictedBar = jElem
731+
this.ensureRestrictedBarIsArray(elem)
697732
break
698733
case 5:
699734
this.minH = jElem
@@ -773,7 +808,16 @@
773808
this.leftOutSelBar,
774809
!this.range || !this.options.showOuterSelectionBars
775810
)
776-
this.alwaysHide(this.restrictedBar, !this.options.restrictedRange)
811+
812+
// this.restrictedBar is everytime an array
813+
for (var r in this.restrictedBar) {
814+
if (this.restrictedBar[r])
815+
this.alwaysHide(
816+
this.restrictedBar[r],
817+
!this.options.restrictedRange[r]
818+
)
819+
}
820+
777821
this.alwaysHide(
778822
this.rightOutSelBar,
779823
!this.range || !this.options.showOuterSelectionBars
@@ -1358,14 +1402,23 @@
13581402
var position = 0,
13591403
dimension = 0
13601404
if (this.options.restrictedRange) {
1361-
var from = this.valueToPosition(this.options.restrictedRange.from),
1362-
to = this.valueToPosition(this.options.restrictedRange.to)
1363-
dimension = Math.abs(to - from)
1364-
position = this.options.rightToLeft
1365-
? to + this.handleHalfDim
1366-
: from + this.handleHalfDim
1367-
this.setDimension(this.restrictedBar, dimension)
1368-
this.setPosition(this.restrictedBar, position)
1405+
this.options.restrictedRange = !Array.isArray(
1406+
this.options.restrictedRange
1407+
)
1408+
? [this.options.restrictedRange]
1409+
: this.options.restrictedRange
1410+
for (var i in this.options.restrictedRange) {
1411+
var from = this.valueToPosition(
1412+
this.options.restrictedRange[i].from
1413+
),
1414+
to = this.valueToPosition(this.options.restrictedRange[i].to)
1415+
dimension = Math.abs(to - from)
1416+
position = this.options.rightToLeft
1417+
? to + this.handleHalfDim
1418+
: from + this.handleHalfDim
1419+
this.setDimension(this.restrictedBar[i], dimension)
1420+
this.setPosition(this.restrictedBar[i], position)
1421+
}
13691422
}
13701423
},
13711424

@@ -1447,8 +1500,8 @@
14471500
? 'bottom'
14481501
: 'top'
14491502
: reversed
1450-
? 'left'
1451-
: 'right'
1503+
? 'left'
1504+
: 'right'
14521505
this.scope.barStyle = {
14531506
backgroundImage:
14541507
'linear-gradient(to ' +
@@ -2183,6 +2236,55 @@
21832236
}
21842237
},
21852238

2239+
/**
2240+
* Skip restricted range function when arrow keys use
2241+
*
2242+
* @param {number} currentValue value of the slider
2243+
* @param {number} key arrow key used
2244+
*
2245+
* @returns {number} currentValue value of the slider
2246+
*/
2247+
2248+
skipRestrictedRanges: function(key, currentValue) {
2249+
if (
2250+
this.options.restrictedRange &&
2251+
Array.isArray(this.options.restrictedRange)
2252+
) {
2253+
for (var i in this.options.restrictedRange) {
2254+
var range = this.options.restrictedRange[i]
2255+
// if it first or last value
2256+
if (
2257+
(range.from === 0 &&
2258+
currentValue === 0 &&
2259+
[37, 40].includes(key)) || // LEFT or DOWN
2260+
(range.to >=
2261+
this.options.restrictedRange[
2262+
this.options.restrictedRange.length - 1
2263+
].to &&
2264+
currentValue >=
2265+
this.options.restrictedRange[
2266+
this.options.restrictedRange.length - 1
2267+
].to &&
2268+
[38, 39].includes(key)) // UP or RIGHT
2269+
) {
2270+
return currentValue
2271+
}
2272+
if (range.to > currentValue && currentValue > range.from) {
2273+
if (
2274+
Math.abs(range.to - currentValue) >
2275+
Math.abs(range.from - currentValue)
2276+
) {
2277+
currentValue = range.to
2278+
} else {
2279+
currentValue = range.from
2280+
}
2281+
}
2282+
}
2283+
}
2284+
2285+
return currentValue
2286+
},
2287+
21862288
/**
21872289
* Key actions helper function
21882290
*
@@ -2228,9 +2330,9 @@
22282330
},
22292331

22302332
onKeyboardEvent: function(event) {
2231-
var currentValue = this[this.tracking],
2232-
keyCode = event.keyCode || event.which,
2233-
keys = {
2333+
var keyCode = event.keyCode || event.which
2334+
var currentValue = this[this.tracking]
2335+
var keys = {
22342336
38: 'UP',
22352337
40: 'DOWN',
22362338
37: 'LEFT',
@@ -2254,6 +2356,9 @@
22542356
var self = this
22552357
$timeout(function() {
22562358
var newValue = self.roundStep(self.sanitizeValue(action))
2359+
newValue = self.options.skipRestrictedRangesWithArrowKeys
2360+
? self.skipRestrictedRanges(keyCode, newValue)
2361+
: newValue
22572362
if (!self.options.draggableRangeOnly) {
22582363
self.positionTrackingHandle(newValue)
22592364
} else {
@@ -2548,26 +2653,30 @@
25482653
},
25492654

25502655
applyRestrictedRange: function(newValue) {
2551-
if (
2552-
this.options.restrictedRange != null &&
2553-
newValue > this.options.restrictedRange.from &&
2554-
newValue < this.options.restrictedRange.to
2555-
) {
2556-
var halfWidth =
2557-
(this.options.restrictedRange.to -
2558-
this.options.restrictedRange.from) /
2559-
2
2560-
if (this.tracking === 'lowValue') {
2561-
return newValue > this.options.restrictedRange.from + halfWidth
2562-
? this.options.restrictedRange.to
2563-
: this.options.restrictedRange.from
2564-
}
2565-
if (this.tracking === 'highValue') {
2566-
return newValue < this.options.restrictedRange.to - halfWidth
2567-
? this.options.restrictedRange.from
2568-
: this.options.restrictedRange.to
2656+
for (var i in this.options.restrictedRange) {
2657+
if (
2658+
this.options.restrictedRange[i] != null &&
2659+
newValue > this.options.restrictedRange[i].from &&
2660+
newValue < this.options.restrictedRange[i].to
2661+
) {
2662+
var halfWidth =
2663+
(this.options.restrictedRange[i].to -
2664+
this.options.restrictedRange[i].from) /
2665+
2
2666+
if (this.tracking === 'lowValue') {
2667+
return newValue >
2668+
this.options.restrictedRange[i].from + halfWidth
2669+
? this.options.restrictedRange[i].to
2670+
: this.options.restrictedRange[i].from
2671+
}
2672+
if (this.tracking === 'highValue') {
2673+
return newValue < this.options.restrictedRange[i].to - halfWidth
2674+
? this.options.restrictedRange[i].from
2675+
: this.options.restrictedRange[i].to
2676+
}
25692677
}
25702678
}
2679+
25712680
return newValue
25722681
},
25732682

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: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)