Skip to content

Instantly share code, notes, and snippets.

@saqueib
Last active December 23, 2020 03:52
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save saqueib/0f14d87a4f44c4b9ffc3c65d905cb6b2 to your computer and use it in GitHub Desktop.
Save saqueib/0f14d87a4f44c4b9ffc3c65d905cb6b2 to your computer and use it in GitHub Desktop.
VueJS pagination component to paginate anything in Laravel, checkout the tutorial on http://wp.me/p8cmxL-b7 by www.qcode.in
<template>
<div :class="{'loading': loading}" class="pager-data-wrapper">
<!-- Pagination Slot -->
<slot :result="getResult()">
<div class="text-center alert-info pb-3">
<span v-if="!loading">
{{ result.length }} items found. render it using v-for="item in result"
</span>
<span v-if="loading">
Loading...
</span>
</div>
</slot>
<!-- Pagination links -->
<div class="pager-link text-center">
<div v-if="pagerType == 'paged'">
<a
v-show="result.length"
:disabled="!prevPageUrl || loading"
:href="prevPageUrl"
@click.prevent="prevPage"
:class="{loading: loading}"
class="btn btn-primary">Prev</a>
<a
:disabled="!nextPageUrl || loading"
:href="nextPageUrl"
@click.prevent="nextPage"
:class="{loading: loading}"
class="btn btn-primary">Next</a>
</div>
<button
v-if="pagerType == 'single'"
@click.prevent="nextPage"
class="btn btn-block btn-primary"
:class="{loading: loading}"
:disabled="loading || !nextPageUrl">
{{ loading ? 'Loading...' : moreBtnText }}
</button>
</div>
</div>
</template>
<script>
export default {
props: {
url: {
required: true
},
moreBtnText: {
type: String,
default: 'Load More...'
},
chunked: {
type: Number,
default: 0
},
prepend: {
default: null
},
apepend: {
default: null
},
pagerType: {
default: 'single'
}
},
data() {
return {
result: [],
loading: true,
nextPageUrl: null,
prevPageUrl: null,
prependData: null,
appendData: null
}
},
created() {
// load the data initially
this.fetchData();
},
methods: {
fetchData(url) {
let vm = this;
let endpoint = url ? url : this.url;
// show loader
vm.loading = true;
// fetch the data from passed url property
axios.get(endpoint).then((res) => {
// hide the loader
vm.loading = false;
// Assign returend data
if( url && vm.pagerType == 'single' ) {
// push next page into result
_.forEach(res.data.data, (item) => vm.result.push(item))
} else {
// add first page
vm.result = res.data.data;
}
// assigne next and prev page url
vm.nextPageUrl = res.data.next_page_url;
vm.prevPageUrl = res.data.prev_page_url;
}).catch((err) => {
vm.loading = false;
})
},
getResult() {
return (this.chunked > 0) ? _.chunk(this.result, this.chunked) : this.result;
},
prevPage() {
this.fetchData(this.prevPageUrl)
},
nextPage() {
this.fetchData(this.nextPageUrl)
}
},
watch: {
prepend(newVal) {
if( newVal ) {
this.prependData = newVal;
this.result.unshift(newVal);
}
this.prependData = null
},
append(newVal) {
if( newVal ) {
this.appendData = newVal;
this.result.push(newVal);
}
this.appendData = null
}
}
}
</script>
<style>
@-webkit-keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.btn.loading {
color: transparent !important;
pointer-events: none;
position: relative;
}
.btn.loading:after {
-webkit-animation: spinAround 500ms infinite linear;
animation: spinAround 500ms infinite linear;
border: 2px solid #dbdbdb;
border-radius: 290486px;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
height: 1em;
position: relative;
width: 1em;
position: absolute;
left: calc(50% - (1em / 2));
top: calc(50% - (1em / 2));
position: absolute !important;
border-color: transparent transparent #fff #fff !important;
}
.pb-3 {
margin-bottom: 3rem
}
.alert-info {
padding: 1rem
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment