5

I am using dir-pagination directive by @michaelbromley. I want to get all the records on the current page of directive. Is there any way to do this?

dir-paginate pic

Here is the link: dir-pagination, so I need a collection of 5 records from 100 to 96. Is there any quick way to do it?

I have tried couple of things but not working.

developer033
  • 24,267
  • 8
  • 82
  • 108
Samir Shah
  • 709
  • 3
  • 12
  • 23

5 Answers5

4

I ran into this same issue, but the answers here didn't fulfill my needs (or maybe wants). I decided to solve it myself, and settled on creating a filter whose sole purpose is to record the items passing through it in a given property on a given target. I came up with this:

/**
 * Author: Eric Ferreira <http://stackoverflow.com/users/2954747/eric-ferreira> ©2015
 *
 * This filter will sit in the filter sequence, and its sole purpose is to record 
 * the current contents to the given property on the target object. It is sort of
 * like the 'tee' command in *nix cli.
 */
angular.module('app').filter('record', function() {
    return function(array, property, target) {
        if (target && property) {
            target[property] = array;
        }
        return array;
    }
});

Then you use the filter in your pagination (or anywhere you want to get the current array actually [think, after filtering with a search query, after paging, after filtering current page, et cetera]) like so:

<div dir-paginate="item in items | itemsPerPage:pageSize | record:'currentPage':this">{{item.text}}</div>

You can also use it multiple times in one sequence:

<div dir-paginate="item in items | filter:searchQuery | record:'filtered':this | itemsPerPage:pageSize | record:'currentPage':this">{{item.text}}</div>

The above would record both the current page and all records resulted from the current filter query.

This will record (and update whenever it changes) the current page in $scope.currentPage. The this in the above example is the target of the filter. It resolves to $scope.this which, for most intents and purposes, is just $scope.

In your specific case, you would use this line (after adding/requiring the filter in your module) instead for your pagination:

<li dir-paginate="meal in perman  = ( meals | filter:q ) | orderBy: order?'key':'-key' | itemsPerPage: pageSize | record:'currentPage':this">{{ meal.key + ': ' +meal.val }}</li>

I went ahead and forked your plunker to show it working too:

http://plnkr.co/edit/uC3RiC?p=preview

Eric Ferreira
  • 1,811
  • 18
  • 20
  • How would this record if an item is not allowed through the filter? Is `target` somehow being reset? – pcnate Aug 17 '16 at 20:40
  • This only saves the items that reach it, so it wouldn’t save anything filtered out by a previous filter. If you want to save the list before a given filter, just put this before the other filter in the list of filters. – Eric Ferreira Aug 18 '16 at 02:41
  • actually what I was referring to was the fact that the filters will frequently process. Just looking at the code I would think that when the filters restart, and find less results that the previous execution that it would not remove the missing results so you would end up with more than you think are visible. – pcnate Aug 18 '16 at 03:08
  • Well it doesn’t record incrementally; it wipes out the previous reference each time it is called. So it wouldn’t ever get out of synchronization with the actual values. – Eric Ferreira Aug 18 '16 at 11:55
  • 1
    That's a great idea @EricF ! – Lulu Dec 21 '16 at 13:59
1

Here is another possible way to do it, which does not require you to duplicate the logic from the dir-paginate expression:

For each repeated item, you could just push that item into an array in your controller. This will of course give you all the items for that page.

Here is an example:

<ul>
   <li dir-paginate="meal in perman  = ( meals | filter:q ) | orderBy: order?'key':'-key' | itemsPerPage: pageSize" current-page="currentPage" ng-init="addMeal(meal)">{{ meal.key + ': ' +meal.val }}</li>
</ul>

Then in the controller:

$scope.addMeal = function(meal) {
  if (meal) {
    if ($scope.page.length === $scope.pageSize + 1) {
      $scope.page = [];
    }
    $scope.page.push(meal);
  }
}

I've not expensively tested it, but the general principle should work. It's a bit hacky in my opinion, but it's worth knowing as an alternative to the answer provided by Rathish.

Michael Bromley
  • 4,792
  • 4
  • 35
  • 57
  • Thanks Michael for reply. Is there any way I can get the current page index in my controller. means on which page I am currently. – Samir Shah May 04 '15 at 03:41
  • When using a filter query, and typing and backspacing repeatedly, it is possible to trick this into losing track of the current page. It isn't useful when using dir-paginate and filtering at the same time. In my case, if I repeatedly typed and deleted `u`, the page would get out of sync. – Eric Ferreira Sep 25 '15 at 17:40
0

Yes we can create our own logic according to data.

Displaying {{ pageSize * (currentPage-1)+$index+1 }} - {{ pageSize*currentPage }} of {{ perman.length }}
-1

You can use array slice method since you already have access to the large array, know which page number you are on and know the number of elements per page. You can reuse the getPage function in the below code to achieve this.

app.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.currentPage = 1;
  $scope.pageSize = 5;
  var meals = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

  function getPage(currentPage, pageSize, arr, reverse) {  
    var beginIndex, endIndex, noOfPages;

    if(reverse) {
       beginIndex = arr.length - currentPage * pageSize;  
    } else {
      beginIndex = currentPage * pageSize - pageSize;
    }

    endIndex = beginIndex + pageSize;
    beginIndex = beginIndex < 0 ? 0 : beginIndex;
    return arr.slice(beginIndex, endIndex);
  }

  //This will return the 5 elements in page 1 of meals array which will be meals 11 to 15 since the array is bound to the pagination directive in the reverse (desc) order
  $scope.firstFiveArrRev = getPage($scope.currentPage, $scope.pageSize, meals, true);

  //This will return the 5 elements in page 1 of meals array which will be meals 1 to 5 since the array is bound to the pagination directive in ascending order
  $scope.firstFiveArr = getPage($scope.currentPage, $scope.pageSize, meals, false);
});

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.0-rc.0/angular.js" data-semver="1.4.0-rc.0"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    Displaying elements from page number {{currentPage}}
    <br />
    Page size is set to {{pageSize}}
    <br />
    When order is Reverse: true
    <div>{{ firstFiveArrRev.toString() }}</div>

    When order is Reverse: false
    <div>{{ firstFiveArr.toString() }}</div>
  </body>

</html>

Here is the plnkr

http://plnkr.co/edit/CgH1WFR1JvOLmQsacVoI?p=preview

-1
  1. Download dirPagination.js from here.

  2. Now include dirPagination.js to your page.

  3. Add angularUtils.directives.dirPagination in your module like this

var app = angular.module("myApp",['angularUtils.directives.dirPagination']);
  1. We use dir-paginate directive for pagination ,add dir-paginate in tr tag
<tr dir-paginate="event in events|orderBy:['columnid', 't']:true | itemsPerPage: 5">
  1. Add below given code anywhere on your page or where ever you want.
<dir-pagination-controls
                max-size="5"
                direction-links="true"
                boundary-links="true" >
</dir-pagination-controls>
Sahil Saini
  • 250
  • 5
  • 11