0

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

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is fantastic! Thanks for taking the time to fork/update the Fiddle and explain.
0

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>

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.