Skip to content

Commit

Permalink
feat(pagination): Accessibiliy & Keyboard Support to Pagination Controls
Browse files Browse the repository at this point in the history
 - Adds appropriate aria labels to the pagination controls.
 - Styles Pagination Buttons using Bootstrap.
 - Adds focus managment on the buttons so that when they are disabled
   focus shifts to the center input box.
  • Loading branch information
JLLeitschuh committed Jul 27, 2015
1 parent 377485a commit ee04132
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 14 deletions.
32 changes: 32 additions & 0 deletions src/features/pagination/js/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,14 @@
scope: true,
require: '^uiGrid',
link: function ($scope, $elm, $attr, uiGridCtrl) {
var defaultFocusElementSelector = '.ui-grid-pager-control-input';
$scope.aria = i18nService.getSafeText('pagination.aria'); //Returns an object with all of the aria labels

$scope.paginationApi = uiGridCtrl.grid.api.pagination;
$scope.sizesLabel = i18nService.getSafeText('pagination.sizes');
$scope.totalItemsLabel = i18nService.getSafeText('pagination.totalItems');
$scope.paginationOf = i18nService.getSafeText('pagination.of');
$scope.paginationThrough = i18nService.getSafeText('pagination.through');

var options = uiGridCtrl.grid.options;

Expand Down Expand Up @@ -414,6 +418,34 @@
$scope.cantPageBackward = function () {
return options.paginationCurrentPage <= 1;
};

var focusToInputIf = function(condition){
if (condition){
gridUtil.focus.bySelector($elm, defaultFocusElementSelector);
}
};

//Takes care of setting focus to the middle element when focus is lost
$scope.pageFirstPageClick = function () {
$scope.paginationApi.seek(1);
focusToInputIf($scope.cantPageBackward());
};

$scope.pagePreviousPageClick = function () {
$scope.paginationApi.previousPage();
focusToInputIf($scope.cantPageBackward());
};

$scope.pageNextPageClick = function () {
$scope.paginationApi.nextPage();
focusToInputIf($scope.cantPageForward());
};

$scope.pageLastPageClick = function () {
$scope.paginationApi.seek($scope.paginationApi.getTotalPages());
focusToInputIf($scope.cantPageToLast());
};

}
};
}
Expand Down
19 changes: 19 additions & 0 deletions src/features/pagination/less/pagination.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@import "../../../less/variables";
@import "../../../less/elements";
@import (reference) "../../../less/bootstrap/bootstrap";

