Skip to content

Commit 9afba6c

Browse files
authored
fix(pagination pagination-nav): v-model active class fix + keypress click fix (Fixes #1985, #1629) (#2299)
1 parent dabe150 commit 9afba6c

File tree

9 files changed

+494
-272
lines changed

9 files changed

+494
-272
lines changed

src/components/pagination-nav/README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# Pagination Navigation
22

3-
> Quick first, previous, next, last, and page buttons for pagination based navigation, supporting
3+
> Quick first, previous, next, last, and page buttons for navigation based pagination, supporting
44
regular links or router links.
55

6+
`<b-pagination-nav>` is used for navigating to new page URLs. For controlling in page component
7+
pagination (such as table or list pagination), use the [`<b-pagination>`](/docs/components/pagination)
8+
component instead.
9+
610
```html
711
<template>
812
<div>
@@ -86,7 +90,7 @@ buttons. You can override this behaviour by supplying a function reference to
8690
the `page-gen` property. The function reference should accept a single argument
8791
which is a page number (1-N). The `page-gen` function should return a string.
8892

89-
Note HTML strings are currently not supported.
93+
**Note:** HTML content in generated page number strings is **not** supported.
9094

9195
**Example: Using an array of links to generate pagination:**
9296

@@ -131,6 +135,7 @@ export default {
131135

132136
<!-- pagination-nav-links.vue -->
133137
```
138+
134139
## Button Size
135140
Optionally change from the default button size by setting the `size`
136141
prop to eiter `'am` for smaller buttons or `'lg'` for larger buttons.
@@ -162,6 +167,7 @@ export default {
162167
<!-- pagination-size.vue -->
163168
```
164169

170+
165171
## Customizing
166172

167173
`<b-pagination-nav>` supports several props that allow you to customize the appearance.
@@ -170,18 +176,27 @@ export default {
170176
| ---- | -----------
171177
| `limit` | Limit the maximum number of displayed page buttons (including ellipsis if present, and excluding first/prev/next/last buttons)
172178
| `number-of-pages` | The total number of pages
179+
| `hide-ellipsis` | never show ellipsis indicators
180+
| `hide-goto-end-buttons` | never display goto first/last buttons
181+
182+
And provides several props for setting the content of the bookend buttons:
183+
184+
| Prop | Description
185+
| ---- | -----------
173186
| `first-text` | The "goto first page" button text (plain html supported)
174187
| `prev-text` | The "goto previous page" button text (plain html supported)
175188
| `next-text` | The "goto next page" button text (plain html supported)
176189
| `last-text` | The "goto last page" button text (plain html supported)
177190
| `ellipsis-text` | the `...` indicator text (plain html supported)
178-
| `hide-ellipsis` | never show ellipsis indicators
179-
| `hide-goto-end-buttons` | never display goto first/last buttons
180191

181192
Ellipsis indicator(s) will only be ever shown at the front and/or end of
182193
the page number buttons. For `limit` values less than or equal to `3`, the ellipsis
183194
indicator(s) will never be shown for practical display reasons.
184195

196+
**Note:** HTML is supported via the bookend content props. If allowing user supplied content
197+
to populate these props, you should use named slots (see below) instead to avoid possible XSS attacks.
198+
199+
185200
### Named slots
186201

187202
`<b-pagination-nav>` supports several slots that allow you to customize the appearance.
@@ -194,6 +209,7 @@ indicator(s) will never be shown for practical display reasons.
194209
| `last-text` | The "goto last page" button text (html/sub-components supported)
195210
| `ellipsis-text` | the `...` indicator text (html/sub-components supported)
196211

212+
197213
## Alignment
198214

199215
By default the pagination component is left aligned. Change the alignment to
@@ -274,7 +290,7 @@ list, respectively, and <kbd>ENTER</kbd> or <kbd>SPACE</kbd> keys will select (c
274290
## See also
275291

276292
For pagination control of a component (such as `<b-table>`), use the
277-
[`<b-pagination>`](./pagination) component instead.
293+
[`<b-pagination>`](/docs/components/pagination) component instead.
278294

279295

280296
<!-- Component reference added automatically from component package.json -->
Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
<div id="app">
2-
<div>
3-
<h6>Default</h6>
4-
<b-pagination-nav :number-of-pages="10" base-url="#" v-model="currentPage" />
5-
<br>
6-
<div>currentPage: {{currentPage}}</div>
7-
</div>
2+
<div>
3+
<h6>Default</h6>
4+
<b-pagination-nav :number-of-pages="10" base-url="#" v-model="currentPage" />
5+
<br>
6+
<div>currentPage: {{currentPage}}</div>
7+
</div>
8+
<div>
9+
<h6>Link/Page Generation Fns</h6>
10+
<b-pagination-nav :link-gen="linkGen" :page-gen="pageGen" :number-of-pages="10" base-url="#" v-model="currentPage" />
11+
<br>
12+
<div>currentPage: {{currentPage}}</div>
13+
</div>
14+
<div>
15+
<h6>Router Links</h6>
16+
<b-pagination-nav use-router :number-of-pages="10" base-url="#" v-model="currentPage" />
17+
<br>
18+
<div>currentPage: {{currentPage}}</div>
19+
</div>
820
</div>

src/components/pagination-nav/fixtures/pagination-nav.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,18 @@ window.app = new Vue({
22
el: '#app',
33
data: {
44
currentPage: 1
5+
},
6+
mounted () {
7+
this.$nextTick(() => {
8+
this.currentPage = 2
9+
})
10+
},
11+
methods: {
12+
pageGen (num) {
13+
return `Page ${num})`
14+
},
15+
linkGen (num) {
16+
return `#page/${num})`
17+
}
518
}
619
})

