Skip to content

Instantly share code, notes, and snippets.

@Strae
Created May 29, 2017 08:18
Show Gist options
  • Save Strae/4b4549733c958a1229a7e3bf1a9511a1 to your computer and use it in GitHub Desktop.
Save Strae/4b4549733c958a1229a7e3bf1a9511a1 to your computer and use it in GitHub Desktop.
Dead simple Vuejs paginator component
<template>
<nav v-if="0 < numResults" class="float pagination" aria-label="Page navigation">
<ul class="pagination">
<li v-if="show_prev">
<a href="#" class="no-underline" aria-label="First" v-on:click="first()">
<span aria-hidden="true">[1]</span>
</a>
</li>
<li v-if="show_prev">
<a href="#" class="no-underline" aria-label="Previous" v-on:click="prev()">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
<li v-for="(n, idx) in pages"
:key="n"
:idx="idx"
>
<span v-if="n === currPage">{{n}}</span>
<a v-if="n !== currPage" href="#" v-on:click="page(n)">{{n}}</a>
</li>
<li v-if="show_next">
<a href="#" class="no-underline" aria-label="Next" v-on:click="next()">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
<li v-if="show_next">
<a href="#" class="no-underline" aria-label="Last" v-on:click="last()">
<span aria-hidden="true">[{{num_pages}}]</span>
</a>
</li>
</ul>
<span class="info-block">
Show results from <b>{{firstResult}}</b> to <b>{{lastResult}}</b> of <b>{{numResults}}</b>
</span>
</nav>
</template>
<script>
"use strict"
import debounce from 'lodash/debounce'
/**
* Author: Daniele P. <[email protected]>
* License: MIT
* Dead-simple Vuejs paginator that do not require the full object list - just give it:
* - how many items we have [numResults, int]
* - how many items are displayed on the page [itemsPerPage, int]
* - the current page [currPage, int]
* - how many page links we want for each side [numLinks, int]
* - and obviously the callback to change pages [handleClick, fn]
**/
const Paginator = {
props: [ 'numResults', 'currPage', 'numLinks', 'handleClick', 'itemsPerPage' ],
data: function () {
return {
show_prev: false,
show_next: false,
num_pages: 0,
pages: []
};
},
watch: {
numResults: function( newVal, oldVal ) {
if ( newVal !== oldVal ) {
this.doTheMath();
}
},
currPage: function( newVal, oldVal ) {
if ( newVal !== oldVal ) {
this.doTheMath();
}
},
itemsPerPage: function( newVal, oldVal ) {
if ( newVal !== oldVal ) {
this.doTheMath();
}
},
},
computed: {
firstResult () {
return ( ( this.$props.currPage - 1 ) * this.$props.itemsPerPage ) + 1;
},
lastResult () {
return this.$props.currPage * this.$props.itemsPerPage > this.$props.numResults ? this.$props.numResults : this.$props.currPage * this.$props.itemsPerPage;
},
},
methods: {
next () {
this.page( this.$props.currPage + 1 );
},
prev () {
this.page( this.$props.currPage - 1 );
},
first () {
this.page( 1 );
},
last () {
this.page( this.num_pages );
},
page: debounce( function( num ){ this.$props.handleClick( num ); }, 150),
doTheMath () {
let first_page, last_page, i = 0;
// Calculate range of pages to show to.
this.num_pages = Math.ceil( this.$props.numResults / parseInt( this.$props.itemsPerPage ) );
first_page = this.$props.currPage - parseInt( this.$props.numLinks );
last_page = this.$props.currPage + parseInt( this.$props.numLinks ) + 1;
if ( first_page < 1 ) {
first_page = 1;
}
if ( last_page > this.num_pages ) {
last_page = this.num_pages;
}
this.show_prev = 1 !== first_page ? true : false;
this.show_next = last_page !== this.num_pages ? true : false;
this.pages = [];
for( i = first_page; i != ( last_page + 1 ); i++ ) {
this.pages.push( i );
}
}
}
};
export default Paginator;
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment