Further work on VPaginator component
This commit is contained in:
@@ -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(page)">
|
<button class="page-link" @click="setPage(props.firstPage)">
|
||||||
{{ page }}
|
{{props.firstPage}}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="page-item" :class="{disabled: isLastPage}" @click="setPage(store.meta.last_page)">
|
<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)">
|
||||||
|
{{ page }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</template >
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -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: ''
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user