Authored by xuqi

Merge branch 'develop' of http://git.yoho.cn/fe/yoho-blk into develop

  1 +## Yoho BLK Components
  2 +
  3 +### 目的
  4 +
  5 +- 开箱即用
  6 +- 松耦合,内聚
  7 +- 开发并行
  8 +
  9 +### 分页组件
  10 +
  11 +- 组件名: pagination
  12 +
  13 +- 说明
  14 +
  15 + 根据BLK样式设计
  16 +
  17 +- 使用
  18 +
  19 + 1. express 服务端路由
  20 +
  21 + res.render('index', {
  22 + helpers: {
  23 + // 引入组件,注意path,根据项目路径
  24 + pagination: require('../components/paginator').createPagination
  25 + },
  26 + paginationOpts: {
  27 + page: page, // 当前页 http://host/?page=2
  28 + limit: 10, // 每页显示多少
  29 + totalRows: 100 // 一共多少纪录
  30 + }
  31 + });
  32 +
  33 + 2. handlebars view
  34 +
  35 + {{{ pagination paginationOpts }}}
  36 +
  37 + 3. 将public/scss/components/pagination.scss 加入到编译列表中
  38 +
  39 +- 参数option
  40 +
  41 + - 每页显示10条纪录
  42 +
  43 + {{{ pagination paginationOpts limit="10" }}}
  44 +
  45 + - 修改上一页文本
  46 +
  47 + {{{ pagination paginationOpts leftText="上一页" }}}
  48 +
  49 + - 修改下一页文本
  50 +
  51 + {{{ pagination paginationOpts leftText="下一页" }}}
  52 +
  53 + - 修改分页组件根元素class
  54 +
  55 + {{{ pagination paginationOpts paginationClass="your-class" }}}
  1 +/**
  2 + * 分页组件
  3 + * @author: djh<jinhu.dong@yoho.cn>
  4 + * @date: 2016/6/29
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +// render pagination ellipse indicator
  10 +function _renderEllipse(templateStr) {
  11 + return templateStr + '<li><a>...</a></li>';
  12 +}
  13 +
  14 +// render last page link
  15 +function _renderLastPage(templateStr, pageCount, queryParams) {
  16 + return templateStr + '<li><a href="?page=' + pageCount + queryParams + '">' + pageCount + '</a></li>';
  17 +}
  18 +
  19 +/*
  20 + * Pagination Component
  21 + * @param { Object } pagination pagination constructor
  22 + * --- pagination ---
  23 + * @param { Integer } limit: per page records number
  24 + * @param { String } leftText: prev button text, default is iconfont
  25 + * @param { String } rightText: next button text, default is iconfont
  26 + * @param { String } paginationClass: pagination ul class, default is 'blk-pagination'
  27 + */
  28 +
  29 +exports.createPagination = function(pagination, options) {
  30 + // default options
  31 + var limit = 9, // display links number
  32 + n, // page number ?page=n
  33 + queryParams = '', // paginate with query parameter
  34 + page = parseInt(pagination.page, 10), // current page number
  35 + leftText = '<i class="iconfont">&#xe60e;</i>', // prev
  36 + rightText = '<i class="iconfont">&#xe60c;</i>', // next
  37 + paginationClass = 'blk-pagination'; // pagination <ul> default class
  38 +
  39 + var pageCount,
  40 + key, // query params key
  41 + lastCharacterOfQueryParams;
  42 +
  43 + var i, // iterator for each refresh page
  44 + leftCount, // left pagination link counts for current position
  45 + rightCount, // right pagination link counts for current position
  46 + start; // left first link number
  47 +
  48 + var template;
  49 +
  50 + if (!pagination) {
  51 + return '';
  52 + }
  53 +
  54 + // custome options
  55 + if (options.hash.limit) {
  56 + limit = +options.hash.limit;
  57 + }
  58 +
  59 + if (options.hash.leftText) {
  60 + leftText = options.hash.leftText;
  61 + }
  62 +
  63 + if (options.hash.rightText) {
  64 + rightText = options.hash.rightText;
  65 + }
  66 +
  67 + if (options.hash.paginationClass) {
  68 + paginationClass = options.hash.paginationClass;
  69 + }
  70 +
  71 + pageCount = Math.ceil(pagination.totalRows / pagination.limit);
  72 +
  73 + // query params
  74 + if (pagination.queryParams) {
  75 + queryParams = '&';
  76 + for (key in pagination.queryParams) {
  77 + if (pagination.queryParams.hasOwnProperty(key) && key !== 'page') {
  78 + queryParams += key + '=' + pagination.queryParams[key] + '&';
  79 + }
  80 + }
  81 + lastCharacterOfQueryParams = queryParams.substring(queryParams.length, -1);
  82 +
  83 + if (lastCharacterOfQueryParams === '&') {
  84 + // trim off last & character
  85 + queryParams = queryParams.substring(0, queryParams.length - 1);
  86 + }
  87 + }
  88 +
  89 + template = '<ul class="' + paginationClass + '">';
  90 +
  91 + // ========= Previous Button ===============
  92 + if (page - 1) {
  93 + n = page - 1;
  94 + template = template + '<li><a href="?page=' + n + queryParams + '">' + leftText + '</a></li>';
  95 + }
  96 +
  97 + // ========= Page Numbers Middle ===============
  98 + // current is active, and make left page link count equal right link count
  99 + i = 0;
  100 + leftCount = Math.ceil(limit / 2) - 1;
  101 + rightCount = limit - leftCount - 1;
  102 +
  103 + if (page + rightCount > pageCount) {
  104 + leftCount = limit - (pageCount - page) - 1;
  105 + }
  106 +
  107 + if (page - leftCount < 1) {
  108 + leftCount = page - 1;
  109 + }
  110 +
  111 + start = page - leftCount;
  112 +
  113 + while (i < limit && i < pageCount) {
  114 + // start is every link
  115 + n = start;
  116 +
  117 + if (start === page) {
  118 + template = template + '<li class="active"><a href="?page=' + n + queryParams + '">' + n + '</a></li>';
  119 + } else {
  120 + // generate left style
  121 + if (leftCount >= 4) {
  122 + if (i === 0) {
  123 + // first page
  124 + template = template + '<li><a href="?page=1' + queryParams + '">1</a></li>';
  125 + } else if (i === 1 || (i === 7 && start <= pageCount - 2)) {
  126 + // left and right ...
  127 + template = _renderEllipse(template);
  128 + } else if (i === 8 && start <= pageCount - 1) {
  129 + template = _renderLastPage(template, pageCount, queryParams);
  130 + } else {
  131 + // other links is normal
  132 + template = template +
  133 + '<li><a href="?page=' + n + queryParams + '">' +
  134 + n +
  135 + '</a></li>';
  136 + }
  137 + } else {
  138 + if (i === 7 && start <= pageCount - 2) {
  139 + // right ...
  140 + template = _renderEllipse(template);
  141 + } else if (i === 8 && start <= pageCount - 1) {
  142 + template = _renderLastPage(template, pageCount, queryParams);
  143 + } else {
  144 + template = template +
  145 + '<li><a href="?page=' + n + queryParams + '">' +
  146 + n +
  147 + '</a></li>';
  148 + }
  149 + }
  150 +
  151 + }
  152 +
  153 + start++;
  154 + i++;
  155 + }
  156 +
  157 + // ========= Next page ===============
  158 + if (pageCount - page) {
  159 + n = page + 1;
  160 + template = template + '<li><a href="?page=' + n + queryParams + '">' + rightText + '</a></li>';
  161 + }
  162 +
  163 + template = template + '</ul>';
  164 +
  165 + // html template
  166 + return template;
  167 +};
  1 +ul.blk-pagination {
  2 + padding: 0;
  3 +
  4 + li {
  5 + display: inline-block;
  6 + padding: 5px;
  7 + width: 15px;
  8 + height: 15px;
  9 + text-align: center;
  10 +
  11 + &:first-child {
  12 + margin-right: 10px;
  13 + border: 1px solid #333;
  14 +
  15 + &:hover {
  16 + background-color: #333;
  17 + cursor: pointer;
  18 +
  19 + a {
  20 + color: #fff;
  21 + }
  22 + }
  23 + }
  24 +
  25 + &:last-child {
  26 + margin-left: 10px;
  27 + border: 1px solid #333;
  28 +
  29 + &:hover {
  30 + background-color: #333;
  31 + cursor: pointer;
  32 +
  33 + a {
  34 + color: #fff;
  35 + }
  36 + }
  37 + }
  38 + }
  39 +
  40 + .active {
  41 + background-color: #333;
  42 + a {
  43 + color: #fff;
  44 + }
  45 + }
  46 +}