37

Let's say I receive an object literal with 15+ objects and I need to display them in a nice layout (not all in a row), what is the most efficient method for controlling when the line should break/page should end?

Right now I'm using ng-repeat on table row's, and the result is a long thin table with one column.

Edit for clarification. Could have objects within objects/more params. Here is my object:

$scope.zones = [
        {"name": "Zone 1",
         "activity": "1"},
        {"name": "Zone 2",
         "activity": "1"},
        {"name": "Zone 3",
         "activity": "0"},
        {"name": "Zone 4",
         "activity": "0"},
        {"name": "Zone 5",
         "activity": "0"},
        {"name": "Zone 6",
         "activity": "0"},
        {"name": "Zone 7",
         "activity": "1"},
        {"name": "Zone 8",
         "activity": "0"},
        {"name": "Zone 9",
         "activity": "0"},
        {"name": "Zone 10",
         "activity": "0"},
        {"name": "Zone 11",
         "activity": "1"},
        {"name": "Zone 12",
         "activity": "1"},
        {"name": "Zone 13",
         "activity": "0"},
        {"name": "Zone 14",
         "activity": "0"},
        {"name": "Zone 15",
         "activity": "1"},
    ];
gogogadgetinternet
  • 5,719
  • 4
  • 24
  • 28
  • Please post an example of what your "object literal with 15+ objects" looks like. Is it an array of objects? or an object containing child objects? etc. – tennisgent Oct 16 '13 at 17:17
  • Do you want a kind of flow layout to display your items? If so I'm not sure this is an angular question, how would you do it without angular? I've done it before using fixed-height divs with either `float: left` or `display: inline-block`. I don't get what your question has to do with pagination... – Jason Goemaat Oct 16 '13 at 17:59
  • It would help if you gave more details of what exactly you want to accomplish or some of your code that's "not working" – NicolasMoise Oct 16 '13 at 18:16

8 Answers8

72

I would use table and implement the pagination in the controller to control how much is shown and buttons to move to the next page. This Fiddle might help you.

example of the pagination

 <table class="table table-striped table-condensed table-hover">
                <thead>
                    <tr>
                        <th class="id">Id&nbsp;<a ng-click="sort_by('id')"><i class="icon-sort"></i></a></th>
                        <th class="name">Name&nbsp;<a ng-click="sort_by('name')"><i class="icon-sort"></i></a></th>
                        <th class="description">Description&nbsp;<a ng-click="sort_by('description')"><i class="icon-sort"></i></a></th>
                        <th class="field3">Field 3&nbsp;<a ng-click="sort_by('field3')"><i class="icon-sort"></i></a></th>
                        <th class="field4">Field 4&nbsp;<a ng-click="sort_by('field4')"><i class="icon-sort"></i></a></th>
                        <th class="field5">Field 5&nbsp;<a ng-click="sort_by('field5')"><i class="icon-sort"></i></a></th>
                    </tr>
                </thead>
                <tfoot>
                    <td colspan="6">
                        <div class="pagination pull-right">
                            <ul>
                                <li ng-class="{disabled: currentPage == 0}">
                                    <a href ng-click="prevPage()">« Prev</a>
                                </li>
                                <li ng-repeat="n in range(pagedItems.length)"
                                    ng-class="{active: n == currentPage}"
                                ng-click="setPage()">
                                    <a href ng-bind="n + 1">1</a>
                                </li>
                                <li ng-class="{disabled: currentPage == pagedItems.length - 1}">
                                    <a href ng-click="nextPage()">Next »</a>
                                </li>
                            </ul>
                        </div>
                    </td>
                </tfoot>
                <tbody>
                    <tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
                        <td>{{item.id}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.description}}</td>
                        <td>{{item.field3}}</td>
                        <td>{{item.field4}}</td>
                        <td>{{item.field5}}</td>
                    </tr>
                </tbody>
            </table> 

the $scope.range in the fiddle example should be:

