RobertFrenette
RobertFrenette

Reputation: 627

Dynamic Angular table not filtering with pagination

Thanks to the assistance of another contributor, I have a dynamic Angular table that sorts / filters. I was able to add pagination tonight, following an example I found in another post, but the table filter only works on the first page.

I'm thinking it has something to do with the following table-row code, but haven't been able to narrow it down.

<tr class="paginationclass" ng-repeat="row in rows |
                                   orderBy:sort.type:sort.reverse |
                                   filter:searchData |
                                   pagination: curPage * pageSize |
                                   limitTo: pageSize">
    <td ng-repeat="column in cols">{{row[column]}}</td>
</tr>

I'd appreciate any guidance on where I'm going wrong. Thanks!

Fiddle

Upvotes: 0

Views: 2221

Answers (3)

Ignacio Villaverde
Ignacio Villaverde

Reputation: 1264

This is because the filter is being applied to the whole collection, so if you filter it, you could no longer have more than 1 page and that is why the second page is being empty, try going back to the first page and you will see the element you are searching for.

I have added a ng-change directive on filters input, so it modifies actual page when there are less items than the pageSize.

I have forked your fiddle and here it is:

https://jsfiddle.net/ignaciovillaverde/2rxg2e0y/3/

By the way, your ng-disabled condition for the "Next" button was not working well, I have modified it, take a look and try it.

Upvotes: 1

oori
oori

Reputation: 5711

Or even simpler, just add this:

$scope.$watch('searchData', function() { $scope.curPage = 0; });

So whenever there's any change to the 'searchData', we go to the first page.

Upvotes: 0

Saltuk
Saltuk

Reputation: 1159

You can watch $scope.$watch searchData filter on there ..

 $scope.$watch('searchData',function(newValue , oldValue){
    $scope.rows = $filter("filter")(data,newValue);
        $scope.curPage = 0;
        $scope.numberOfPages = Math.ceil($scope.rows.length / $scope.pageSize);
    },true);

here is your js

var data = [
    {"id" : "3", "name" : "Item 3", "cost" : "300"}, 
    {"id" : "1", "name" : "Item 1", "cost" : "100"}, 
    {"id" : "2", "name" : "Item 2", "cost" : "200"},
    {"id" : "6", "name" : "Item 6", "cost" : "600"}, 
    {"id" : "5", "name" : "Item 5", "cost" : "500"}, 
    {"id" : "4", "name" : "Item 4", "cost" : "400"}
];
angular.module('myApp', []).controller('myController', function ($scope,$filter) {
    $scope.sort = {
        type: 'id',
        reverse: false
    };
    $scope.searchData = '';
    $scope.rows = data;
    $scope.cols = Object.keys($scope.rows[0]);

    $scope.curPage = 0;
    $scope.pageSize = 3;
    $scope.numberOfPages =  Math.ceil($scope.rows.length / $scope.pageSize);

    $scope.$watch('searchData',function(newValue , oldValue){
    $scope.rows = $filter("filter")(data,newValue);
        $scope.curPage = 0;
        $scope.numberOfPages = Math.ceil($scope.rows.length / $scope.pageSize);
    },true);
}
);

ng-repeat="row in rows | orderBy:sort.type:sort.reverse | limitTo: pageSize"

<div class="container" ng-app="myApp" ng-controller="myController">
    <div class="row">
        <div class="col-md-8">
            <form>
                <div class="form-group">
                    <div class="input-group">
                        <div class="input-group-addon"><i class="glyphicon glyphicon-filter"></i>
                        </div>
                        <input type="text" class="form-control" placeholder="Filter" ng-model="searchData" id="filterText" />
                    </div>
                </div>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <div>
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <td ng-repeat="column in cols"> 
                                <a href="#" ng-click="sort.type = column; sort.reverse = !sort.reverse">
                                    {{column}}
                                    <span ng-show="sort.type == column && !sort.reverse" class="glyphicon glyphicon-arrow-down"></span>
                                    <span ng-show="sort.type == column && sort.reverse" class="glyphicon glyphicon-arrow-up"></span>
                                </a>
                            </td>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="paginationclass" ng-repeat="row in rows | orderBy:sort.type:sort.reverse | limitTo: pageSize">
                            <td ng-repeat="column in cols">{{row[column]}}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!-- pagination buttons -->
    <div class="row">
        <div class="pagination pagination-centered" ng-show="rows.length">
            <ul class="pagination-controle pagination">
                <li>
                    <button type="button" class="btn btn-primary"
                            ng-disabled="curPage == 0"
                            ng-click="curPage=curPage-1"> &lt; PREV</button>
                </li>
                <li>
                    <span>Page {{curPage + 1}} of {{ numberOfPages }}</span>
                </li>
                <li>
                    <button type="button" class="btn btn-primary"
                            ng-disabled="curPage >= datalists.length/pageSize - 1"
                            ng-click="curPage = curPage+1">NEXT &gt;</button>
                </li>
            </ul>
        </div>        
    </div>
</div>

Upvotes: 0

Related Questions