使用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的分页功能 的相关文章

  • 如何在 JS Rails 响应中包含 HTML?

    我有一个响应 HTML 和 JS AJAX 查询的 FooController app controllers foo controller rb class FooController lt ApplicationController l
  • React JS - 单击时更改颜色并将默认颜色放在所有其他颜色上

    我有 x 个渲染数文章预览依赖于 API 调用的组件 div div Object keys images map index i gt return div div
  • 在 Javascript 中动态添加事件处理程序

    我在使用 Javascript 时遇到了一个奇怪的问题 我得到的是一个特定格式的字符串 我将尝试用它创建一个表 该表每行只有一个单元格 字符串的格式为 每个单元格 行 需要显示内容 将传递给的参数onmouseover当用户将鼠标移动到显示
  • 防止jsTree节点选择

    我正在使用 jsTree 插件列出文件系统中的文件夹 我需要防止用户在满足特定条件之前更改到另一个节点 下面的代码不会停止传播 我看到了一些使用其他插件的解决方案 但这是一个简单的任务 没有其他插件它一定是可能的 jstree on sel
  • JQUERY 中用于加载 JQGRID 的选项卡

    我正在使用 jqgrid 制作网格 我想在我的应用程序中创建选项卡 单击选项卡应打开一个网格 选项卡的名称应显示在页面顶部 当我单击另一个选项卡时 它应该加载另一个网格 网格应该加载在同一页面上 并且选项卡也应该始终出现在页面上 我已经创建
  • less.js - 在解析器回调中获取变量值

    我正在使用 less js 1 3 0 在客户端将 less 解析为 css 在解析器的回调中 我想获取每个变量的值 我尝试了以下方法但没有成功 var data colour red example background color co
  • jQuery id 选择器在有 .在 ID 中[重复]

    这个问题在这里已经有答案了 我的html代码如下 div class chatbox html markup which is validated div 在上面的代码中dipesh parmardiv 动态添加 我正在使用以下代码访问它
  • Child_process 处理带有回车符 (\r) 的 STDOUT 流

    我正在编写一个简单的应用程序 它允许工作中的内部系统请求从远程服务器到使用 REST 调用发起的另一个远程服务器的复制过程 使用 rsync 我已经对express框架足够熟悉 并且刚刚开始尝试child process库 并偶然发现了一个
  • 通过 Javascript 将图像切割成碎片

    我正在创建一个简单的拼图游戏 为了做到这一点 我需要将我正在使用的图片切成 20 块 Javascript 有没有办法将一张图片切成 20 个相等的部分 并将它们保存为网页中的 20 个不同的对象 或者我只需要进入 Photoshop 自己
  • JSON对象的长度[重复]

    这个问题在这里已经有答案了 该函数生成一个包含 json 对象的数组 var estoque function unpack estoque tnm total estoque vl id tid st tnm tnm split tota
  • 缩放事件侦听器之前的 Javascript OpenLayers

    我正在尝试将 OpenLayers 设置为在缩放开始之前不显示矢量图层 并使其在缩放结束后重新出现 我已经像这样建立了缩放结束部分 map new OpenLayers Map map element eventListeners zoom
  • mouseover 和 mouseout 事件在子进程上触发

    代码 div div div div 如果我将鼠标悬停在Navigation the Drop Downdiv 向下滑动 如果我将鼠标移开 它会向上滑动 问题是如果我将鼠标悬停在孩子上Drop Downdiv它也向上滑 动 有谁知道我该如何
  • 覆盖函数(例如“警报”)并调用原始函数?

    我想用调用原始版本的新版本覆盖 Javascript 内置函数 类似于用调用的版本覆盖类上的方法 super有多种语言版本 我怎样才能做到这一点 例如 window alert function str do something addit
  • express 或express-generator:我需要两者吗?

    只是探索 Node js 并遇到了 Express 在 npm 存储库站点上https www npmjs com package express https www npmjs com package express它明确指出安装是 np
  • 在 ASP.NET MVC 4 中使用 jQuery Mobile 1.3 面板时的双滚动条

    我无法弄清楚这一点 将以下代码放入布局页面并在浏览器中查看后 我将显示 2 个垂直滚动条 div div 遇到了类似的问题 并注意到只有在使用我的自定义主题时才出现这种问题 我以错误的顺序将自定义主题添加到页面 这导致了问题 正确的顺序是
  • 有没有好的 JQuery twitter 小部件可以循环推文?

    我想知道是否有任何 JQuery 小部件提供了循环加载推文的功能 例如在官方小部件中http twitter com about resources widgets widget profile http twitter com about
  • 为 Meteor 数据创建编号列表

    有没有办法获取 Meteor 集合中项目的编号列表的 编号 我知道我可以在 html 中做到这一点 但我觉得如果我可以在 spacebars 中放置一些东西 那么样式会更容易 如果我可以使用更好的术语 请告诉我 像这样的东西 前 20 部电
  • 通过多个回调优雅地传递“点击事件”

    当未登录的用户单击给定的按钮时 我想停止该事件 收集他的 oauth 收集他的电子邮件 如果我没有 然后执行该事件 我想用 javascript 来做所有事情 因为这会让事情变得更加简单 这就是我执行它的方式 我有两个问题 有没有更优雅的方
  • 为什么 JSON 结果可以是布尔值而不是对象或数组?

    From JSON 网站 http json org JSON 建立在两种结构之上 名称 值对的集合 在各种语言中 这被实现为对象 记录 结构 字典 哈希表 键控列表或关联数组 值的有序列表 在大多数语言中 这被实现为数组 向量 列表或序列
  • 支持换行的 JQuery 工具提示

    我正在寻找一个轻量级的 jquery 插件 用于在用户将鼠标悬停在元素上时显示工具提示 我希望插件从标题属性中获取内容 而且我可以创建新行也很重要 任何帮助表示赞赏 在 jQuery 1 9 jquery jquery ui 和标准 too