$scope.range = function (size,start, end) {
    var ret = [];        
    console.log(size,start, end);

       if (size < end) {
        end = size;
        if(size<$scope.gap){
             start = 0;
        }else{
             start = size-$scope.gap;
        }

    }
    for (var i = start; i < end; i++) {
        ret.push(i);
    }        
     console.log(ret);        
    return ret;
};
Kevin STS
  • 183
  • 2
  • 10
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • The jsfiddle is not working. Someone help me running this demo. – Ihsahs Apr 04 '14 at 14:16
  • 1
    @user2249160 where did you open it? In chrome it works – Maxim Shoustin Apr 04 '14 at 14:18
  • In the Fiddle. when sorting by ID it is not sorting in correct numeric ID order. – dman Apr 18 '14 at 02:07
  • 1
    @dman True, because id was defined as string. I changed it to numeric and changed Fiddle link. Thanks – Maxim Shoustin Apr 18 '14 at 06:28
  • Looks good now. Is loading the ALL the json data into the client side at once the only way this will work? – dman Apr 18 '14 at 13:27
  • 1
    @dman yes, in this demo I load all at once. But its not a lot stuff to do to load from server each page – Maxim Shoustin Apr 18 '14 at 13:55
  • If laod from server each page, won't that break the pagination customized sort order? Meaning on the next search page(page #2), the customized sort order is reset to default sort order? – dman Apr 18 '14 at 17:36
  • @dman in current example sorting done for one page only (what we actually see). – Maxim Shoustin Apr 18 '14 at 17:46
  • 1
    @MaximShoustin: setting the `$scope.itemsPerPage = 50;` causes a funky result. Pages from -2 to 2. – Jon Crowell Sep 21 '15 at 21:16
  • What if I want to display 5 items per page and if items are less than or equal to 5, I want to hide the pagination control? Can anyone shade light on this? – YuDroid Jan 13 '16 at 07:24
  • I don't mean to sound like a boor, but I keep running across a bug that crashes my browser (IE 11). When I am on my browser changing pages between arbitrary numbers, eventually, my browser crashes claiming I accessed an invalid area. I've spent hours trying to fix it, but I can't quite figure it out. Anyone else have this problem? – Sal Alturaigi Jul 14 '16 at 13:51
  • It just orders the items in the current page. – Watchmaker Jul 18 '16 at 11:38
  • @MaximShoustin this pagination is good but sort won't work as expected it will filter only that data which is appearing on the screen instead of the whole object.! can you help with this fix.! – Mr world wide Apr 11 '18 at 05:29
16

This is the simplest example I found for pagination! http://code.ciphertrick.com/2015/06/01/search-sort-and-pagination-ngrepeat-angularjs/

Santosh
  • 2,093
  • 1
  • 15
  • 21
  • it's indeed very helpful. Worked like a charm. Updated documentation for Angular 7 is here https://ciphertrick.com/search-sort-pagination-angular/ – learner Sep 20 '19 at 22:23
13

I use this solution:

It's a bit more concise since I use: ng-repeat="obj in objects | filter : paginate" to filter the rows. Also made it working with $resource:

http://plnkr.co/edit/79yrgwiwvan3bAG5SnKx?p=preview

Nuno Silva
  • 728
  • 11
  • 27
8

Here is my solution. @Maxim Shoustin's solution has some issue with sorting. I also wrap the whole thing to a directive. The only dependency is UI.Bootstrap.pagination, which did a great job on pagination.

Here is the plunker

Here is the github source code.

maxisam
  • 21,975
  • 9
  • 75
  • 84
7

here i have solve my angularJS pagination issue with some more tweak in server side + view end you can check the code it will be more efficient. all i have to do is put two value start number and end number , it will represent index of the returned json array.

here is the angular

var refresh = function () {
    $('.loading').show();
    $http.get('http://put.php?OutputType=JSON&r=all&s=' + $scope.CountStart + '&l=' + $scope.CountEnd).success(function (response) {
        $scope.devices = response;


        $('.loading').hide();
    });
};

if you see carefully $scope.CountStart and $scope.CountStart are two argument i am passing with the api

here is the code for next button

$scope.nextPage = function () {
    $('.loading').css("display", "block");
    $scope.nextPageDisabled();


    if ($scope.currentPage >= 0) {
        $scope.currentPage++;

        $scope.CountStart = $scope.CountStart + $scope.DevicePerPage;
        $scope.CountEnd = $scope.CountEnd + $scope.DevicePerPage;
        refresh();
    }
};

here is the code for previous button

$scope.prevPage = function () {
    $('.loading').css("display", "block");
    $scope.nextPageDisabled();

    if ($scope.currentPage > 0) {
        $scope.currentPage--;

        $scope.CountStart = $scope.CountStart - $scope.DevicePerPage;
        $scope.CountEnd = $scope.CountEnd - $scope.DevicePerPage;

        refresh();

    }
};

if the page number is zero my previous button will be deactivated

   $scope.nextPageDisabled = function () {

    console.log($scope.currentPage);

    if ($scope.currentPage === 0) {
        return false;
    } else {
        return true;
    }
};
nur farazi
  • 1,197
  • 12
  • 32
2

Table with papging, sort and filter

enter image description here

Refer full example at Angularjs table sorting filter and paging

Lewis Hai
  • 1,114
  • 10
  • 22
2

The best simple plug and play solution for pagination.

https://ciphertrick.com/2015/06/01/search-sort-and-pagination-ngrepeat-angularjs/#comment-1002

you would jus need to replace ng-repeat with custom directive.

<tr dir-paginate="user in userList|filter:search |itemsPerPage:7">
<td>{{user.name}}</td></tr>

Within the page u just need to add

<div align="center">
       <dir-pagination-controls
            max-size="100"
            direction-links="true"
            boundary-links="true" >
       </dir-pagination-controls>
</div>

In your index.html load

<script src="./js/dirPagination.js"></script>

In your module just add dependencies

angular.module('userApp',['angularUtils.directives.dirPagination']);

and thats all needed for pagination.

Might be helpful for someone.

Hema
  • 988
  • 1
  • 16
  • 38
  • 1
    I had almost finished coding my own - which I have now thrown away to use this. dirPagination seems to get a thumbs up all across the webs. It's powerful, with free search & sort and the ability to change the number of items per page at run-time, and just a simple to use as you say. Highly recommended – Mawg says reinstate Monica Mar 20 '17 at 12:33
0

The simplest way is using slice. You pipe the slice and mention the start index and end index for the part of the data you wish to display. Here is the code:
HTML

<table>
  <thead>
     ...
  </thead>
  <tbody>
     <tr *ngFor="let row of rowData | slice:startIndex:endIndex">
        ...
     </tr>
  </tbody>
</table>
<nav *ngIf="rowData" aria-label="Page navigation example">
    <ul class="pagination">
        <li class="page-item">
            <a class="page-link" (click)="updateIndex(0)" aria-label="Previous">
                <span aria-hidden="true">First</span>
            </a>
        </li>
        <li *ngFor="let i of getArrayFromNumber(rowData.length)" class="page-item">
            <a class="page-link" (click)="updateIndex(i)">{{i+1}}</a></li>

        <li class="page-item">
            <a class="page-link" (click)="updateIndex(pageNumberArray.length-1)" aria-label="Next">
                <span aria-hidden="true">Last</span>
            </a>
        </li>
    </ul>
</nav>


TypeScript

...
public rowData = data // data you want to display in table
public paginationRowCount = 100 //number of records in a page
...
getArrayFromNumber(length) {
        if (length % this.paginationRowCount === 0) {
            this.pageNumberArray = Array.from(Array(Math.floor(length / this.paginationRowCount)).keys());
        } else {
            this.pageNumberArray = Array.from(Array(Math.floor(length / this.paginationRowCount) + 1).keys());
        }
        return this.pageNumberArray;
    }

    updateIndex(pageIndex) {
        this.startIndex = pageIndex * this.paginationRowCount;
        if (this.rowData.length > this.startIndex + this.paginationRowCount) {
            this.endIndex = this.startIndex + this.paginationRowCount;
        } else {
            this.endIndex = this.rowData.length;
        }
    }

Refence for tutorial: https://www.youtube.com/watch?v=Q0jPfb9iyE0