Pagination functionality using js rudders

DEMO

I am developing pagination functionality using js descriptors and retrieving data from JSON.

  • The first 5 results will be displayed on page load.

  • clicking the next pagination will display another set of 5 results, and so on.

  • If I have a total of 100 results displaying every 5 results on the page. The page numbers will be 1 out of 20.

  • if there are more than 5 pages in the folder, I want to display "1,2,3 ... last Page Number (20)" the same vice versa
  • when loading Previous button Should be hidden when clicking on the next page, it should be enabled.

Feel free to contact us, please read this and give some advice / suggestions on this matter.

Should be lower

enter image description here

Vice versa

Appreciate your kind help!

thank

  • example code:

        $(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);
            }
        });
    });
    
          

+3


source to share


1 answer


I had to solve a similar problem a few months ago. I found this Gist from kottenator.

Your range function changes in this way, which c

is the current page, and m

is yours pageCount

. The function call has been slightly modified, and a recursive call to your function has paginate(...)

also been added to recompile the tag after navigation (also added a branch to your DOM add function calls to change the pagination tag, I used ternary operator. It might be more elegant for that ).
See this CodePen

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;
}

      

It doesn't exactly solve your problem in one go, but it paginates correctly.
If I have some time, I will try to make it look the way you want it to (this is really just setting the personalization of the operands delta

, left

and right

in the algorithm, and also changing the pagination and paging of the prev event handler).

Edit . I changed the algorithm to find the border left

and right

. Yours is index.html

also slightly modified.
The idea is to compute the left and right margins in multiples of 5. Then you create a range of indices to display and add elipsis if the difference is too big. This should effectively solve your original problem.



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 / Steering Wheels

<!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>

      

+2


source







All Articles