Created
May 29, 2017 08:18
-
-
Save Strae/4b4549733c958a1229a7e3bf1a9511a1 to your computer and use it in GitHub Desktop.
Dead simple Vuejs paginator component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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">«</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">»</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