pagination.js 5.71 KB
/**
 * 分页组件
 * @author: djh<jinhu.dong@yoho.cn>
 * @date: 2016/6/29
 */

'use strict';

// render pagination ellipse indicator
function _renderEllipse(templateStr) {
    return templateStr + '<a>...</a>';
}

// render last page link
function _renderLastPage(templateStr, pageCount, queryParams) {
    return templateStr + '<a href="?page=' + pageCount + queryParams + '">' + pageCount + '</a>';
}

/*
 * Pagination Component
 * @param { Object } pagination pagination constructor
 * --- pagination ---
 * @param { Integer } limit: per page records number
 * @param { String } leftText: prev button text, default is iconfont
 * @param { String } rightText: next button text, default is iconfont
 * @param { String } paginationClass: pagination ul class, default is 'blk-pagination'
 */

module.exports = function(pagination, options) {
    // default options
    var limit = 9,                                      // display links number
        n,                                              // page number ?page=n
        queryParams = '',                               // paginate with query parameter
        page = parseInt(pagination.page, 10),           // current page number
        leftText = '<i class="iconfont">&#xe607;</i>',  // prev
        rightText = '<i class="iconfont">&#xe61e;</i>', // next
        paginationClass = 'blk-pagination';             // pagination <ul> default class

    var pageCount,
        key,                                            // query params key
        lastCharacterOfQueryParams;

    var i,                                              // iterator for each refresh page
        leftCount,                                      // left pagination link counts for current position
        rightCount,                                     // right pagination link counts for current position
        start;                                          // left first link number

    var template;

    if (!pagination || pagination.pageTotal === 1) {
        return '';
    }

    // custome options
    if (options.hash.limit) {
        limit = +options.hash.limit;
    }

    if (options.hash.leftText) {
        leftText = options.hash.leftText;
    }

    if (options.hash.rightText) {
        rightText = options.hash.rightText;
    }

    if (options.hash.paginationClass) {
        paginationClass = options.hash.paginationClass;
    }

    pageCount = Math.ceil(pagination.total / pagination.limit);

    // query params
    if (pagination.queryParams) {
        queryParams = '&';
        for (key in pagination.queryParams) {
            if (pagination.queryParams.hasOwnProperty(key) && key !== 'page') {
                queryParams += key + '=' + pagination.queryParams[key] + '&';
            }
        }

        // lastCharacterOfQueryParams = queryParams.substring(queryParams.length, -1);
        lastCharacterOfQueryParams = queryParams.slice(queryParams.length - 1);

        if (lastCharacterOfQueryParams === '&') {
            // trim off last & character
            queryParams = queryParams.slice(0, queryParams.length - 1);
        }
    }

    queryParams = encodeURI(queryParams);

    template = '<div class="' + paginationClass + '">';

    // ========= Previous Button ===============
    if (page - 1) {
        n = page - 1;
        template = template + '<a class="pre-page" href="?page=' + n + queryParams + '">' + leftText + '</a>';
    }

    // ========= Page Numbers Middle ===============
    // current is active, and make left page link count equal right link count
    i = 0;
    leftCount = Math.ceil(limit / 2) - 1;
    rightCount = limit - leftCount - 1;

    if (page + rightCount > pageCount) {
        leftCount = limit - (pageCount - page) - 1;
    }

    if (page - leftCount < 1) {
        leftCount = page - 1;
    }

    start = page - leftCount;

    while (i < limit && i < pageCount) {
        // start is every link
        n = start;

        if (start === page) {
            template = template + '<a class="active" href="?page=' + n + queryParams + '">' + n + '</a>';
        } else {
            // generate left style
            if (leftCount >= 4) {
                if (i === 0) {
                    // first page
                    template = template + '<a href="?page=1' + queryParams + '">1</a>';
                } else if (i === 1 || (i === 7 && start <= pageCount - 2)) {
                    // left and right ...
                    template = _renderEllipse(template);
                } else if (i === 8 && start <= pageCount - 1) {
                    template = _renderLastPage(template, pageCount, queryParams);
                } else {
                    // other links is normal
                    template = template +
                               '<a href="?page=' + n + queryParams + '">' +
                                    n +
                                '</a>';
                }
            } else {
                if (i === 7 && start <= pageCount - 2) {
                    // right ...
                    template = _renderEllipse(template);
                } else if (i === 8 && start <= pageCount - 1) {
                    template = _renderLastPage(template, pageCount, queryParams);
                } else {
                    template = template +
                               '<a href="?page=' + n + queryParams + '">' +
                                    n +
                                '</a>';
                }
            }

        }

        start++;
        i++;
    }

    // ========= Next page ===============
    if (pageCount - page) {
        n = page + 1;
        template = template + '<a class="next-page" href="?page=' + n + queryParams + '">' + rightText + '</a>';
    }

    template = template + '</div>';

    // html template
    return template;
};