Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(b-pagination): if number of pages changes, try and keep current page active (closes #3716) #3990

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Aug 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 40 additions & 19 deletions src/components/pagination/pagination.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import Vue from '../../utils/vue'
import { getComponentConfig } from '../../utils/config'
import { isVisible } from '../../utils/dom'
import { isUndefinedOrNull } from '../../utils/inspect'
import paginationMixin from '../../mixins/pagination'

// --- Constants ---

const NAME = 'BPagination'

const DEFAULT_PER_PAGE = 20
const DEFAULT_TOTAL_ROWS = 0

// Sanitize the provided per page number (converting to a number)
const sanitizePerPage = val => {
const perPage = parseInt(val, 10) || DEFAULT_PER_PAGE
return perPage < 1 ? 1 : perPage
}

// Sanitize the provided total rows number (converting to a number)
const sanitizeTotalRows = val => {
const totalRows = parseInt(val, 10) || DEFAULT_TOTAL_ROWS
return totalRows < 0 ? 0 : totalRows
}

const props = {
size: {
type: String,
Expand All @@ -39,7 +30,21 @@ const props = {
}
}

// The render function is brought in via the pagination mixin
// --- Helper functions ---

// Sanitize the provided per page number (converting to a number)
const sanitizePerPage = val => {
const perPage = parseInt(val, 10) || DEFAULT_PER_PAGE
return perPage < 1 ? 1 : perPage
}

// Sanitize the provided total rows number (converting to a number)
const sanitizeTotalRows = val => {
const totalRows = parseInt(val, 10) || DEFAULT_TOTAL_ROWS
return totalRows < 0 ? 0 : totalRows
}

// The render function is brought in via the `paginationMixin`
// @vue/component
export const BPagination = /*#__PURE__*/ Vue.extend({
name: NAME,
Expand All @@ -49,16 +54,32 @@ export const BPagination = /*#__PURE__*/ Vue.extend({
numberOfPages() {
const result = Math.ceil(sanitizeTotalRows(this.totalRows) / sanitizePerPage(this.perPage))
return result < 1 ? 1 : result
},
pageSizeNumberOfPages() {
// Used for watching changes to `perPage` and `numberOfPages`
return {
perPage: sanitizePerPage(this.perPage),
totalRows: sanitizeTotalRows(this.totalRows),
numberOfPages: this.numberOfPages
}
}
},
watch: {
numberOfPages(newVal) {
if (newVal === this.localNumberOfPages) {
/* istanbul ignore next */
return
pageSizeNumberOfPages(newVal, oldVal) {
if (!isUndefinedOrNull(oldVal)) {
if (newVal.perPage !== oldVal.perPage && newVal.totalRows === oldVal.totalRows) {
// If the page size changes, reset to page 1
this.currentPage = 1
} else if (
newVal.numberOfPages !== oldVal.numberOfPages &&
this.currentPage > newVal.numberOfPages
) {
// If `numberOfPages` changes and is less than
// the `currentPage` number, reset to page 1
this.currentPage = 1
}
}
this.localNumberOfPages = newVal
this.currentPage = 1
this.localNumberOfPages = newVal.numberOfPages
}
},
created() {
Expand Down
76 changes: 71 additions & 5 deletions src/components/pagination/pagination.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,15 @@ describe('pagination', () => {
wrapper.setProps({
totalRows: 4
})
await waitNT(wrapper.vm)

expect(wrapper.is('ul')).toBe(true)
expect(wrapper.findAll('li').length).toBe(8)

wrapper.setProps({
perPage: 2
})
await waitNT(wrapper.vm)

expect(wrapper.is('ul')).toBe(true)
expect(wrapper.findAll('li').length).toBe(6)
Expand Down Expand Up @@ -679,8 +681,8 @@ describe('pagination', () => {
wrapper.destroy()
})

it('changing the pagesize resets to page 1', async () => {
// https://github.com/bootstrap-vue/bootstrap-vue/issues/2987
it('changing the number of pages to less than current page number resets to page 1', async () => {
// https://github.com/bootstrap-vue/bootstrap-vue/issues/3716
const wrapper = mount(BPagination, {
propsData: {
totalRows: 10,
Expand All @@ -694,16 +696,79 @@ describe('pagination', () => {
expect(wrapper.vm.currentPage).toBe(10)
expect(wrapper.emitted('input')).not.toBeDefined()

// Change total rows to larger value. Should not change page number
wrapper.setProps({
totalRows: 20
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(10)
expect(wrapper.emitted('input')).not.toBeDefined()

// Change to page 20
wrapper.setProps({
value: 20
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(20)
expect(wrapper.emitted('input')).toBeDefined()
expect(wrapper.emitted('input').length).toBe(1)
expect(wrapper.emitted('input')[0][0]).toBe(20)

// Decrease number of pages should reset to page 1
wrapper.setProps({
totalRows: 10
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(1)
expect(wrapper.emitted('input').length).toBe(2)
expect(wrapper.emitted('input')[1][0]).toBe(1)

// Change to page 3
wrapper.setProps({
value: 3
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(3)
expect(wrapper.emitted('input').length).toBe(3)
expect(wrapper.emitted('input')[2][0]).toBe(3)

// Decrease number of pages to 5 should not reset to page 1
wrapper.setProps({
totalRows: 5
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(3)
expect(wrapper.emitted('input').length).toBe(3)

wrapper.destroy()
})

it('changing per-page resets to page 1', async () => {
// https://github.com/bootstrap-vue/bootstrap-vue/issues/2987
const wrapper = mount(BPagination, {
propsData: {
totalRows: 10,
perPage: 1,
value: 4,
limit: 20
}
})
expect(wrapper.isVueInstance()).toBe(true)

expect(wrapper.vm.currentPage).toBe(4)
expect(wrapper.emitted('input')).not.toBeDefined()

// Change perPage
wrapper.setProps({
perPage: 3
perPage: 2
})
await waitNT(wrapper.vm)
expect(wrapper.vm.currentPage).toBe(1)
expect(wrapper.emitted('input')).toBeDefined()
expect(wrapper.emitted('input').length).toBe(1)
expect(wrapper.emitted('input')[0][0]).toBe(1)

// Change to page 3
// Change page to 3
wrapper.setProps({
value: 3
})
Expand All @@ -712,7 +777,8 @@ describe('pagination', () => {
expect(wrapper.emitted('input').length).toBe(2)
expect(wrapper.emitted('input')[1][0]).toBe(3)

// Increasing number of pages should reset to page 1
// Change perPage. Should reset to page 1, even though
// current page is within range of numberOfPages
wrapper.setProps({
perPage: 1
})
Expand Down