Skip to content Skip to sidebar Skip to footer

Pagination Functionality Using Handlebars Js

DEMO I'am developing a Pagination Functionality using handlebars js and fetching the data from JSON. First 5 results will be shown on page load. on click of next pagination anoth

Solution 1:

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

Your range function is modified thusly, with c being the current page, and m your pageCount. Calls to the function have been modified a bit and a recursive call to your paginate(...) function is also added to recompute the tag after navigation (also, a branch was added to your DOM appending function calls, to modify the pagination tag, I used a ternary operator. There may be more elegant to achieve this). 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);
          } elseif (i - l !== 1) {
            rangeWithEllipsis.push("...");
          }
        }
        rangeWithEllipsis.push(i);
        l = i;
      }
    return rangeWithEllipsis;
}

It doesn't solve exactly your problem per say, but it does paginate correctly. If I have some time, I'll try and make it paginate the exact way you want to (it's really only about customizing the delta, left and right operand in the algorithm, and changing your pagination next and pagination prev event handler calls).

Edit I changed the algorithm to find the left and right boundary. Your index.html is also modified a bit. The idea is to compute the left and right boundary by multiples of 5. You then create a range of the indexes to show and add an elipsis if the difference is too big. This should effectively solves your original problem.

JavaScript

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

getLastDigit = (t) => {
 returnparseInt(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) => {
  returnparseInt(getFirstDigits(t).toString() + d.toString())
}

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

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

getLeft = (t) => {
  if(t>=10){
    if(isBetween0and5(t)) returnappendDigit(t,0);
    elsereturnappendDigit(t,5);
  } else {
    if (t<5) return0;
    elsereturn5;
  }
}

getRight = (t) => {
  if(t<5) return5;
  elseif (t<10) return10;
  elseif(isBetween0and5(t)) returnappendDigit(t,5)
  elsereturnappendDigit(incrementSecondDigit(t),0);
}

functionrange(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);
          } elseif (i - l !== 1){
            rangeWithEllipsis.push("...");
          }
        }
        rangeWithEllipsis.push(i);
        l = i;
      }
    return rangeWithEllipsis;
}

HTML/HandleBars

<!doctype html><htmllang="en"><head><metacharset="UTF-8"><title>Handlebars Pagination</title><linkhref="main.css"  /><scriptsrc="jquery.min.js"></script><scriptsrc="handlebars.min.js"></script><scriptsrc="functions.js"></script></head><bodyclass="container"><divid="posts"></div><scriptid="pagination-template"type="text/x-handlebars-template"><ulclass="pagination"><liclass="pagination-prev"><ahref="#">&laquo;</a></li>

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

            <liclass="pagination-next"><ahref="#">&raquo;</a></li></ul></script><scriptid="post-template"type="text/x-handlebars-template"><divclass="score-structural score-column2-wideright search-listings post"><divclass="score-right"><h4>{{record_count}}</h4><h5style="z-index: 1;"><ahref="#"> {{ title }} </a></h5><pstyle="z-index: 1;"> {{ desc }} </p></div></div><hr></script></body></html><script>
     $(function () {
        var opts = {
            pageMax: 2,
            postsDiv: $('#posts'),
            dataUrl: "searchResult.json"
        }

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

        functionhidePrev() { $('.pagination .pagination-prev').hide(); }
        functionshowPrev() { $('.pagination .pagination-prev').show(); }

        functionhideNext() { $('.pagination .pagination-next').hide(); }
        functionshowNext() { $('.pagination .pagination-next').show(); }

        functionpaginate(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);

            functionchangePage(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()
                }
                elseif (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>

Post a Comment for "Pagination Functionality Using Handlebars Js"