pager.js 6.13 KB
/**
 * guang
 * @author: lcy<chuanyang.liu@yoho.cn>
 * @date: 2016/09/01
 */

'use strict';

let _ = require('lodash');
let Handlebars = require('handlebars');

let ALL_TYPES = {
    stand: 'p-page-n',
    mini: 'p-n',
    full: 'f-p-page-n-l-info-input-gobtn',
    fullellipsis: 'f-p-pe-n-l-info-input-gobtn',
    ellipsis: 'p-pe-n'
};

exports.gpager = function() {

    let options = arguments[arguments.length - 1];

    let baseUrl = (arguments.length > 1 ? arguments[0] : null) || options.hash.baseUrl || '',
        page = (options.hash.page || 1) * 1,
        showNum = (options.hash.showNum || 7) * 1,
        pageSize = options.hash.pageSize || 20,
        totalPages = options.hash.totalPages,
        totalRecords = options.hash.totalRecords,
        theme = options.hash.theme || 'pager',
        currentClass = options.hash.currentClass || 'cur',

        // min full stand ellipsis  or: f-首页, p-上一页, page-页码,n-下一页,l-最后一页,info-displayMsg,inout输入框,gobtn-goto Btn
        type = options.hash.type || 'stand',
        pageVar = options.hash.pageVar || 'page',
        pageSizeVar = options.hash.pageSizeVar || 'pageSize';

    // 清除原来page(page=1&) 重新定义page
    let clearPageReg = new RegExp(pageVar + '=[^&]*(&|$)'),
        clearSizeReg = new RegExp(pageSizeVar + '=[^&]*(&|$)'),
        base = baseUrl.replace(clearPageReg, '');

    if (options.hash.pageSize) {
        base = base.replace(clearSizeReg, '');
    }

    base += (base.indexOf('?') < 0 ? '?' : (/(\?|&)$/.test(base) ? '' : '&')) +
            (options.hash.pageSize ? (pageSizeVar + '=' + pageSize + '&') : '') +
            pageVar + '=';

    function getPageNums(ntype) {
        var pageNums = [];
        var num = showNum;

        if (ntype === 'e') {
            num = num - 2;
            num = num > 2 ? num : 2;
        }

        /** 分页展示页码个数begin 规则:展示最靠近当前页的指定个数 **/
        let pageShowMax = num % 2 === 0 ? page - 1 : page;
        let pageShowMin = page;

        for (let i = 0; i < Math.floor(num / 2); i++) {
            pageShowMax++;
            pageShowMin--;
            if (pageShowMax > totalPages) {
                pageShowMax = totalPages;
                if (pageShowMin > 1) {
                    pageShowMin--;
                }
            }
            if (pageShowMin < 1) {
                pageShowMin = 1;
                if (pageShowMax < totalPages) {
                    pageShowMax++;
                }
            }
        }

        for (let n = pageShowMin; n <= pageShowMax; n++) {
            pageNums.push(n);
        }

        if (ntype === 'e') {
            if (pageShowMin > 3) {
                pageNums.unshift(1, '.');
            } else if (pageShowMin === 2) {
                pageNums.unshift(1);
            } else if (pageShowMin === 3) {
                pageNums.unshift(1, 2);
            }

            if (pageShowMax < totalPages - 2) {
                pageNums.push('.', totalPages);
            } else {
                for (let x = pageShowMax + 1; x <= totalPages; x++) {
                    pageNums.push(x);
                }
            }
        }

        return pageNums;
    }

    function renderItem(arr) {
        /** 分页展示页码个数end **/
        let ret = '';

        if (_.isArray(arr) && arr.length) {

            arr.forEach((val) => {
                if (val === '.') {
                    ret += '<a>...</a>';
                } else {
                    ret += `<a href="${base}${val}"` +
                            (page === val ? `class="${currentClass}"` : '') +
                            ` title="第${val}页">${val}</a>`;
                }
            });
        }

        return ret;
    }

    function createStandItems() {
        return renderItem(getPageNums());
    }

    function createEllipsisItems() {
        return renderItem(getPageNums('e'));
    }

    if (!totalPages) {
        if (!totalRecords || !pageSize) {
            return new Handlebars.SafeString('');
        } else {
            totalPages = Math.ceil(totalRecords / pageSize);
        }
    }

    let items = ALL_TYPES[type] ? ALL_TYPES[type] : type;

    items = _.isArray(items) ? items : (items || ALL_TYPES.stand).split('-');

    let hasPage = false; // 配置中如果配置了多次 page/pe 则将忽略,只第一次有效
    let ret = `<div class="pager ${theme}">`;

    items.forEach(function(val) {

        switch (val) {
            case 'f' :
                if (page > 1) {
                    ret += `<a href="${base}1" title="首页">首页</a>`;
                }
                break;
            case 'p' :
                if (page > 1) {
                    ret += `<a href="${base}` + (page - 1) +
                            '" title="上一页"><span class="iconfont">&#xe60e;</span>上一页</a>';
                }
                break;
            case 'n' :
                if (page < totalPages) {
                    ret += `<a href="${base}` + (page + 1) +
                            '" title="下一页">下一页<span class="iconfont">&#xe60c;</span></a>';
                }
                break;
            case 'l' :
                if (page < totalPages) {
                    ret += `<a href="${base}${totalPages}" title="尾页">尾页</a>`;
                }
                break;
            case 'info' :
                ret += '共{totalRecords}条/{totalPages}页';
                break;
            case 'input' :
                // input
                // ret += '<span class="{cls}"><input value="{value}" type="text"></span>';
                break;
            case 'gobtn' :
                // goto btn
                break;
            case 'page' :
                if (!hasPage) {
                    ret += createStandItems();
                }
                hasPage = true;
                break;
            case 'pe' :
                if (!hasPage) {
                    ret += createEllipsisItems();
                }
                hasPage = true;
                break;
        }
    });

    if (options.fn) {
        ret += options.fn(options.context);
    }
    ret += '</div>';
    return new Handlebars.SafeString(ret);
};