Skip to content

Instantly share code, notes, and snippets.

@kirilkirkov
Last active January 30, 2020 11:47
Show Gist options
  • Save kirilkirkov/73e328bf55631663be81e28afb53e605 to your computer and use it in GitHub Desktop.
Save kirilkirkov/73e328bf55631663be81e28afb53e605 to your computer and use it in GitHub Desktop.
JS Pagination Class Module for Vuejs Components
export default class Pagination {
constructor(vm, limit, total, page_param_name) {
this.vm = vm
this.limit = parseInt(limit)
this.total = parseInt(total)
this.page_param_name = page_param_name
this.setMaxPagesToShow(5)
this.setDefaultStyles()
this.setNumberOfPages()
}
/**
* Default styles are from
* tailwindcss.com
*/
setDefaultStyles()
{
this.nextBtnClasses = 'bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white h-10 w-16 flex items-center justify-center ml-4 border border-blue-500 hover:border-transparent rounded'
this.prevBtnClasses = 'bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white h-10 w-16 flex items-center justify-center border border-blue-500 hover:border-transparent rounded'
this.pageBtnNoHoverClasses = 'bg-transparent hover:bg-blue-500 text-blue-700 hover:text-white border border-blue-500 hover:border-transparent'
this.pageBtnHoverClasses = 'bg-blue-500 hover:bg-blue-700 text-white'
this.mainContainerClasses = '-ml-4 flex'
this.dotsClasses = 'ml-4 h-10 w-4 flex items-end justify-center'
this.pageBtnDefaultClasses = 'rounded-full h-10 w-10 flex items-center justify-center'
this.mainLiClasses = 'ml-4'
}
setNextBtnClasses(classes)
{
this.nextBtnClasses = classes
return this
}
setPrevBtnClasses(classes)
{
this.prevBtnClasses = classes
return this
}
setPageBtnNoHoverClasses(classes)
{
this.pageBtnNoHoverClasses = classes
return this
}
setPageBtnHoverClasses(classes)
{
this.pageBtnHoverClasses = classes
return this
}
setMainContainerClasses(classes)
{
this.mainContainerClasses = classes
return this
}
setDotsClasses(classes)
{
this.dotsClasses = classes
return this
}
setPageBtnDefaultClasses(classes)
{
this.pageBtnDefaultClasses = classes
return this
}
setMainLiClasses(classes)
{
this.mainLiClasses = classes
return this
}
setNumberOfPages()
{
this.numberOfPages = Math.ceil(this.total / this.limit)
}
getLastPage()
{
return this.numberOfPages
}
setMaxPagesToShow(maxPagesToShow)
{
this.maxPagesToShow = maxPagesToShow
return this
}
getMaxPagesToShow()
{
return this.maxPagesToShow
}
getPaginationLinks()
{
let el_pagination = document.createElement('ul')
el_pagination.setAttribute('class', this.mainContainerClasses)
let i
let count = 0
let add_dots_after_first_page = false
for (i = this.vm.$route.params[this.page_param_name]; i <= this.getLastPage(); i++) {
let isActive = false
if(i == this.vm.$route.params[this.page_param_name]) {
isActive = true
}
if(count == 1 && this.vm.$route.params[this.page_param_name] > this.getMaxPagesToShow()) {
add_dots_after_first_page = true
}
let createdLi = this.createList(i, isActive)
el_pagination.appendChild(createdLi)
count++
if(count == this.getMaxPagesToShow()) {
break;
}
}
/**
* Add dots before last page
*/
if(i < this.getLastPage()) {
let createdLastLi = this.createList(this.getLastPage(), false, true)
let listDots = this.createDots()
el_pagination.appendChild(listDots)
el_pagination.appendChild(createdLastLi)
}
/**
* Add dots before first page
*/
if(add_dots_after_first_page === true) {
let createdFirstLi = this.createList(1, false, true)
let listDots = this.createDots()
el_pagination.prepend(listDots)
el_pagination.prepend(createdFirstLi)
}
if(this.getHasNextPage()) {
let createdNextButton = this.createNextButton()
el_pagination.appendChild(createdNextButton)
}
if(this.getHasPrevPage()) {
let createdPrevButton = this.createPrevButton()
el_pagination.prepend(createdPrevButton)
}
return el_pagination
}
createNextButton()
{
let createLi = document.createElement('li')
let createdNextPage = document.createElement('a')
createdNextPage.setAttribute('class', this.nextBtnClasses)
createdNextPage.innerText = 'Next'
createdNextPage.setAttribute('href', 'javascript:;')
createdNextPage.addEventListener('click', (e) => this.setNextPage())
createLi.appendChild(createdNextPage)
return createLi
}
setNextPage()
{
let nextPage = parseInt(this.vm.$route.params[this.page_param_name]) + 1
this.setPage(nextPage)
}
createPrevButton()
{
let createLi = document.createElement('li')
let createdPrevPage = document.createElement('a')
createdPrevPage.setAttribute('class', this.prevBtnClasses)
createdPrevPage.innerText = 'Prev'
createdPrevPage.setAttribute('href', 'javascript:;')
createdPrevPage.addEventListener('click', (e) => this.setPrevPage())
createLi.appendChild(createdPrevPage)
return createLi
}
setPrevPage()
{
let nextPage = parseInt(this.vm.$route.params[this.page_param_name]) - 1
this.setPage(nextPage)
}
createDots()
{
let createLastLi = document.createElement('li')
let dots = document.createElement('span')
dots.setAttribute('class', this.dotsClasses)
dots.innerText = '...'
createLastLi.appendChild(dots)
return createLastLi
}
createList(page_num, isActive = false)
{
let createLi = document.createElement('li')
createLi.setAttribute('class', this.mainLiClasses)
let createA = document.createElement('a')
createA.setAttribute('href', 'javascript:;')
let bgColor = this.pageBtnNoHoverClasses
if(isActive !== false) {
bgColor = this.pageBtnHoverClasses
}
createA.addEventListener('click', (e) => this.setPage(page_num))
createA.setAttribute('class', bgColor + ' ' + this.pageBtnDefaultClasses)
createA.innerText = page_num
createLi.appendChild(createA)
return createLi
}
setPage(page_num)
{
let new_query_params = this.vm.$route.params
new_query_params[this.page_param_name] = page_num
if(typeof this.vm.$route.name === 'undefined') {
throw 'Route doesnt have name'
}
this.vm.$router.push({name: this.vm.$route.name, query: this.vm.$route.query, params: new_query_params}).catch(err => {
throw err
})
}
getHasNextPage()
{
return this.vm.$route.params[this.page_param_name] !== this.getLastPage()
}
getHasPrevPage()
{
return this.vm.$route.params[this.page_param_name] > 1
}
getOffset()
{
return (this.vm.$route.params[this.page_param_name] - 1) * this.limit
}
}
@kirilkirkov
Copy link
Author

kirilkirkov commented Jan 14, 2020

Example usage:

new Pagination(this, limit, total, 'page')

  • this - Component instance
  • limit - Limit of the results per page
  • total - Total results count
  • 'page' - String with name of the router param with page
methods: {
       getPaginationLinks()
                {
                   let pagination = new Pagination(this, this.results.limit, this.results.total, 'page')
                   let pagination_links = pagination.setMaxPagesToShow(5).getPaginationLinks()
             
                   let paginationContainer = document.getElementById('pagination')
                   paginationContainer.innerHTML = ''
                   paginationContainer.appendChild(pagination_links)

                   this.offset = pagination.getOffset()
               }
},
watch:{
        $route(to, from){
            getPaginationLinks() // For example if instance is in getPaginationLinks() function
        },
        offset: function (newValue, oldValue) {
            this.getAlbumResults()
        },
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment