Files
SAFEKISO/inspond-nuxt-safekiso/base/components/BasePagination1.vue
2026-04-07 14:50:23 +09:00

290 lines
11 KiB
Vue

<template>
<div
class="pt-5 px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6"
>
<div class="flex-1 flex justify-between sm:hidden">
<a
href="#"
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:text-gray-500"
>
Previous
</a>
<a
href="#"
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:text-gray-500"
>
Next
</a>
</div>
<div
class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between"
>
<div>
<p class="text-sm text-gray-700">
Showing
<span class="font-medium">{{ showingFrom }}</span>
to
<span class="font-medium">{{ showingTo }}</span>
of
<span class="font-medium">{{ recordsTotal }}</span>
results
</p>
</div>
<div>
<nav
class="relative z-0 inline-flex shadow-sm -space-x-px"
aria-label="Pagination"
>
<a
href="javascript:void(0)"
class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
@click="gotoPage('first', 0)"
>
<span class="sr-only">First</span>
<!-- Heroicon name: chevron-double-left -->
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
></path>
</svg>
</a>
<a
href="javascript:void(0)"
class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
@click="gotoPage('prev', 0)"
>
<span class="sr-only">Previous</span>
<!-- Heroicon name: chevron-left -->
<svg
class="h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<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"
/>
</svg>
</a>
<a
v-for="(item, index) in currentSlots"
:key="index"
href="javascript:void(0)"
:class="
currentSlots[index] == currentPageNumber
? 'bg-gray-200'
: 'bg-white'
"
class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50"
@click="gotoPage(currentSlots[index], index)"
>
{{ currentSlots[index] }}
</a>
<a
href="javascript:void(0)"
class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
@click="gotoPage('next', 0)"
>
<span class="sr-only">Next</span>
<!-- Heroicon name: chevron-right -->
<svg
class="h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<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"
/>
</svg>
</a>
<a
href="javascript:void(0)"
class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
@click="gotoPage('last', 0)"
>
<span class="sr-only">Last</span>
<!-- Heroicon name: chevron-double-right -->
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 5l7 7-7 7M5 5l7 7-7 7"
></path>
</svg>
</a>
</nav>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {
ChevronLeftIcon,
ChevronRightIcon,
} from '@heroicons/vue/solid/index.js';
import { computed } from 'vue';
const props = defineProps({
totalPageCount: { type: Number, default: 1 },
currentPageNumber: { type: Number, default: 1 },
pageSize: { type: Number, default: 10 },
recordsTotal: { type: Number, default: 0 },
pageMove: { type: Function, required: true },
});
const pagenationSize = 5;
//console.log(props);
const showingFrom = computed(() => {
const result = 1 + (props.currentPageNumber - 1) * props.pageSize;
return result;
});
//console.log(showingFrom.value);
const showingTo = computed(() => {
let result = props.currentPageNumber * props.pageSize;
if (result > props.recordsTotal) {
result = props.recordsTotal;
}
return result;
});
const currentSlots = computed(() => {
const result: string[] = [];
if (props.totalPageCount > pagenationSize) {
if (props.currentPageNumber < Math.ceil(pagenationSize / 2)) {
for (let i = 1; i < pagenationSize; i++) {
// good for 3, 4, ....
result.push(i.toString());
}
result.push('...');
} else if (
props.currentPageNumber >
props.totalPageCount - pagenationSize / 2
) {
result.push('...');
for (
let i = props.totalPageCount - pagenationSize + 1;
i <= props.totalPageCount;
i++
) {
// good for 3, 4, ....
result.push(i.toString());
}
} else {
result.push('...');
for (
let i =
props.currentPageNumber - Math.floor(pagenationSize / 2);
i < props.currentPageNumber + Math.ceil(pagenationSize / 2);
i++
) {
// good for 3, 4, ....
result.push(i.toString());
}
result.push('...');
}
} else {
for (let i = 1; i <= props.totalPageCount; i++) {
result.push(i.toString());
}
}
//console.log('result = ', result);
return result;
});
function gotoPage(target, opt) {
//console.log('gotoPage, target=', target);
let targetPageIndex = props.currentPageNumber;
switch (target) {
case 'first':
targetPageIndex = 1;
break;
case 'prev':
if (props.currentPageNumber > 1) {
targetPageIndex = props.currentPageNumber - 1;
} else {
targetPageIndex = props.currentPageNumber;
}
break;
case 'next':
if (props.totalPageCount > props.currentPageNumber) {
targetPageIndex = props.currentPageNumber + 1;
} else {
targetPageIndex = props.currentPageNumber;
}
break;
case 'last':
targetPageIndex = props.totalPageCount;
break;
case '...':
if (opt == 0) {
if (props.currentPageNumber - pagenationSize > 0) {
targetPageIndex = props.currentPageNumber - pagenationSize;
} else {
targetPageIndex = 1;
}
} else {
if (
props.currentPageNumber + pagenationSize <
props.totalPageCount
) {
targetPageIndex = props.currentPageNumber + pagenationSize;
} else {
targetPageIndex = props.totalPageCount;
}
}
break;
default:
const tmpPageIdx = parseInt(target);
if (tmpPageIdx >= 1 && tmpPageIdx <= props.totalPageCount) {
targetPageIndex = tmpPageIdx;
} else {
targetPageIndex = props.currentPageNumber;
}
}
//console.log('final targetPageIdex = ', targetPageIndex);
// console.log('huk', this);
// this.$parent.pageMove(targetPageIndex);
// $emit('pageMove', targetPageIndex);
props.pageMove(targetPageIndex);
}
</script>