随机推荐

  • 对可执行文件进行数字签名有多重要?

    我们生产内容管理系统 它是一个基于数据库的系统 仅供企业和组织使用 并且不能从互联网上下载 也就是说 它不是那种人们可能会偶然发现并想知道它是什么以及运行是否安全的软件 我们的系统销售了 20 多年 其可执行文件从未经过数字签名 我们是时候
  • 显示 PHP 文件中的 404 错误页面,无需重定向

    我有一个文件secret php其中包含在index php我想在有人尝试访问时显示 404 错误页面secret php直接地 但 header Location this site certainly does not exist in
  • CComboBox 下拉时未选择 CurSel

    我在对话框中有一个按字母顺序排序的组合框 该组合包含多个字符串 但有些字符串在不同情况下重复 即我们有一个 开 和一个 开 一个 关 和一个 关 这看起来似乎多余 但这是有原因的 尽管现在这并不重要 重复项显然是一个接一个地出现在列表中 大
  • CSS background-clip:来自父元素背景的文本

    我想得到一个background clip text在子 div 上从父 div 获取其背景 基本上它应该看起来像文本被剪掉了 当背景位于同一元素上时很容易做到 但我似乎无法弄清楚背景何时位于不同的 div 上 background wid
  • 导入我的非托管解决方案不会更改帐户表单

    我在 CRM 中有一个定制的帐户 主 表单 我在其中添加了一个新选项卡 一个新部分和新字段 我事先发布了所有自定义内容 然后导出 然后导入到我的测试环境中 我都是在测试环境下发布的 非托管解决方案包含此表单及其新字段 当我查看导出的 zip
  • 如何制作iOS资源包?

    我在评估的 iOS 项目中看到了一个自定义资源包 所以至少我知道这是可能的 我的问题是 我对给定图像使用大约 22 000 个图块的 CATiledLayer 并且编译需要很长时间 干净构建需要半小时 常规构建需要 5 10 分钟 因此 我
  • HTML 垂直对齐失败?

    我有一个由 2 个文本框组成的简单表单 我只是想让表单出现在页面中间 页面中没有任何额外的元素 通过使用align center 元素确实移动到中心 但情况并非如此vertical align middle
  • Java UI,尝试在单击按钮后转到下一页

    我有一个简单的 GUI 带有 3 个单选按钮和一个按钮 我希望用户选择一个单选选项 然后单击该按钮后 用户将根据他们选择的单选按钮被定向到不同的 Java UI 这是我的方法 private void btnContinueActionPe
  • 在网站上动态生成 SVG 图像是否明智?

    我刚刚学习 SVG 它看起来很棒 但我不确定浏览器支持 人们是否成功解决了这个问题 还是还为时过早 Raphael http raphaeljs com 是一个跨浏览器矢量图形库 可能值得一看
  • 将 Kotlin + Java 与 Maven 混合,未解决的参考

    我有一个带有 Kotlin 代码的 Maven 项目hello kt它调用 Java 代码JavaFoo java调用 Kotlin 代码KotlinFoo kt hello kt还打电话KotlinFoo kt直接地 我正在尝试用mvn
  • 如何在CUBLAS中计算复数幂?

    我正在将我的 C 代码移植到 CUDA 和 CUBLAS 我使用 stl complex 进行复杂计算 即 pow log exp 等 但我没有看到 CuComplex 库中定义的相同函数 我不知道如何创建这些功能 但我在网上找到了一些代码
  • Ember CLI 应用程序中基于环境的主机

    我正在尝试在 Ember CLI 应用程序中配置适配器 以根据环境使用不同的主机 在开发中 我希望它成为默认的当前主机 让我通过 proxy选项 但在生产中我知道它会是http some url 我尝试导入我的ENV进入我的应用程序适配器
  • 具有两种文本对齐方式的属性文本

    有谁知道如何在一个字符串中实现两种不同的文本对齐方式 这就是我想要 textView 显示的内容 label value My code let txtView cell viewWithTag 77 as UITextView let l
  • android:fontFamily 需要 api 级别 16,但文档说级别 15 可以吗?

    如何在 API 级别 15 上设置字体系列 文档说 API 15does有 fontFamily 属性 我希望文档会说 这在 API 级别 15 中已弃用 对于 API 级别 15 及更低级别 请参阅 但他们没有 如何在 XML 中 或以编
  • System.TypeLoadException:“Xamarin.Forms.Forms+AndroidPlatformServices 类型的 VTable 设置失败”

    我是 Xamarin 新手 目前我必须对现有应用程序之一进行一些更改 但是当我尝试加载项目时 最初出现了很多与版本代码相关的错误 我以某种方式设法克服了这些错误 但我对这个错误感到震惊 System TypeLoadException VT
  • 添加事件监听器的多个功能

    没有jquery 嘿 我正在尝试向按钮添加多个添加事件侦听器 function logoContame var logo document getElementById logoheader logo addEventListener cl
  • 在Python中将列表的列表转换为字典的字典

    我正在尝试将列表数据结构的列表转换为字典的字典 该列表定义如下 l PP Ear rings Holesovice 2000 PP Skirts Holesovice 1000 PP Dresses E shop 1500 BM Butte
  • 连接周期以获得时间序列,同时针对不同的起点

    我有以下示例数据 library data table set seed 42 t lt data table time 1 1000 period round runif 100 1 5 p lt data table id 1 10 c
  • 有没有办法以编程方式请求许可?

    有什么方法可以在android中以编程方式请求许可吗 我不想将所有权限添加到 AndroidManifest xml 那么有没有在运行时请求权限的对话框呢 应用程序静态声明它们所需的权限 Android系统在安装应用程序时提示用户同意 An
  • 使用handlebars js的分页功能

    DEMO https codepen io syedazam project editor XYeJoa 0 我正在使用handlebars js 开发分页功能并从JSON 中获取数据 前 5 个结果将在页面加载时显示 单击下一页时 将显示