Skip to content

Commit 8cbdc46

Browse files
authored
fix(keyboardSupport): Prevent losing focus when slider is rerendered (#415)
Fix #411
1 parent 8af6174 commit 8cbdc46

File tree

4 files changed

+71
-11
lines changed

4 files changed

+71
-11
lines changed

dist/rzslider.js

+25-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*! angularjs-slider - v5.5.0 -
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-09-06 */
4+
2016-09-22 */
55
/*jslint unparam: true */
66
/*global angular: false, console: false, define, module */
77
(function(root, factory) {
@@ -304,6 +304,11 @@
304304
*/
305305
this.cmbLabelShown = false;
306306

307+
/**
308+
* Internal variable to keep track of the focus element
309+
*/
310+
this.currentFocusElement = null;
311+
307312
// Slider DOM elements wrapped in jqLite
308313
this.fullBar = null; // The whole slider bar
309314
this.selBar = null; // Highlight between two handles
@@ -413,6 +418,7 @@
413418
this.scope.$on('$destroy', function() {
414419
self.unbindEvents();
415420
angular.element($window).off('resize', calcDimFn);
421+
self.currentFocusElement = null;
416422
});
417423
},
418424

@@ -577,7 +583,7 @@
577583
else {
578584
this.customTrFn = function(modelValue) {
579585
if (this.options.bindIndexForStepsArray)
580-
return this.getStepValue(modelValue)
586+
return this.getStepValue(modelValue);
581587
return modelValue;
582588
};
583589
}
@@ -605,6 +611,14 @@
605611
this.manageEventsBindings();
606612
this.setDisabledState();
607613
this.calcViewDimensions();
614+
this.refocusPointerIfNeeded();
615+
},
616+
617+
refocusPointerIfNeeded: function() {
618+
if (this.currentFocusElement) {
619+
this.onPointerFocus(this.currentFocusElement.pointer, this.currentFocusElement.ref);
620+
this.focusElement(this.currentFocusElement.pointer)
621+
}
608622
},
609623

610624
/**
@@ -1070,7 +1084,7 @@
10701084
};
10711085
}
10721086

1073-
if(this.options.autoHideLimitLabels){
1087+
if (this.options.autoHideLimitLabels) {
10741088
this.shFloorCeil();
10751089
}
10761090
},
@@ -1092,7 +1106,7 @@
10921106
backgroundColor: pointercolor
10931107
};
10941108
}
1095-
if(this.options.autoHideLimitLabels){
1109+
if (this.options.autoHideLimitLabels) {
10961110
this.shFloorCeil();
10971111
}
10981112

@@ -1695,6 +1709,11 @@
16951709
pointer.on('keyup', angular.bind(this, this.onKeyUp));
16961710
this.firstKeyDown = true;
16971711
pointer.addClass('rz-active');
1712+
1713+
this.currentFocusElement = {
1714+
pointer: pointer,
1715+
ref: ref
1716+
};
16981717
},
16991718

17001719
onKeyUp: function() {
@@ -1707,6 +1726,7 @@
17071726
pointer.off('keyup');
17081727
this.tracking = '';
17091728
pointer.removeClass('rz-active');
1729+
this.currentFocusElement = null
17101730
},
17111731

17121732
/**
@@ -1925,7 +1945,7 @@
19251945
newMinValue = this.options.minLimit;
19261946
newMaxValue = newMinValue + this.dragging.difference;
19271947
}
1928-
if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit){
1948+
if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit) {
19291949
newMaxValue = this.options.maxLimit;
19301950
newMinValue = newMaxValue - this.dragging.difference;
19311951
}

dist/rzslider.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rzslider.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@
308308
*/
309309
this.cmbLabelShown = false;
310310

311+
/**
312+
* Internal variable to keep track of the focus element
313+
*/
314+
this.currentFocusElement = null;
315+
311316
// Slider DOM elements wrapped in jqLite
312317
this.fullBar = null; // The whole slider bar
313318
this.selBar = null; // Highlight between two handles
@@ -417,6 +422,7 @@
417422
this.scope.$on('$destroy', function() {
418423
self.unbindEvents();
419424
angular.element($window).off('resize', calcDimFn);
425+
self.currentFocusElement = null;
420426
});
421427
},
422428

@@ -581,7 +587,7 @@
581587
else {
582588
this.customTrFn = function(modelValue) {
583589
if (this.options.bindIndexForStepsArray)
584-
return this.getStepValue(modelValue)
590+
return this.getStepValue(modelValue);
585591
return modelValue;
586592
};
587593
}
@@ -609,6 +615,14 @@
609615
this.manageEventsBindings();
610616
this.setDisabledState();
611617
this.calcViewDimensions();
618+
this.refocusPointerIfNeeded();
619+
},
620+
621+
refocusPointerIfNeeded: function() {
622+
if (this.currentFocusElement) {
623+
this.onPointerFocus(this.currentFocusElement.pointer, this.currentFocusElement.ref);
624+
this.focusElement(this.currentFocusElement.pointer)
625+
}
612626
},
613627

614628
/**
@@ -1074,7 +1088,7 @@
10741088
};
10751089
}
10761090

1077-
if(this.options.autoHideLimitLabels){
1091+
if (this.options.autoHideLimitLabels) {
10781092
this.shFloorCeil();
10791093
}
10801094
},
@@ -1096,7 +1110,7 @@
10961110
backgroundColor: pointercolor
10971111
};
10981112
}
1099-
if(this.options.autoHideLimitLabels){
1113+
if (this.options.autoHideLimitLabels) {
11001114
this.shFloorCeil();
11011115
}
11021116

@@ -1699,6 +1713,11 @@
16991713
pointer.on('keyup', angular.bind(this, this.onKeyUp));
17001714
this.firstKeyDown = true;
17011715
pointer.addClass('rz-active');
1716+
1717+
this.currentFocusElement = {
1718+
pointer: pointer,
1719+
ref: ref
1720+
};
17021721
},
17031722

17041723
onKeyUp: function() {
@@ -1711,6 +1730,7 @@
17111730
pointer.off('keyup');
17121731
this.tracking = '';
17131732
pointer.removeClass('rz-active');
1733+
this.currentFocusElement = null
17141734
},
17151735

17161736
/**
@@ -1929,7 +1949,7 @@
19291949
newMinValue = this.options.minLimit;
19301950
newMaxValue = newMinValue + this.dragging.difference;
19311951
}
1932-
if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit){
1952+
if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit) {
19331953
newMaxValue = this.options.maxLimit;
19341954
newMinValue = newMaxValue - this.dragging.difference;
19351955
}

tests/specs/keyboard-controls/specific-test.js

+20
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,26 @@
241241
helper.pressKeydown(helper.slider.minH, 'RIGHT');
242242
expect(helper.scope.slider.value).to.equal(90);
243243
});
244+
245+
it('should refocus the slider after a reset if needed and still handle keyboard', function() {
246+
var sliderConf = {
247+
value: 90,
248+
options: {
249+
floor: 0,
250+
ceil: 100,
251+
step: 1
252+
}
253+
};
254+
helper.createSlider(sliderConf);
255+
//try to move minH right
256+
helper.slider.minH.triggerHandler('focus');
257+
258+
helper.slider.resetSlider();
259+
260+
helper.pressKeydown(helper.slider.minH, 'RIGHT');
261+
expect(document.activeElement).to.equal(helper.slider.minH[0]);
262+
expect(helper.scope.slider.value).to.equal(91);
263+
});
244264
});
245265

246266
describe('Right to left Keyboard controls - specific tests', function() {

0 commit comments

Comments
 (0)