From a6cdd6eed72b4346eb790a2a8559fee2658dbca5 Mon Sep 17 00:00:00 2001 From: Wesley Cho <wesley.cho@gmail.com> Date: Sun, 11 Oct 2015 08:07:06 -0700 Subject: [PATCH] feat(timepicker): add accessibility improvements - Add ng-disabled usage in template - Add `timepickerTabindex` attribute support for binding tabindex to timepicker controls --- src/timepicker/docs/readme.md | 4 ++++ src/timepicker/test/timepicker.spec.js | 15 +++++++++++++++ src/timepicker/timepicker.js | 8 ++++++-- template/timepicker/timepicker.html | 14 +++++++------- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/timepicker/docs/readme.md b/src/timepicker/docs/readme.md index a168b0dcc4..4e2a231b7c 100644 --- a/src/timepicker/docs/readme.md +++ b/src/timepicker/docs/readme.md @@ -50,3 +50,7 @@ All settings can be provided as attributes in the `<uib-timepicker>` or globally * `max` _(Defaults: undefined)_ : Maximum time a user can select + + * `tabindex` + _(Defaults: 0)_ : + Sets tabindex for each control in timepicker \ No newline at end of file diff --git a/src/timepicker/test/timepicker.spec.js b/src/timepicker/test/timepicker.spec.js index 93dac89664..128471ec27 100644 --- a/src/timepicker/test/timepicker.spec.js +++ b/src/timepicker/test/timepicker.spec.js @@ -937,6 +937,21 @@ describe('timepicker directive', function() { expect(getModelState()).toEqual([16, 40]); expect(element.hasClass('ng-invalid-time')).toBe(false); }); + + it('should have a default tabindex of 0', function() { + element = $compile('<uib-timepicker ng-model="time"></uib-timepicker>')($rootScope); + $rootScope.$digest(); + + expect(element.isolateScope().tabindex).toBe(0); + }); + + fit('should have the correct tabindex', function() { + element = $compile('<uib-timepicker ng-model="time" tabindex="5"></uib-timepicker>')($rootScope); + $rootScope.$digest(); + + expect(element.attr('tabindex')).toBe(undefined); + expect(element.isolateScope().tabindex).toBe('5'); + }); }); describe('when model is not a Date', function() { diff --git a/src/timepicker/timepicker.js b/src/timepicker/timepicker.js index 6ab5917750..8e91e9b0e3 100644 --- a/src/timepicker/timepicker.js +++ b/src/timepicker/timepicker.js @@ -11,11 +11,14 @@ angular.module('ui.bootstrap.timepicker', []) showSpinners: true }) -.controller('UibTimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) { +.controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) { var selected = new Date(), ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS; + $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0; + $element.removeAttr('tabindex'); + this.init = function(ngModelCtrl_, inputs) { ngModelCtrl = ngModelCtrl_; ngModelCtrl.$render = this.render; @@ -386,13 +389,14 @@ angular.module('ui.bootstrap.timepicker') .value('$timepickerSuppressWarning', false) -.controller('TimepickerController', ['$scope', '$attrs', '$controller', '$log', '$timepickerSuppressWarning', function($scope, $attrs, $controller, $log, $timepickerSuppressWarning) { +.controller('TimepickerController', ['$scope', '$element', '$attrs', '$controller', '$log', '$timepickerSuppressWarning', function($scope, $element, $attrs, $controller, $log, $timepickerSuppressWarning) { if (!$timepickerSuppressWarning) { $log.warn('TimepickerController is now deprecated. Use UibTimepickerController instead.'); } return $controller('UibTimepickerController', { $scope: $scope, + $element: $element, $attrs: $attrs }); }]) diff --git a/template/timepicker/timepicker.html b/template/timepicker/timepicker.html index f09963333d..1873841f49 100644 --- a/template/timepicker/timepicker.html +++ b/template/timepicker/timepicker.html @@ -1,25 +1,25 @@ <table> <tbody> <tr class="text-center" ng-show="::showSpinners"> - <td><a ng-click="incrementHours()" ng-class="{disabled: noIncrementHours()}" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td> + <td><a ng-click="incrementHours()" ng-class="{disabled: noIncrementHours()}" class="btn btn-link" ng-disabled="noIncrementHours()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-up"></span></a></td> <td> </td> - <td><a ng-click="incrementMinutes()" ng-class="{disabled: noIncrementMinutes()}" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td> + <td><a ng-click="incrementMinutes()" ng-class="{disabled: noIncrementMinutes()}" class="btn btn-link" ng-disabled="noIncrementMinutes()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-up"></span></a></td> <td ng-show="showMeridian"></td> </tr> <tr> <td class="form-group" ng-class="{'has-error': invalidHours}"> - <input style="width:50px;" type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2"> + <input style="width:50px;" type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2" tabindex="{{::tabindex}}"> </td> <td>:</td> <td class="form-group" ng-class="{'has-error': invalidMinutes}"> - <input style="width:50px;" type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2"> + <input style="width:50px;" type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2" tabindex="{{::tabindex}}"> </td> - <td ng-show="showMeridian"><button type="button" ng-class="{disabled: noToggleMeridian()}" class="btn btn-default text-center" ng-click="toggleMeridian()">{{meridian}}</button></td> + <td ng-show="showMeridian"><button type="button" ng-class="{disabled: noToggleMeridian()}" class="btn btn-default text-center" ng-click="toggleMeridian()" ng-disabled="noToggleMeridian()" tabindex="{{::tabindex}}">{{meridian}}</button></td> </tr> <tr class="text-center" ng-show="::showSpinners"> - <td><a ng-click="decrementHours()" ng-class="{disabled: noDecrementHours()}" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td> + <td><a ng-click="decrementHours()" ng-class="{disabled: noDecrementHours()}" class="btn btn-link" ng-disabled="noDecrementHours()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-down"></span></a></td> <td> </td> - <td><a ng-click="decrementMinutes()" ng-class="{disabled: noDecrementMinutes()}" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td> + <td><a ng-click="decrementMinutes()" ng-class="{disabled: noDecrementMinutes()}" class="btn btn-link" ng-disabled="noDecrementMinutes()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-down"></span></a></td> <td ng-show="showMeridian"></td> </tr> </tbody>