Skip to content

Instantly share code, notes, and snippets.

@mauro-baptista
Last active May 15, 2020 23:52
Show Gist options
  • Save mauro-baptista/07ff90da32c66bb84b15de45940b73ed to your computer and use it in GitHub Desktop.
Save mauro-baptista/07ff90da32c66bb84b15de45940b73ed to your computer and use it in GitHub Desktop.
Using Laravel Pagination with IntertiaJS

Description

This is a simple implementation of the Laravel pagination using InertiaJS without having to create a custom LengthAwarePaginator class.

I've built it to match my needs, therefore you can find it limited to your purpose, so fill free to modify it as it suits your! :)

@carnou

Mauro Baptista

How to use it:

  1. Copy and paste the component Pagination into your project.
  2. Where you have a paginate result, import the Pagination component into it, and then add the following props:

Items:

Item Is required? Type Description
current-page yes Number
last-page yes Number
path yes String Base path for the pagination link
query no Object Items to be added in the query

Sample usage:

<Pagination
    :current-page="posts.current_page"
    :last-page="posts.last_page"
    :path="posts.path"
    :query="{test: 'hi', another: 'test'}"
/>

Output: http://localhost:3000/dashboard/posts?test=hi&another=test&page=7

<template>
<div v-if="hasPages" class="mx-auto mb-4">
<ul>
<li v-if="onFirstPage" class="inline-block p-2 bg-transparent mx-1 rounded text-gray-400">
<span aria-hidden="true">&lsaquo;</span>
</li>
<li v-else class="inline-block p-2 bg-transparent mx-1 rounded text-gray-700">
<inertia-link :href="previousPageUrl" rel="prev">&lsaquo;</inertia-link>
</li>
<template v-for="element in elements()">
<li v-if="typeof element === 'string'" class="inline-block p-2 bg-transparent mx-1 rounded text-gray-400">
<span>{{ element }}</span>
</li>
<template v-if="typeof element === 'object'">
<li v-if="element.page === currentPage" class="inline-block p-2 bg-transparent mx-1 rounded font-bold bg-gray-300">
<span>{{ element.page }}</span>
</li>
<li v-else class="inline-block p-2 bg-transparent mx-1 rounded border-gray-500">
<inertia-link :href="element.url">{{ element.page }}</inertia-link>
</li>
</template>
</template>
<li v-if="hasMorePages" class="inline-block p-2 bg-transparent mx-1 rounded text-gray-700">
<inertia-link :href="nextPageUrl" rel="next">&rsaquo;</inertia-link>
</li>
<li v-else class="inline-block p-2 bg-transparent mx-1 rounded text-gray-400">
<span aria-hidden="true">&rsaquo;</span>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
lastPage: {
type: Number,
required: true,
},
currentPage: {
type: Number,
required: true,
},
path: {
type: String,
required: true,
},
query: {
type: Object,
default: () => {},
},
},
computed: {
hasPages: function () {
return this.lastPage > 1
},
onFirstPage: function () {
return this.currentPage === 1
},
hasMorePages: function () {
return this.currentPage < this.lastPage
},
previousPageUrl: function () {
return this.url(this.currentPage - 1)
},
nextPageUrl: function () {
return this.url(this.currentPage + 1)
},
},
methods: {
url: function(page) {
let urlParams = new URLSearchParams();
for (let index in this.query) {
if (this.query.hasOwnProperty(index)) {
urlParams.append(index, this.query[index]);
}
}
page = (page <= 0) ? 1 : page
page = (page >= this.lastPage) ? this.lastPage : page
urlParams.append('page', page);
return this.path + '?' + urlParams.toString();
},
elements: function () {
let elements = [];
for (let page = 1; page <= this.lastPage; page++) {
elements.push({
page: page,
url: this.url(page),
});
}
return elements;
}
}
}
</script>
<template>
<div>
<Pagination
:current-page="posts.current_page"
:last-page="posts.last_page"
:path="posts.path"
:query="{test: 'abc', mais: '123'}"
/>
</div>
</template>
<script>
import Pagination from './Pagination'
export default {
metaInfo: { title: 'Posts' },
components: {
Pagination,
},
props: {
posts: Object,
},
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment