parsley/app/javascript/components/AppPager.vue

100 lines
2.4 KiB
Vue
Raw Normal View History

2018-04-03 18:31:20 -05:00
<template>
<nav v-show="totalPages > 1" class="pagination" role="navigation" :aria-label="pagedItemName + ' page navigation'">
<a class="pagination-previous" :title="isFirstPage ? 'This is the first page' : ''" :disabled="isFirstPage" @click.prevent="changePage(currentPage - 1)">Previous</a>
<a class="pagination-next" :title="isLastPage ? 'This is the last page' : ''" :disabled="isLastPage" @click.prevent="changePage(currentPage + 1)">Next page</a>
<ul class="pagination-list">
<li v-for="page in pageItems" :key="page">
<a v-if="page > 0" class="pagination-link" :class="{'is-current': page === currentPage}" href="#" @click.prevent="changePage(page)">{{page}}</a>
<span v-else class="pagination-ellipsis">&hellip;</span>
</li>
</ul>
</nav>
</template>
<script>
export default {
props: {
pagedItemName: {
required: false,
type: String,
default: ''
},
currentPage: {
required: true,
type: Number
},
totalPages: {
required: true,
type: Number
},
pageWindow: {
required: false,
type: Number,
default: 4
},
pageOuterWindow: {
required: false,
type: Number,
default: 1
}
},
computed: {
pageItems() {
const items = new Set();
for (let x = 0; x < this.pageOuterWindow; x++) {
items.add(x + 1);
items.add(this.totalPages - x);
}
const start = this.currentPage - Math.ceil(this.pageWindow / 2);
const end = this.currentPage + Math.floor(this.pageWindow / 2);
for (let x = start; x <= end; x++) {
items.add(x);
}
let emptySpace = -1;
const finalList = [];
[...items.values()].filter(p => p > 0 && p <= this.totalPages).sort((a, b) => a - b).forEach((p, idx, list) => {
finalList.push(p);
if (list[idx + 1] && list[idx + 1] !== p + 1) {
finalList.push(emptySpace--);
}
});
return finalList;
},
isLastPage() {
return this.currentPage === this.totalPages;
},
isFirstPage() {
return this.currentPage === 1;
}
},
methods: {
changePage(idx) {
this.$emit("changePage", idx);
}
}
}
</script>
<style lang="scss" scoped>
ul.pagination {
}
</style>