src/components/pagination-nav/pagination-nav.js

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
1-
import { assign } from '../../utils/object'
1+
import warn from '../../utils/warn'
22
import paginationMixin from '../../mixins/pagination'
33
import { pickLinkProps } from '../link/link'
44

55
// Props needed for router links
66
const routerProps = pickLinkProps('activeClass', 'exactActiveClass', 'append', 'exact', 'replace', 'target', 'rel')
77

88
// Props object
9-
const props = assign(
9+
const props = {
1010
// pagination-nav specific props
11-
{
12-
numberOfPages: {
13-
type: Number,
14-
default: 1
15-
},
16-
baseUrl: {
17-
type: String,
18-
default: '/'
19-
},
20-
useRouter: {
21-
type: Boolean,
22-
default: false
23-
},
24-
linkGen: {
25-
type: Function,
26-
default: null
27-
},
28-
pageGen: {
29-
type: Function,
30-
default: null
11+
numberOfPages: {
12+
type: [Number, String],
13+
default: 1,
14+
validator (value) {
15+
const num = parseInt(value, 10)
16+
/* istanbul ignore if */
17+
if (isNaN(num) || num < 1) {
18+
warn('b-pagination: prop "number-of-pages" must be a number greater than 0')
19+
return false
20+
}
21+
return true
3122
}
3223
},
24+
baseUrl: {
25+
type: String,
26+
default: '/'
27+
},
28+
useRouter: {
29+
type: Boolean,
30+
default: false
31+
},
32+
linkGen: {
33+
type: Function,
34+
default: null
35+
},
36+
pageGen: {
37+
type: Function,
38+
default: null
39+
},
3340
// Router specific props
34-
routerProps
35-
)
41+
...routerProps
42+
}
43+
3644
// Our render function is brought in via the pagination mixin
3745
// @vue/component
3846
export default {
@@ -46,7 +54,16 @@ export default {
4654
},
4755
methods: {
4856
onClick (pageNum, evt) {
57+
// Update the v-model
4958
this.currentPage = pageNum
59+
this.$nextTick(() => {
60+
try {
61+
// Emulate native link click page reloading behaviour by bluring the
62+
// paginator and returing focus to the document
63+
const target = evt.currentTarget || evt.target
64+
target.blur()
65+
} catch (e) {}
66+
})
5067
},
5168
makePage (pagenum) {
5269
if (this.pageGen && typeof this.pageGen === 'function') {
@@ -70,14 +87,15 @@ export default {
7087
disabled: this.disabled
7188
}
7289
if (this.useRouter || typeof link === 'object') {
73-
props = assign(props, {
90+
props = {
91+
...props,
7492
to: link,
7593
exact: this.exact,
7694
activeClass: this.activeClass,
7795
exactActiveClass: this.exactActiveClass,
7896
append: this.append,
7997
replace: this.replace
80-
})
98+
}
8199
}
82100
return props
83101
}

src/components/pagination/README.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Pagination
22

33
> Quick first, previous, next, last, and page buttons for pagination control
4-
of another component (such as `<b-table>`).
4+
of another component (such as `<b-table>` or lists).
5+
6+
For pagination that navigates to a new URL, use the [`<b-pagination-nav>`](/docs/components/pagination-nav)
7+
component instead.
58

69
```html
710
<template>
@@ -49,21 +52,33 @@ values for `total-rows` and `per-page`.
4952
`<b-pagination>` supports several props that allow you to customize the appearance.
5053

5154
### Props
55+
5256
| Prop | Description
5357
| ---- | -----------
5458
| `limit` | Limit the maximum number of displayed page buttons (including ellipsis if present, and excluding first/prev/next/last buttons)
55-
| `total-rows` | The total number of records in your data
56-
| `per-page` | The maximum number of data records per page
59+
| `number-of-pages` | The total number of pages
60+
| `hide-ellipsis` | never show ellipsis indicators
61+
| `hide-goto-end-buttons` | never display goto first/last buttons
62+
63+
And provides several props for setting the content of the bookend buttons:
64+
65+
| Prop | Description
66+
| ---- | -----------
5767
| `first-text` | The "goto first page" button text (plain html supported)
5868
| `prev-text` | The "goto previous page" button text (plain html supported)
5969
| `next-text` | The "goto next page" button text (plain html supported)
6070
| `last-text` | The "goto last page" button text (plain html supported)
6171
| `ellipsis-text` | the `...` indicator text (plain html supported)
62-
| `hide-ellipsis` | never show ellipsis indicators
63-
| `hide-goto-end-buttons` | never display goto first/last buttons
6472

73+
Ellipsis indicator(s) will only be ever shown at the front and/or end of
74+
the page number buttons. For `limit` values less than or equal to `3`, the ellipsis
75+
indicator(s) will never be shown for practical display reasons.
76+
77+
**Note:** HTML is supported via the bookend content props. If allowing user supplied content
78+
to populate these props, you should use named slots (see below) instead to avoid possible XSS attacks.
6579

6680
### Named slots
81+
6782
| Slot | Description
6883
|----- | -----------
6984
| `first-text` | The "goto first page" button text (html/sub-components supported)
@@ -72,7 +87,6 @@ values for `total-rows` and `per-page`.
7287
| `last-text` | The "goto last page" button text (html/sub-components supported)
7388
| `ellipsis-text` | the `...` indicator text (html/sub-components supported)
7489

75-
7690
Ellipsis inidcator(s) will only be ever shown at the front and/or end of
7791
the page number buttons. For `limit` values less than or equal to `3`, the ellipsis
7892
indicator(s) will never be shown for practical display reasons.
@@ -168,7 +182,7 @@ list, respectively, and <kbd>ENTER</kbd> or <kbd>SPACE</kbd> keys will select (c
168182
Both events provide the single argument of the current page number (starting from 1)
169183

170184
## See Also
171-
For navigation based pagination, please see the [`<b-pagination-nav>`](./pagination-nav)
185+
For navigation based pagination, please see the [`<b-pagination-nav>`](/docs/components/pagination-nav)
172186
component.
173187

174188

src/components/pagination/fixtures/pagination.html

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ <h6>Default</h6>
66

77
<br><br>
88

9-
<b-pagination size="md" :total-rows="100" v-model="currentPage" :limit="10" :per-page="10">
9+
<b-pagination size="md" total-rows="100" v-model="currentPage" limit="10" per-page="10">
1010
</b-pagination>
1111

1212
<br><br>
@@ -39,7 +39,42 @@ <h6>Default</h6>
3939
<template slot="ellipsis-text">...</template>
4040
</b-pagination>
4141

42+
<br><br>
43+
44+
<b-pagination :total-rows="100" v-model="currentPage" limit="-1" :per-page="10">
45+
</b-pagination>
46+
47+
<br><br>
48+
49+
<b-pagination align="center" :total-rows="100" v-model="currentPage" :limit="4" :per-page="10">
50+
</b-pagination>
51+
52+
<br><br>
53+
54+
<b-pagination align="right" hide-goto-end-buttons :total-rows="100" v-model="currentPage" :limit="4" :per-page="10">
55+
</b-pagination>
56+
57+
<br><br>
58+
59+
<b-pagination align="end" hide-goto-end-buttons :total-rows="100" v-model="currentPage" :limit="4" :per-page="10">
60+
</b-pagination>
61+
4262
<br><br>
4363
<div>currentPage: {{currentPage}}</div>
64+
<br><br>
65+
66+
<b-pagination total-rows="100" v-model="currentPage2" limit="4" per-page="20">
67+
</b-pagination>
68+
<div>currentPage: {{currentPage2}}</div>
69+
70+
<br><br>
71+
72+
<b-pagination total-rows="100" value="10" limit="4" per-page="10">
73+
</b-pagination>
74+
75+
<br><br>
76+
77+
<b-pagination total-rows="100" value="20" limit="4" per-page="10">
78+
</b-pagination>
4479
</div>
4580
</div>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
window.app = new Vue({
22
el: '#app',
33
data: {
4-
currentPage: 3
4+
currentPage: 3,
5+
currentPage2: 2
56
}
67
})

0 commit comments

Comments
 (0)