使用handlebars js的分页功能

2024-02-07

DEMO https://codepen.io/syedazam/project/editor/XYeJoa/#0

我正在使用handlebars js 开发分页功能并从JSON 中获取数据。

  1. 前 5 个结果将在页面加载时显示。

  2. 单击下一页时,将显示另一组 5 个结果,依此类推。

  3. 如果我通过在页面中显示每 5 个结果来获得结果总数 100。页码将为 20 页中的第 1 页。

  4. 如果分页有超过 5 页,我想显示“1,2,3 ...最后页码 (20)”,反之亦然
  5. 加载时上一页按钮应隐藏,当单击下一页时,必须启用它。

请求您对此进行调查并就此提出一些意见/建议。

应该像下面这样

感谢您的帮助!

Thanks

  • 一些代码示例:

        $(function () {
            var opts = {
            pageMax: 5,
            postsDiv: $('#posts'),
            dataUrl: "searchResult.json"
        }
    
        function range(i) { return i ? range(i - 1).concat(i) : [] }
    
        function loadPosts(posts) {
            opts.postsDiv.empty();
            posts.each(function () {
                var source = $("#post-template").html();
                var template = Handlebars.compile(source);
                var context = {
                    title: this.title,
                    desc: this.body,
                };
                var html = template(context);
                opts.postsDiv.append(html);
            });
        }
    
        function paginate(pageCount) {
            var source = $("#pagination-template").html();
            var template = Handlebars.compile(source);
            var context = { pages: range(pageCount) };
            var html = template(context);
            opts.postsDiv.after(html);
    
            function changePage(pageNumber) {
                pageItems.removeClass('active');
                pageItems.filter('[data-page="' + pageNumber + '"]').addClass('active');
                loadPosts(data.slice(pageNumber * opts.pageMax - opts.pageMax, pageNumber * opts.pageMax));
            }
    
            var pageItems = $('.pagination>li.pagination-page');
    
            pageItems.on('click', function () {
                changePage(this.getAttribute('data-page'));
            }).filter('[data-page="1"]').addClass('active');
    
            $('.pagination>li.pagination-prev').on('click', function () {
                gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) - 1;
                if (gotoPageNumber <= 0) { gotoPageNumber = pageCount; }
                changePage(gotoPageNumber);
            });
    
            $('.pagination>li.pagination-next').on('click', function () {
                gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) + 1;
                if (gotoPageNumber > pageCount) { gotoPageNumber = 1; }
                changePage(gotoPageNumber);
            });
        }
    
        $.ajax({
            dataType: 'json',
            url: opts.dataUrl,
            success: function (response_json) {
                data = $(response_json.records.page);
                dataCount = data.length;
    
                pageCount = Math.ceil(dataCount / opts.pageMax);
    
                if (dataCount > opts.pageMax) {
                    paginate(pageCount);
                    posts = data.slice(0, opts.pageMax);
                } else {
                    posts = data;
                }
                loadPosts(posts);
            }
        });
    });
    

几个月前我必须解决类似的问题。我发现这个要点 https://gist.github.com/kottenator/9d936eb3e4e3c3e02598来自科特纳特。

您的范围函数因此被修改,c是当前页面,并且m your pageCount。对函数的调用已进行了一些修改,并对您的函数进行了递归调用paginate(...)还添加了函数来在导航后重新计算标签(另外,在 DOM 附加函数调用中添加了一个分支,以修改分页标签,我使用了三元运算符。可能有更优雅的方式来实现这一点)。
请参阅此代码笔 https://codepen.io/sumi1985/project/editor/Dzvzbd/#0

function range(c,m) {
  var current = c || 1,
      last = m,
      delta = 2,
      left = current - delta,
      right = parseInt(current) + delta + 1,
      range = [],
      rangeWithEllipsis = [],
      l,
      t;

      range.push(1);
      for (var i = c - delta ; i <= c + delta ; i++) {
        if (i >= left && i < right && i < m && i > 1) {
          range.push(i);
        }
      }  
      range.push(m);

      for (var i of range) {
        if (l) {
          if (i - l === 2) {
            t = l+1;
            rangeWithEllipsis.push(t);
          } else if (i - l !== 1) {
            rangeWithEllipsis.push("...");
          }
        }
        rangeWithEllipsis.push(i);
        l = i;
      }
    return rangeWithEllipsis;
}

它并不能完全解决您所说的问题,但它确实可以正确分页。
如果我有时间,我会尝试让它按照您想要的方式进行分页(这实际上只是关于自定义delta, left and right算法中的操作数,并更改分页下一个和分页上一个事件处理程序调用)。

Edit我改变了算法来找到left and right边界。你的index.html也稍作修改。
这个想法是按 5 的倍数计算左右边界。然后创建一个索引范围来显示,如果差异太大,则添加省略号。这应该可以有效地解决您原来的问题。

JavaScript

getFirstDigits = (t) => {
 return parseInt(t.toString().slice(0,-1))
}

getLastDigit = (t) => {
 return parseInt(t.toString().slice(-1))
}

isMultipleOf5 = (t) => {
 return [0,5].reduce((res,curr)=>{
   return res = res || curr === getLastDigit(t);
 },false);
}

isBetween0and5 = (t) => {
  const _t = getLastDigit(t);
  return  _t < 5;
}

isBetween5and9 = (t) => {
  const _t = getLastDigit(t);
  return  _t => 5 && _t <= 9;
}

appendDigit = (t,d) => {
  return parseInt(getFirstDigits(t).toString() + d.toString())
}

