0

So I don't have the option to use external third party libraries that would make my life so much easier, so I have to build this from scratch.

And I think I over complicated this.

So the idea is that if a client passes in, via the url, something like: showPages=4. Then we have something like:

<< < 1 2 3 4 _5_ 6 7 8 9 > >>

Where 5 is the current page, you should see 4 to the left and 4 to the right of the current page (lets say the max pages are 20)

My view model, so far, looks like:

var ViewModel = {
    self.pagesBefore = ko.observable(4);
    self.pagesAfter = ko.observable(4);
    self.currentPage = ko.observable(5);
    self.totalPages = ko.observable(20);
    self.pageStart = ko.observable(0);
    self.pageEnd = ko.observable(0);
}

I think I overcomplicated this because I don't think I need the pages before and pages after, I think I can change that into: self.showPages(4)

The problem I am having is laying this out in the view, I have no issue figuring out where to start, so for example there might be a method in the view model that does:

var endPage = self.currentPage() + self.pagesAfter();

if (endPage <= self.totalPages()) {
  self.pageEnd(endPage); // In our example above its 9
} else { 
  self.pageEnd(self.totalPages());
}

To get the "final" page to the right, in this case 9.

And another that calculates what the "starting page (or pages before the current page)" is:

var startPage = self.currentPage() - self.pagesBefore();

if (startPage > 1) {
  self.pageStart(startPage); // In our example above its 1
} else { 
  self.pageEnd(1);
}

So I would end up with a view model variables looking like:

var ViewModel = {
    self.pagesBefore = ko.observable(4);
    self.pagesAfter = ko.observable(4);
    self.currentPage = ko.observable(5);
    self.totalPages = ko.observable(20);
    self.pageStart = ko.observable(1);
    self.pageEnd = ko.observable(9);
}

So my question is: How do I translate this to the view so that I have a paginated element that has 5 selected with 4 to the right and 4 to the left with a total of 20 pages?

Jeroen
  • 60,696
  • 40
  • 206
  • 339
TheWebs
  • 12,470
  • 30
  • 107
  • 211
  • Possible duplicate of [How to handle pagination with Knockout](http://stackoverflow.com/questions/17668491/how-to-handle-pagination-with-knockout) – Jeroen Jun 01 '16 at 05:26

1 Answers1

0

It is probably easier to get your JavaScript to make an array of objects to show on the page. You can do this with a ko.computed function. Then to display it, you can just use a knockout foreach in your HTML.

As it is a computed function, changing the currentPage or totalPage observable will automatically cause your HTML to update.

Something like:

function ViewModel() {
  var self = this;

  self.currentPage = ko.observable(5);
  self.totalPages = ko.observable(20);
  self.pagesBefore = ko.observable(4);
  self.pagesAfter = ko.observable(4);
  
  self.pages = ko.computed(function() {
      // Work out the start and end pages - same logic as you already had
      var startPage = self.currentPage() - self.pagesBefore();
      if (startPage < 1) {
          startPage = 1
      }
      var endPage = self.currentPage() + self.pagesAfter();
      if (endPage > self.totalPages()) {
          endPage = self.totalPages();
      }

      // Make the page array
      var pageArray = [];
      for (var i = startPage; i <= endPage; i++) {
          pageArray.push({ page: i, highlight: i == self.currentPage() });
      }
      return pageArray;
  });
}

ko.applyBindings(new ViewModel());
<!-- Stuff to get the snippet to work -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<style>
  ul li {
    display: inline;
  }
  .high { color: red; }
</style>

<!-- output the pages (the important bit) -->
<ul data-bind="foreach: pages">
  <li data-bind="text: page, css: (highlight ? 'high' : '')"></li>
</ul>
The Dark
  • 8,453
  • 1
  • 16
  • 19
  • You can add this data-bind to your `
  • ` if you want to test the updates: `click: $parent.currentPage.bind(null, page)`
  • – user3297291 Jun 01 '16 at 09:03