Skip to content
This repository was archived by the owner on Aug 7, 2020. It is now read-only.

Commit 11c3c47

Browse files
authored
fix(oui-pagination): add input search when huge amount of pages (#358)
* fix(oui-pagination): add input search when huge amount of pages * style: code review * style: code review
1 parent d736ebd commit 11c3c47

File tree

3 files changed

+80
-25
lines changed

3 files changed

+80
-25
lines changed

packages/oui-pagination/README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44

55
## Usage
66

7+
### One page
8+
9+
```html:preview
10+
<oui-pagination
11+
current-offset="1"
12+
page-size="100"
13+
total-items="12">
14+
</oui-pagination>
15+
```
16+
717
### A few pages
818

919
```html:preview
@@ -25,13 +35,14 @@
2535
</oui-pagination>
2636
```
2737

28-
### One page
38+
### Huge amount of pages
2939

3040
```html:preview
3141
<oui-pagination
32-
current-offset="1"
33-
page-size="100"
34-
total-items="12">
42+
current-offset="$ctrl.pagination3.offset"
43+
page-size="$ctrl.pagination3.pageSize"
44+
total-items="$ctrl.pagination3.totalItems"
45+
on-change="$ctrl.onChange('pagination3', $event)">
3546
</oui-pagination>
3647
```
3748

packages/oui-pagination/src/pagination.controller.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import clamp from "lodash/clamp";
2+
import range from "lodash/range";
3+
14
export default class {
25
constructor ($attrs, ouiPaginationConfiguration) {
36
"ngInject";
@@ -35,17 +38,23 @@ export default class {
3538

3639
processPaginationChange () {
3740
this.pageCount = this.getPageCount();
38-
this.pageRange = this.getPageRange();
3941
this.currentPage = this.getCurrentPage();
42+
this.inputPage = this.getCurrentPage(); // Update model for input
4043
}
4144

4245
processTranslations () {
43-
this.translations = Object.assign({}, this.config.translations);
46+
this.translations = { ...this.config.translations };
4447
this.translations.ofNResults = this.translations.ofNResults
4548
.replace("{{totalItems}}", this.totalItems);
4649
this.translations.currentPageOfPageCount = this.translations.currentPageOfPageCount
4750
.replace("{{currentPage}}", this.currentPage)
4851
.replace("{{pageCount}}", this.pageCount);
52+
53+
// For huge amount of pages, we replaced "{{currentPage}}" by a number input
54+
const translations = { ...this.config.translations };
55+
this.translations.inputPageOfPageCount = translations.currentPageOfPageCount
56+
.replace("{{pageCount}}", this.pageCount)
57+
.split("{{currentPage}}");
4958
}
5059

5160
getPageAriaLabel (page) {
@@ -71,9 +80,19 @@ export default class {
7180

7281
onPageChange (page) {
7382
this.currentOffset = (this.pageSize * (page - 1)) + 1;
83+
this.currentPage = this.getCurrentPage();
84+
this.inputPage = this.getCurrentPage(); // Update model for input
7485
this._onChange();
7586
}
7687

88+
checkPageRange (page) {
89+
const currentPage = Number.isInteger(page) ?
90+
clamp(page, 1, this.pageCount) :
91+
this.currentPage;
92+
93+
this.onPageChange(currentPage);
94+
}
95+
7796
getLastItemOffset () {
7897
return Math.min(this.currentOffset + this.pageSize - 1, this.totalItems);
7998
}
@@ -87,8 +106,7 @@ export default class {
87106
}
88107

89108
getPageRange () {
90-
return Array(...{ length: this.getPageCount() })
91-
.map((item, index) => index + 1);
109+
return range(1, this.getPageCount() + 1);
92110
}
93111

94112
_onChange () {

packages/oui-pagination/src/pagination.html

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,20 @@
2727

2828
<div class="oui-pagination__selector"
2929
ng-if="$ctrl.totalItems > $ctrl.pageSize">
30-
<button type="button" class="oui-button oui-button_secondary oui-button_icon-only oui-button_small-width"
31-
type="button"
30+
<button type="button"
31+
class="oui-button oui-button_secondary oui-button_icon-only oui-button_small-width"
3232
ng-attr-aria-label="{{ ::$ctrl.translations.previousPage }}"
3333
ng-disabled="$ctrl.currentPage === 1"
3434
ng-click="$ctrl.onPageChange($ctrl.getCurrentPage() - 1)">
3535
<span class="oui-icon oui-icon-chevron-left" aria-hidden="true"></span>
3636
</button>
37+
38+
<!-- Buttons (<= 5 pages) -->
3739
<div class="oui-button-group"
3840
ng-if="$ctrl.pageCount <= 5">
3941
<button type="button"
4042
class="oui-button oui-button_small-width"
41-
ng-repeat="page in $ctrl.pageRange track by page"
43+
ng-repeat="page in $ctrl.getPageRange() track by page"
4244
ng-class="{
4345
'oui-button_primary oui-pagination-button_selected': page === $ctrl.currentPage,
4446
'oui-button_secondary': page != $ctrl.currentPage
@@ -47,30 +49,54 @@
4749
ng-bind="page"
4850
ng-click="$ctrl.onPageChange(page)"></button>
4951
</div>
50-
<oui-dropdown ng-if="$ctrl.pageCount > 5">
52+
<!-- /Buttons (<= 5 pages) -->
53+
54+
<!-- Dropdown (> 5 && <= 100 pages) -->
55+
<oui-dropdown ng-if="$ctrl.pageCount > 5 && $ctrl.pageCount <= 100"
56+
align="end">
5157
<button oui-dropdown-trigger
5258
type="button"
5359
ng-attr-aria-label="{{ $ctrl.translations.currentPageOfPageCount }}"
5460
class="oui-button oui-button_dropdown oui-dropdown__trigger">
5561
<span ng-bind="$ctrl.translations.currentPageOfPageCount"></span>
5662
<span class="oui-icon oui-icon-chevron-down" aria-hidden="true"></span>
5763
</button>
58-
<oui-dropdown-content>
59-
<div role="menu" class="oui-pagination-menu">
60-
<div class="oui-pagination-menu__items-list">
61-
<button type="button"
62-
ng-repeat="page in $ctrl.pageRange track by page"
63-
class="oui-pagination-menu__item"
64-
ng-attr-aria-label="{{ ::$ctrl.getPageAriaLabel(page) }}"
65-
ng-disabled="page === $ctrl.currentPage"
66-
ng-bind="page"
67-
ng-click="$ctrl.onPageChange(page)"></button>
68-
</div>
64+
<oui-dropdown-content class="oui-pagination-menu">
65+
<div class="oui-pagination-menu__items-list">
66+
<button type="button"
67+
ng-repeat="page in $ctrl.getPageRange() track by page"
68+
class="oui-pagination-menu__item"
69+
ng-attr-aria-label="{{ ::$ctrl.getPageAriaLabel(page) }}"
70+
ng-disabled="page === $ctrl.currentPage"
71+
ng-bind="page"
72+
ng-click="$ctrl.onPageChange(page)"></button>
6973
</div>
7074
</oui-dropdown-content>
7175
</oui-dropdown>
72-
<button type="button" class="oui-button oui-button_secondary oui-button_icon-only oui-button_small-width"
73-
type="button"
76+
<!-- /Dropdown (> 5 && <= 100 pages) -->
77+
78+
<!-- Numeric (> 100 pages) -->
79+
<form class="oui-pagination-numeric"
80+
ng-if="$ctrl.pageCount > 100"
81+
ng-submit="$ctrl.checkPageRange($ctrl.inputPage)"
82+
novalidate>
83+
<span aria-hidden="true"
84+
ng-bind="$ctrl.translations.inputPageOfPageCount[0]">
85+
</span>
86+
<input class="oui-pagination-numeric__input oui-input oui-input_xs"
87+
type="number"
88+
min="1"
89+
max="{{$ctrl.pageCount}}"
90+
ng-attr-aria-label="{{ $ctrl.getPageAriaLabel($ctrl.inputPage) }}"
91+
ng-model="$ctrl.inputPage">
92+
<span aria-hidden="true"
93+
ng-bind="$ctrl.translations.inputPageOfPageCount[1]">
94+
</span>
95+
</form>
96+
<!-- /Input (> 100 pages) -->
97+
98+
<button type="button"
99+
class="oui-button oui-button_secondary oui-button_icon-only oui-button_small-width"
74100
ng-attr-aria-label="{{ ::$ctrl.translations.nextPage }}"
75101
ng-disabled="$ctrl.currentPage === $ctrl.pageCount"
76102
ng-click="$ctrl.onPageChange($ctrl.currentPage + 1)">

0 commit comments

Comments
 (0)