getSecondRightMostDigit = (t) => {
  return parseInt(t.toString().slice(-2,-1))
}

incrementSecondDigit = (t) => {
  return t+10;
}

getLeft = (t) => {
  if(t>=10){
    if(isBetween0and5(t)) return appendDigit(t,0);
    else return appendDigit(t,5);
  } else {
    if (t<5) return 0;
    else return 5;
  }
}

getRight = (t) => {
  if(t<5) return 5;
  else if (t<10) return 10;
  else if(isBetween0and5(t)) return appendDigit(t,5)
  else return appendDigit(incrementSecondDigit(t),0);
}

function range(c,m) {
  var current = c || 1,
      last = m,
      delta = 2,
      left = getLeft(c),
      right = getRight(c),
      range = [],
      rangeWithEllipsis = [],
      l,
      t;

      var rightBoundary = right < 5 ? 5 : right;
      for (var i = left ; i < rightBoundary ; ++i) {
        if( i < m && i > 0) range.push(i);
      }  
      range.push(m);

      for (var i of range) {
        if (l) {
          if (i - l === 2) {
            t = l+1;
            rangeWithEllipsis.push(t);
          } else if (i - l !== 1){
            rangeWithEllipsis.push("...");
          }
        }
        rangeWithEllipsis.push(i);
        l = i;
      }
    return rangeWithEllipsis;
}

HTML/HandleBars

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Handlebars Pagination</title>
    <link href="main.css" rel="stylesheet" />
    <script src="jquery.min.js"></script>
    <script src="handlebars.min.js"></script>
    <script src="functions.js"></script>
</head>

<body class="container">

    <div id="posts"></div>

    <script id="pagination-template" type="text/x-handlebars-template">
        <ul class="pagination">
            <li class="pagination-prev"><a href="#">&laquo;</a></li>

            {{#each pages}}
            <li class="pagination-page" data-page="{{this}}"><a href="#">{{this}}</a></li>
            {{/each}}

            <li class="pagination-next"><a href="#">&raquo;</a></li>
        </ul>
    </script>


    <script id="post-template" type="text/x-handlebars-template">
        <div class="score-structural score-column2-wideright search-listings post">
            <div class="score-right">
                <h4>{{record_count}}</h4>
                <h5 style="z-index: 1;">
                    <a href="#"> {{ title }} </a>
                </h5>
                <p style="z-index: 1;"> {{ desc }} </p>
            </div>
        </div>
        <hr>
    </script>

</body>

</html>

<script>
     $(function () {
        var opts = {
            pageMax: 2,
            postsDiv: $('#posts'),
            dataUrl: "searchResult.json"
        }

        function loadPosts(posts) {
            opts.postsDiv.empty();
            posts.each(function () {
                var source = $("#post-template").html();
                var template = Handlebars.compile(source);
                var context = {
                    title: this.title,
                    desc: this.body,
                };
                var html = template(context);
                opts.postsDiv.append(html);
            });
            hidePrev();
        }

        function hidePrev() { $('.pagination .pagination-prev').hide(); }
        function showPrev() { $('.pagination .pagination-prev').show(); }

        function hideNext() { $('.pagination .pagination-next').hide(); }
        function showNext() { $('.pagination .pagination-next').show(); }

        function paginate(page,pageCount) {
            var source = $("#pagination-template").html();
            var template = Handlebars.compile(source);
            var context = { pages: range(page,pageCount) };
            console.log(range(page,pageCount));
            var html = template(context);
            var paginationTag = opts.postsDiv.parent().find(".pagination");
            paginationTag.length > 0 ? paginationTag.replaceWith(html) : opts.postsDiv.before(html);

            function changePage(page) {
                pageItems.removeClass('active');
                pageItems.filter('[data-page="' + page + '"]').addClass('active');
                loadPosts(data.slice(page * opts.pageMax - opts.pageMax, page * opts.pageMax));
                paginate(page,pageCount);
                if (gotoPageNumber <= 1) {
                    hidePrev();
                }
            }

            var pageItems = $('.pagination>li.pagination-page');
            var pageItemsLastPage = $('.pagination li').length - 2;
            pageItems.removeClass('active');
            pageItems.filter('[data-page="' + page + '"]').addClass('active');

            pageItems.on('click', function () {
                getDataPageNo = this.getAttribute('data-page')
                console.log(getDataPageNo)
                changePage(getDataPageNo);
                if (getDataPageNo == 1) {
                    hidePrev()
                }
                else if (getDataPageNo == pageItemsLastPage) {
                    hideNext();
                }
                else {
                    showPrev();
                    showNext();
                }
            });

            $('.pagination>li.pagination-prev').on('click', function () {
                gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) - 1;
                changePage(gotoPageNumber);
            });

            $('.pagination>li.pagination-next').on('click', function () {
                gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) + 1;
                if (gotoPageNumber > pageCount) {
                    gotoPageNumber = 1;
                    showPrev();
                }
                changePage(gotoPageNumber);
            });
        }

        $.ajax({
            dataType: 'json',
            url: opts.dataUrl,
            success: function (response_json) {
                data = $(response_json.records.page);
                dataCount = data.length;

                pageCount = Math.ceil(dataCount / opts.pageMax);

                if (dataCount > opts.pageMax) {
                    paginate(1,pageCount);
                    posts = data.slice(0, opts.pageMax);
                } else {
                    posts = data;
                }
                loadPosts(posts);
            }
        });

    });

</script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用handlebars js的分页功能 的相关文章