Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 2296115

Browse files
Josh Friendwesleycho
Josh Friend
authored andcommitted
feat(timepicker): have up/down arrow keys control time selection
Add ability to use arrow keys to control time selection
1 parent 0d8820b commit 2296115

File tree

3 files changed

+125
-3
lines changed

3 files changed

+125
-3
lines changed

Diff for: src/timepicker/docs/readme.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ All settings can be provided as attributes in the `<timepicker>` or globally con
2929
Whether user can type inside the hours & minutes input.
3030

3131
* `mousewheel`
32-
_(Defaults: true)_ :
33-
Whether user can scroll inside the hours & minutes input to increase or decrease it's values.
32+
_(Defaults: true)_ :
33+
Whether user can scroll inside the hours & minutes input to increase or decrease it's values.
34+
35+
* `arrowkeys`
36+
_(Defaults: true)_ :
37+
Whether user can use up/down arrowkeys inside the hours & minutes input to increase or decrease it's values.

Diff for: src/timepicker/test/timepicker.spec.js

+83
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ describe('timepicker directive', function () {
7171
return e;
7272
}
7373

74+
function keydown(key) {
75+
var e = $.Event('keydown');
76+
switch(key) {
77+
case 'left':
78+
e.which = 37;
79+
break;
80+
case 'up':
81+
e.which = 38;
82+
break;
83+
case 'right':
84+
e.which = 39;
85+
break;
86+
case 'down':
87+
e.which = 40;
88+
break;
89+
}
90+
return e;
91+
}
92+
7493
it('contains three row & three input elements', function() {
7594
expect(element.find('tr').length).toBe(3);
7695
expect(element.find('input').length).toBe(2);
@@ -376,6 +395,70 @@ describe('timepicker directive', function () {
376395
expect(getModelState()).toEqual([14, 40]);
377396
});
378397

398+
it('responds properly on "keydown" events', function() {
399+
var inputs = element.find('input');
400+
var hoursEl = inputs.eq(0), minutesEl = inputs.eq(1);
401+
var upKeydownEvent = keydown('up');
402+
var downKeydownEvent = keydown('down');
403+
var leftKeydownEvent = keydown('left');
404+
405+
expect(getTimeState()).toEqual(['02', '40', 'PM']);
406+
expect(getModelState()).toEqual([14, 40]);
407+
408+
// UP
409+
hoursEl.trigger( upKeydownEvent );
410+
$rootScope.$digest();
411+
expect(getTimeState()).toEqual(['03', '40', 'PM']);
412+
expect(getModelState()).toEqual([15, 40]);
413+
414+
hoursEl.trigger( upKeydownEvent );
415+
$rootScope.$digest();
416+
expect(getTimeState()).toEqual(['04', '40', 'PM']);
417+
expect(getModelState()).toEqual([16, 40]);
418+
419+
minutesEl.trigger( upKeydownEvent );
420+
$rootScope.$digest();
421+
expect(getTimeState()).toEqual(['04', '41', 'PM']);
422+
expect(getModelState()).toEqual([16, 41]);
423+
424+
minutesEl.trigger( upKeydownEvent );
425+
$rootScope.$digest();
426+
expect(getTimeState()).toEqual(['04', '42', 'PM']);
427+
expect(getModelState()).toEqual([16, 42]);
428+
429+
// DOWN
430+
minutesEl.trigger( downKeydownEvent );
431+
$rootScope.$digest();
432+
expect(getTimeState()).toEqual(['04', '41', 'PM']);
433+
expect(getModelState()).toEqual([16, 41]);
434+
435+
minutesEl.trigger( downKeydownEvent );
436+
$rootScope.$digest();
437+
expect(getTimeState()).toEqual(['04', '40', 'PM']);
438+
expect(getModelState()).toEqual([16, 40]);
439+
440+
hoursEl.trigger( downKeydownEvent );
441+
$rootScope.$digest();
442+
expect(getTimeState()).toEqual(['03', '40', 'PM']);
443+
expect(getModelState()).toEqual([15, 40]);
444+
445+
hoursEl.trigger( downKeydownEvent );
446+
$rootScope.$digest();
447+
expect(getTimeState()).toEqual(['02', '40', 'PM']);
448+
expect(getModelState()).toEqual([14, 40]);
449+
450+
// Other keydown
451+
hoursEl.trigger( leftKeydownEvent );
452+
$rootScope.$digest();
453+
expect(getTimeState()).toEqual(['02', '40', 'PM']);
454+
expect(getModelState()).toEqual([14, 40]);
455+
456+
minutesEl.trigger( leftKeydownEvent );
457+
$rootScope.$digest();
458+
expect(getTimeState()).toEqual(['02', '40', 'PM']);
459+
expect(getModelState()).toEqual([14, 40]);
460+
});
461+
379462
describe('attributes', function () {
380463
beforeEach(function() {
381464
$rootScope.hstep = 2;

Diff for: src/timepicker/timepicker.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ angular.module('ui.bootstrap.timepicker', [])
66
showMeridian: true,
77
meridians: null,
88
readonlyInput: false,
9-
mousewheel: true
9+
mousewheel: true,
10+
arrowkeys: true
1011
})
1112

1213
.controller('TimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'timepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) {
@@ -26,6 +27,11 @@ angular.module('ui.bootstrap.timepicker', [])
2627
this.setupMousewheelEvents( hoursInputEl, minutesInputEl );
2728
}
2829

30+
var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;
31+
if (arrowkeys) {
32+
this.setupArrowkeyEvents( hoursInputEl, minutesInputEl );
33+
}
34+
2935
$scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
3036
this.setupInputEvents( hoursInputEl, minutesInputEl );
3137
};
@@ -114,6 +120,35 @@ angular.module('ui.bootstrap.timepicker', [])
114120

115121
};
116122

123+
// Respond on up/down arrowkeys
124+
this.setupArrowkeyEvents = function( hoursInputEl, minutesInputEl ) {
125+
hoursInputEl.bind('keydown', function(e) {
126+
if ( e.which === 38 ) { // up
127+
e.preventDefault();
128+
$scope.incrementHours();
129+
$scope.$apply();
130+
}
131+
else if ( e.which === 40 ) { // down
132+
e.preventDefault();
133+
$scope.decrementHours();
134+
$scope.$apply();
135+
}
136+
});
137+
138+
minutesInputEl.bind('keydown', function(e) {
139+
if ( e.which === 38 ) { // up
140+
e.preventDefault();
141+
$scope.incrementMinutes();
142+
$scope.$apply();
143+
}
144+
else if ( e.which === 40 ) { // down
145+
e.preventDefault();
146+
$scope.decrementMinutes();
147+
$scope.$apply();
148+
}
149+
});
150+
};
151+
117152
this.setupInputEvents = function( hoursInputEl, minutesInputEl ) {
118153
if ( $scope.readonlyInput ) {
119154
$scope.updateHours = angular.noop;

0 commit comments

Comments
 (0)