.ui-grid-pager-panel {
position: absolute;
left: 0;
Expand All @@ -20,14 +24,26 @@
button {
height: 25px;
min-width: 26px;
#ui-grid-twbs > .btn;
#ui-grid-twbs > .button-variant(@paginationButtonColor, @paginationButtonBackgroundColor, @paginationButtonBorderColor);
}

input {
#ui-grid-twbs > .form-control();
#ui-grid-twbs > .input-sm ();
display: inline;
height: 26px;
width: 50px;
vertical-align: top;
}

.ui-grid-pager-max-pages-number{
vertical-align: bottom;
> * {
vertical-align: middle;
}
}

.first-bar {
width: 10px;
border-left: 2px solid #4d4d4d;
Expand Down Expand Up @@ -75,8 +91,11 @@
float: left;

select {
#ui-grid-twbs > .form-control;
#ui-grid-twbs > .input-sm ();
height: 26px;
width: 60px;
display: inline;
}

.ui-grid-pager-row-count-label {
Expand Down
102 changes: 88 additions & 14 deletions src/features/pagination/templates/pagination.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,97 @@
<div class="ui-grid-pager-panel" ui-grid-pager ng-show="grid.options.enablePaginationControls">
<div class="ui-grid-pager-container">
<div class="ui-grid-pager-control">
<button type="button" class="ui-grid-pager-first" ng-click="paginationApi.seek(1)" ng-disabled="cantPageBackward()"><div class="first-triangle"><div class="first-bar"></div></div></button>
<button type="button" class="ui-grid-pager-previous" ng-click="paginationApi.previousPage()" ng-disabled="cantPageBackward()"><div class="first-triangle prev-triangle"></div></button>
<input type="number" ng-model="grid.options.paginationCurrentPage" min="1" max="{{ paginationApi.getTotalPages() }}" required />
<span class="ui-grid-pager-max-pages-number" ng-show="paginationApi.getTotalPages() > 0">/ {{ paginationApi.getTotalPages() }}</span>
<button type="button" class="ui-grid-pager-next" ng-click="paginationApi.nextPage()" ng-disabled="cantPageForward()"><div class="last-triangle next-triangle"></div></button>
<button type="button" class="ui-grid-pager-last" ng-click="paginationApi.seek(paginationApi.getTotalPages())" ng-disabled="cantPageToLast()"><div class="last-triangle"><div class="last-bar"></div></div></button>
<div
role="contentinfo"
class="ui-grid-pager-panel"
ui-grid-pager
ng-show="grid.options.enablePaginationControls">
<div
role="navigation"
class="ui-grid-pager-container">
<div
role="menubar"
class="ui-grid-pager-control">
<button
type="button"
role="menuitem"
class="ui-grid-pager-first"
ui-grid-one-bind-title="aria.pageToFirst"
ui-grid-one-bind-aria-label="aria.pageToFirst"
ng-click="pageFirstPageClick()"
ng-disabled="cantPageBackward()">
<div class="first-triangle">
<div class="first-bar"></div>
</div>
</button>
<button
type="button"
role="menuitem"
class="ui-grid-pager-previous"
ui-grid-one-bind-title="aria.pageBack"
ui-grid-one-bind-aria-label="aria.pageBack"
ng-click="pagePreviousPageClick()"
ng-disabled="cantPageBackward()">
<div class="first-triangle prev-triangle"></div>
</button>
<input
type="number"
ui-grid-one-bind-title="aria.pageSelected"
ui-grid-one-bind-aria-label="aria.pageSelected"
class="ui-grid-pager-control-input"
ng-model="grid.options.paginationCurrentPage"
min="1"
max="{{ paginationApi.getTotalPages() }}"
required />
<span
class="ui-grid-pager-max-pages-number"
ng-show="paginationApi.getTotalPages() > 0">
<abbr ui-grid-one-bind-title="paginationOf">/</abbr> {{ paginationApi.getTotalPages() }}
</span>
<button
type="button"
role="menuitem"
class="ui-grid-pager-next"
ui-grid-one-bind-title="aria.pageForward"
ui-grid-one-bind-aria-label="aria.pageForward"
ng-click="pageNextPageClick()"
ng-disabled="cantPageForward()">
<div class="last-triangle next-triangle"></div>
</button>
<button
type="button"
role="menuitem"
class="ui-grid-pager-last"
ui-grid-one-bind-title="aria.pageToLast"
ui-grid-one-bind-aria-label="aria.pageToLast"
ng-click="pageLastPageClick()"
ng-disabled="cantPageToLast()">
<div class="last-triangle">
<div class="last-bar">
</div>
</div>
</button>
</div>
<div class="ui-grid-pager-row-count-picker" ng-if="grid.options.paginationPageSizes.length > 1">
<select ng-model="grid.options.paginationPageSize" ng-options="o as o for o in grid.options.paginationPageSizes"></select>
<span class="ui-grid-pager-row-count-label">&nbsp;{{sizesLabel}}</span>
<div
class="ui-grid-pager-row-count-picker"
ng-if="grid.options.paginationPageSizes.length > 1">
<select
ui-grid-one-bind-aria-labelledby-grid="'items-per-page-label'"
ng-model="grid.options.paginationPageSize"
ng-options="o as o for o in grid.options.paginationPageSizes"></select>
<span
ui-grid-one-bind-id-grid="'items-per-page-label'"
class="ui-grid-pager-row-count-label">
&nbsp;{{sizesLabel}}
</span>
</div>
<span ng-if="grid.options.paginationPageSizes.length <= 1" class="ui-grid-pager-row-count-label">{{grid.options.paginationPageSize}}&nbsp;{{sizesLabel}}</span>
<span
ng-if="grid.options.paginationPageSizes.length <= 1"
class="ui-grid-pager-row-count-label">
{{grid.options.paginationPageSize}}&nbsp;{{sizesLabel}}
</span>
</div>
<div class="ui-grid-pager-count-container">
<div class="ui-grid-pager-count">
<span ng-show="grid.options.totalItems > 0">
{{showingLow}} - {{showingHigh}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
{{showingLow}} <abbr ui-grid-one-bind-title="paginationThrough">-</abbr> {{showingHigh}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
</span>
</div>
</div>
Expand Down

0 comments on commit ee04132

Please sign in to comment.