Skip to content

Instantly share code, notes, and snippets.

@rootchips
Created October 10, 2023 01:49
Show Gist options
  • Save rootchips/7e6f948d461b1c9867d6675d2c0c632f to your computer and use it in GitHub Desktop.
Save rootchips/7e6f948d461b1c9867d6675d2c0c632f to your computer and use it in GitHub Desktop.
Pagination
<template>
<nav v-if="pagination && pagination.totalItems" class="flex items-center justify-between pt-4" aria-label="Table navigation">
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">Showing <span
class="font-semibold text-gray-900 dark:text-white">{{ pagination?.startIndex + 1 }} - {{ pagination?.endIndex + 1
}}</span> of <span class="font-semibold text-gray-900 dark:text-white">{{ pagination?.totalItems }}</span></span>
<ul class="inline-flex items-center -space-x-px">
<li>
<a href="#"
@click="pagination?.currentPage !== pagination?.startPage ? setPage(pagination?.currentPage - 1) : $event.preventDefault()"
:class="{ 'z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white' : pagination?.currentPage === 1 }"
class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
<span class="sr-only">Previous</span>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"></path>
</svg>
</a>
</li>
<li v-for="page in pagination?.pages" :key="page">
<a href="#"
@click="pagination?.currentPage !== page ? setPage(page) : $event.preventDefault()"
:class="{ 'z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white' : pagination?.currentPage == page,
'px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white' : pagination?.currentPage !== page
}">{{ page }}</a>
</li>
<li>
<a href="#"
@click="pagination?.currentPage !== pagination?.endPage ? setPage(pagination?.currentPage + 1) : $event.preventDefault()"
:class="{ 'z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white' : pagination?.currentPage === pagination?.totalPages }"
class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
<span class="sr-only">Next</span>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"></path>
</svg>
</a>
</li>
</ul>
</nav>
</template>
<script setup>
const props = defineProps(['pagination'])
const emit = defineEmits(['refreshData'])
let pager = ref(null)
const pagination = computed(() => {
return pager.value
})
const setPage = (page, index = true) => {
pager.value = paginate(props.pagination, page, 10, 15)
if (index == true) {
emit('refreshData', {
page: page
})
}
}
const paginate = (totalItems, currentPage, pageSize, maxPages) => {
if (currentPage === void 0) { currentPage = 1 }
if (pageSize === void 0) { pageSize = 10 }
if (maxPages === void 0) { maxPages = 10 }
var totalPages = Math.ceil(totalItems / pageSize)
if (currentPage < 1) {
currentPage = 1
}
else if (currentPage > totalPages) {
currentPage = totalPages
}
var startPage, endPage
if (totalPages <= maxPages) {
// total pages less than max so show all pages
startPage = 1
endPage = totalPages;
} else {
var maxPagesBeforeCurrentPage = Math.floor(maxPages / 2)
var maxPagesAfterCurrentPage = Math.ceil(maxPages / 2) - 1
if (currentPage <= maxPagesBeforeCurrentPage) {
startPage = 1
endPage = maxPages
} else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
startPage = totalPages - maxPages + 1
endPage = totalPages
} else {
startPage = currentPage - maxPagesBeforeCurrentPage
endPage = currentPage + maxPagesAfterCurrentPage
}
}
var startIndex = (currentPage - 1) * pageSize
var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1)
var pages = Array.from(Array((endPage + 1) - startPage).keys()).map(function (i) { return startPage + i; })
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages
}
}
defineExpose({
setPage
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment