Further work on VPaginator component

This commit is contained in:
Sockenklaus
2021-11-09 23:53:56 +01:00
parent 1abb63f57d
commit 856c81fdf3
3 changed files with 88 additions and 35 deletions

View File

@@ -1,42 +1,62 @@
<template> <template>
<nav aria-label="Page navigation" class="d-flex align-items-center justify-content-between"> <nav aria-label="Page navigation" class="d-flex flex-row align-items-center justify-content-between">
<ul class="pagination" > <ul class="pagination" >
<li class="page-item" :class="{disabled: isFirstPage}"> <li class="page-item" :class="{disabled: isFirstPage}">
<button class="page-link" @click="setPage(store.meta.first_page)"> <button class="page-link" @click="decPage()">
<i class="bi bi-caret-left" /> <i class="bi bi-caret-left" />
Anfang
</button> </button>
</li> </li>
<li v-for="page in displayedPages" class="page-item" :class="{active: page == store.page}"> <li class="page-item" :class="{active: isFirstPage}">
<button class="page-link" @click="setPage(props.firstPage)">
{{props.firstPage}}
</button>
</li>
<li class="page-item disabled" v-if="showLeftSeperator">
<span class="page-link">...</span>
</li>
<template v-for="page in displayedPages">
<li v-if="showPage(page)" class="page-item" :class="{active: classPageActive(page)}">
<button class="page-link" @click="setPage(page)"> <button class="page-link" @click="setPage(page)">
{{ page }} {{ page }}
</button> </button>
</li> </li>
</template >
<li class="page-item" :class="{disabled: isLastPage}" @click="setPage(store.meta.last_page)"> <li class="page-item disabled" v-if="showRightSeperator">
<span class="page-link">...</span>
</li>
<li v-if="!hasOnlyOnePage" class="page-item" :class="{active: isLastPage}" @click="setPage(props.lastPage)">
<button class="page-link"> <button class="page-link">
Ende {{props.lastPage}}
</button>
</li>
<li class="page-item" :class="{disabled: isLastPage}">
<button class="page-link" @click="incPage()">
<i class="bi bi-caret-right" /> <i class="bi bi-caret-right" />
</button> </button>
</li> </li>
</ul> </ul>
<div> <div class="ms-auto pe-2">
Seite Seite
<input type="text" class="form-control inline" :value="store.page" @input="setPage($event.target?.value)"> </div>
von {{ store.meta.last_page }} <div>
<input size="1" type="text" class="form-control form-control-sm" :value="props.page" @input="setPage($event.target?.value)">
</div>
<div class="ms-2">
von {{ props.lastPage }}
</div> </div>
</nav> </nav>
{{displayedPages}}
<br>
{{store.page}}
{{typeof store.page}}
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -47,15 +67,41 @@ import _inRange from 'lodash/inRange'
const store = useEmployees() const store = useEmployees()
const isFirstPage = computed(() => store.page <= store.meta.first_page) const props = defineProps({
const isLastPage = computed(() => store.page >= store.meta.last_page) radius: {
type: Number,
default: 2
},
page: {
type: Number,
default: 1
},
firstPage: {
type: Number,
default: 1
},
lastPage: {
type: Number,
default: 1
}
})
const emit = defineEmits([
'setPage'
])
const isFirstPage = computed(() => props.page <= props.firstPage)
const isLastPage = computed(() => props.page >= props.lastPage)
const showLeftSeperator = computed(() => props.page - props.radius - 1 > props.firstPage)
const showRightSeperator = computed(() => props.page + props.radius + 1 < props.lastPage)
const showPage = (page : number) => page !== props.firstPage && page !== props.lastPage
const classPageActive = (page : number) => page === props.page
const hasOnlyOnePage = computed(() => props.lastPage === props.firstPage)
const displayedPages = computed(() => { const displayedPages = computed(() => {
const radius = 1
const pages = [] const pages = []
const currentPage = store.page const firstPage = props.page - props.radius > props.firstPage ? props.page - props.radius : props.firstPage
const firstPage = currentPage - radius > store.meta.first_page ? currentPage - radius : store.meta.first_page const lastPage = store.page + props.radius < props.lastPage ? props.page + props.radius : props.lastPage
const lastPage = currentPage + radius < store.meta.last_page ? currentPage + radius : store.meta.last_page
for (let i = firstPage; i <= lastPage; i++) { for (let i = firstPage; i <= lastPage; i++) {
pages.push(i) pages.push(i)
@@ -65,24 +111,21 @@ const displayedPages = computed(() => {
}) })
function incPage() { function incPage() {
if(store.page < store.meta.last_page) { if(props.page < props.lastPage) {
store.setPage(store.page + 1) emit('setPage', props.page + 1)
} }
} }
function decPage(){ function decPage(){
if(store.page > store.meta.first_page) { if(props.page > props.firstPage) {
store.setPage( store.page - 1) emit('setPage', props.page - 1)
} }
} }
function setPage(page: number) { function setPage(page: number) {
if(_inRange(page, store.meta.first_page, store.meta.last_page+1)) { if(_inRange(page, props.firstPage, props.lastPage+1)) {
store.setPage(page) emit('setPage', page)
} }
} }
</script> </script>
<style scoped> <style scoped>

View File

@@ -23,7 +23,7 @@ export const useEmployees = defineStore('employees', {
columns: Array<string>(), columns: Array<string>(),
limit: 1, limit: 10,
page: 1, page: 1,
sort_by: '', sort_by: '',
simple_search: '' simple_search: ''

View File

@@ -26,7 +26,13 @@
<h5 v-show="rows.length === 0" class="text-muted">Keine Daten anzuzeigen...</h5> <h5 v-show="rows.length === 0" class="text-muted">Keine Daten anzuzeigen...</h5>
<VPaginator /> <VPaginator
:radius="1"
:page="store.page"
:first-page="store.meta.first_page"
:last-page="store.meta.last_page"
@set-page="paginatorSetPage"
/>
</template> </template>
@@ -69,6 +75,10 @@ const iconSort = computed(() => {
return 'bi-sort-' + (sort_by.asc ? 'down' : 'up')+'-alt' return 'bi-sort-' + (sort_by.asc ? 'down' : 'up')+'-alt'
}) })
function paginatorSetPage(e : number){
store.setPage(e)
}
</script> </script>
<style scoped> <style scoped>