1.0.1 • Published 7 years ago

express-paginatorjs v1.0.1

Weekly downloads
19
License
ISC
Repository
github
Last release
7 years ago

express-paginatorjs

Pagination module for express.js

Install

npm i express-paginatorjs

Basic usage with Express.js and express-handlebars

app.js: require

Misc dependencies: express-handlebars https://github.com/ericf/express-handlebars

const express = require('express')
const path = require('path')
const app = express()
// We need to have express-handlebars installed.
const hbs = require('express-handlebars')

app.js: Use Handlebars as the template engine and register helpers

// View engine setup
app.engine('hbs', hbs({
    extname: 'hbs',
    defaultLayout: 'layout',
    layoutsDir: __dirname + '/views/layouts/',
    helpers: {
        paginator: require('express-paginatorjs')
    }
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

app.js: Example routing with the paginator object that is required.

app.get('/posts', function (req, res, next) {
  res.render('index', {
      paginator: {
          limit: 10, // This key:value pair is required.
          defaultPage: 'posts', // This key:value pair defaults to 'posts' if not set.
          currentPage: req.params.page, // This key:value pair is required.
          totalPages: 20, // This key:value pair is required.
      }
  })
})

app.get('/posts/:page', function(req, res, next) {
  res.render('index', {
      paginator: {
          limit: 10, // This key:value pair is required.
          defaultPage: 'posts', // This key:value pair defaults to 'posts' if not set.
          currentPage: req.params.page, // This key:value pair is required.
          totalPages: 20, // This key:value pair is required.
      }
  })
})

index.hbs: Will output a default pagination based on bootstrap 4. https://v4-alpha.getbootstrap.com/components/pagination/

{{#paginator paginator}}
{{/paginator}}

index.hbs will output the following code block (active class will be automatically set on currentpage):

<nav aria-label="Page navigation">
  <ul class="pagination">
    <li class="page-item"><a class="page-link active" href="#">Previous</a></li>
    <li class="page-item"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
    <li class="page-item"><a class="page-link" href="#">Next</a></li>
  </ul>
</nav>

Customizing the output

In the handlebars file you can customize the pagination.

Limit

{{#paginator paginator limit="4"}}
{{/paginator}}

Type

customizing your own block of code that will be output. Example:

{{#if paginator}}
  <nav aria-label="page navigation">
    <ul class="pagination">
    
      {{#paginator paginator type="prev"}}
        <li class="page-item"><a class="page-link" href="{{prev}}">Previous</a></li>
      {{/paginator}}
      
      {{#paginator paginator type="links" limit="10"}}
        <li class="page-item {{#if active}}active{{/if}}"><a class="page-link" href="{{href}}">{{n}}</a></li>
      {{/paginator}}
      
      {{#paginator paginator type="next"}}
        <li class="page-item"><a class="page-link" href="{{next}}">Next</a></li>
      {{/paginator}}
      
    </ul>
  </nav>
{{/if}}
{{#paginator paginator type="prev"}}
  ...This renders the previous link. Make sure to use the {{href}} key so that it will link correctly.
{{/paginator}}
      
{{#paginator paginator type="links"}}
  ...This renders the list items with their numbers and correct links as long as you provide the {{href}}
  and {{n}} keys.
{{/paginator}}
      
{{#paginator paginator type="next"}}
  ...This renders the next link. Make sure to use the {{href}} key so that it will link correctly.
{{/paginator}}

Advanced usage with MySQL (or other Databases)

This module was created to make dynamic paginations for web apps that connects to databases that will provide them with content.

This is an example of a web app that connects to a database and retrieves blog posts from it.

app.js

'use strict';
const express = require('express')
const path = require('path')
const app = express()
// We need to have express-handlebars installed.
const hbs = require('express-handlebars')
// And we need to connect to our database.
const db = require('<location-of-file>')


// The paginator object is declared outside of the render scope:
let paginator = {};
paginator.limit = 10; // Set your default limit here.
paginator.defaultPage = 'posts'; // Set your default page here.

/**
 * Middleware function to create pages and to set paginator key: values.
 */
 
let pages = (req, res, next) => {

    let currentPage = parseInt(req.params.page) || 1;

    let sql = "SELECT COUNT(post_id) AS total FROM blog_posts";
    db.query(sql, function(err, result){
        if (err) next(err);
        
        // We can do the queries with the paginator values.
        // But this is useful when we don't have a paginator plugin.
        res.locals.currentPage = currentPage;
        res.locals.totalPages = Math.ceil(parseInt(result[0].total) / paginator.limit);
        res.locals.totalPosts = result[0].total;

        // Make the same variable accessible in the pagination object.
        paginator.totalPages = res.locals.totalPages;
        paginator.currentPage = req.params.page;

        next();
    });
}

app.get('/', pages, function(req, res, next) {
    let limit = paginator.limit;
    let offset = res.locals.totalPosts - (paginator.limit * res.locals.currentPage);

    let sql = "SELECT * FROM (SELECT *, DATE_FORMAT(post_published, '%Y-%m-%d') AS published FROM blog_posts LIMIT ? OFFSET ?) sub ORDER BY post_id DESC";

    db.query(sql, [limit, offset], function(err, rows) {
        if (err) next(err);
        res.render('posts', {
            posts: rows,
            paginator: paginator
        })
    });
});

app.get('/:page', pages, function(req, res, next) {

    // Only render pages that do have posts.
    if (res.locals.currentPage > res.locals.totalPages)
        return res.redirect('/posts');

    // If there are 100 posts. Page two will query post 90 to 81. Page three: 71 to 80.
    let limit = paginator.limit;
    let offset = res.locals.totalPosts - (paginator.limit * res.locals.currentPage);
    
    if (offset < 0) {
        limit += offset; // Algebraic double negative
        offset = 0;
    }

    let sql = "SELECT * FROM (SELECT *, DATE_FORMAT(post_published, '%Y-%m-%d') AS published FROM blog_posts LIMIT ? OFFSET ?) sub ORDER BY post_id DESC";

    db.query(sql, [limit, offset], function(err, rows) {
        if (err) next(err);
        res.render('posts', {
            posts: rows,
            paginator: paginator
        })
    });
});