knockout pagination simplified

knockout pagination simplified

by Dejan Vasic

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<div class="container">
  <h2>
  paged
</h2>
  <p>
    current <span data-bind="text: currentPage"></span>
  </p>
  <div data-bind="foreach: ticketsFiltered">
    <div>
      <label data-bind="text: ticketName"></label>
    </div>
  </div>

  <div data-bind="component: { name: 'pagination', params: {dataPromise: ticketPromise, changePage: viewPage, maxPagesToDisplay: 5, pageSize: 2}}">

  </div>

</div>

JavaScript

var data = [{
  ticketName: 'general',
}, {
  ticketName: 'child',
}, {
  ticketName: 'hello',
}, {
  ticketName: 'world',
}, {
  ticketName: 'foo',
}, {
  ticketName: 'bar',
}, {
  ticketName: 'h1',
}, {
  ticketName: 'h2',
}, {
  ticketName: 'h3',
}, {
  ticketName: 'h4',
}, {
  ticketName: 'h5',
}, {
  ticketName: 'h6',
}, {
  ticketName: 'h7'
}, {
  ticketName: 'h8'
}, {
  ticketName: 'h9'
}];

function FindTickets(data) {
  var pageSize = 2;
  var me = this;
  me.tickets = ko.observableArray();
  _.each(data, function(t) {
    me.tickets.push(new Ticket(t));
  });
  me.ticketPromise = new Promise(function(resolve, reject){
  	resolve(me.tickets());
  });

  me.currentPage = ko.observable(1);
  me.ticketsFiltered = ko.computed(function() {
    var chunked = _.chunk(data, pageSize);
    return chunked[me.currentPage() - 1];
  });

  me.viewPage = function(pageNum) {
    me.currentPage(pageNum);
  }
}

function Ticket(data) {
  var me = this;
  me.ticketName = ko.observable(data.ticketName);
}

function Pagination(param) {

  var me = this;
  me.currentPage = ko.observable(1);
  me.pages = ko.observableArray();
  me.totalPageCount = ko.observable();
  me.start = ko.observable(0);
  me.end = ko.observable(param.maxPagesToDisplay);

  param.dataPromise.then(function(items) {
    me.totalPageCount(Math.ceil(items.length / param.pageSize));
    if (me.totalPageCount() < param.maxPagesToDisplay) {
      me.end(me.totalPageCount());
    }

    for (var i = 1; i <= me.totalPageCount(); i++) {
      me.pages.push(new Page({
        number: i,
        selectPage: function(pageNum) {
          me.currentPage(pageNum);
          param.changePage(pageNum);
        }
      }));
    }
  });

  me.next = function() {
    if (me.end() === me.totalPageCount()) {
      return;
    }
    me.start(me.start() + 1);
    me.end(me.end() + 1);
  }

  me.prev = function() {
    if (me.start() === 0) {
      return;
    }
    me.start(me.start() - 1);
    me.end(me.end() - 1);
  }

 ...