1

I'm trying to use Angular-ui pagination directive for the first time and am confused why it isn't working. I can see the pagination buttons and it properly displays two pages to paginate through since there are 8 results and items-per-page="5" But all my data items are showing and not being hidden to five per page.

controller

dataService.get(uri).then(function (data) {

    $scope.testimonials = data;

    $scope.totalItems = $scope.testimonials.length;
    $scope.currentPage = 1;

    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };

    $scope.pageChanged = function() {
        console.log('Page changed to: ' + $scope.currentPage);
    }
});

view

<table class="table table-striped" ng-show="testimonials.length">
    <thead>
      <th>Name</th>
      <th>Message</th>
    </thead>
    <tbody>
    <tr ng-repeat="testimonial in testimonials">
      <td>{{testimonial.name}}</td>
      <td>{{testimonial.message}}</td>
      <td><a href="testimonials/{{testimonial.id}}" class="btn btn-primary">Edit</a></td>
      <td><button class="btn btn-danger" ng-click="delete(testimonial)">Delete</button></td>
    </tr>
    </tbody>

    <pagination total-items="totalItems" ng-model="currentPage" items-per-page="5" ng-change="pageChanged()"></pagination>
</table>

I appreciate any advice, thanks!

Mitch
  • 1,374
  • 5
  • 21
  • 39

3 Answers3

2

Yo need filter data in your ng-reapeter code below should works

<table class="table table-striped" ng-show="testimonials.length">
    <thead>
      <th>Name</th>
      <th>Message</th>
    </thead>
    <tbody>
    <tr ng-repeat="testimonial in testimonials | startFrom: (currentPage-1)*5| limitTo: 5">
      <td>{{testimonial.name}}</td>
      <td>{{testimonial.message}}</td>
      <td><a href="testimonials/{{testimonial.id}}" class="btn btn-primary">Edit</a></td>
      <td><button class="btn btn-danger" ng-click="delete(testimonial)">Delete</button></td>
    </tr>
    </tbody>

    <pagination total-items="totalItems" ng-model="currentPage" items-per-page="5" ng-change="pageChanged()"></pagination>
</table>

filter starts from:

app.filter('startFrom', function () {
    return function (input, start) {



        if (input === undefined || input === null || input.length === 0
         || start === undefined || start === null || start.length === 0 || start === NaN) return [];
        start = +start; //parse to int

        try {
            var result = input.slice(start);
            return result;

        } catch (e) {

        //    alert(input);
        }

    }
});
sylwester
  • 16,498
  • 1
  • 25
  • 33
  • This didn't work, I get the error `Error: [$injector:unpr] Unknown provider: startFromFilterProvider` because I don't have a filter called startFrom – Mitch Jun 27 '14 at 22:08
  • sorry i've missed that I've added filter start to answer – sylwester Jun 27 '14 at 22:21
0

I can't find the original example I used, but this is what I have in my app.

The filter part isn't important, but the filterProducts object is what gets sliced and shown in your view. Check out the $watch for how it works.

app.controller('ProductController', function($scope, $filter, $routeParams, $rootScope, $location, Products){

    $scope.Products = Products;
    Products.brandLimit = $routeParams.brandLimit;
    Products.brand = $routeParams.brand;

    // try to avoid reloading the prod data
    if (!Products.products){
        Products.getProducts().then(function(data){
            Products.products = data.products;
            Products.pagination();
        });
    }else{
        Products.pagination();
    }

    // watch for when the pagination changes
    $scope.$watch('Products.currentPage + Products.numPerPage', function() {
        var begin = ((Products.currentPage - 1) * Products.numPerPage);
        var end = begin + Products.numPerPage;

        Products.pagedProducts = Products.filteredProducts.slice(begin, end);
    });
});

And in the service:

app.factory('Products', function($http, $filter, $location, $routeParams){
    var Products = {
        search: '',
        searching: false,
        filteredProducts: '',
        pagedProducts: '',
        getProduct: function(id){
            delete Products.detail;
            $http.get('/product/' + id).then(function(response){
                Products.detail = response.data.product;
            });
        },
        getProducts: function(){
            return $http.get('/product').then(function(response){
                return response.data;
            });
        },
        pagination: function(){

            // relies on fulltext filter
            this.filteredProducts = $filter('fulltext')(this.products, this.brandLimit);

            // set up default values to feed to ui pagination
            this.currentPage = 1;
            this.numPerPage = 10;
            this.maxSize = 10;

            // check the length of filtered items based on search or brand clicked (in the URL)
            this.totalItems = this.filteredProducts.length;
            this.numPages =  Math.ceil(this.totalItems / this.numPerPage);
        },
        brandTitle: function() {

            if (this.searching === false || this.brand) {
                this.search = '';
                return $routeParams.brand + " Products";
            } else {
                return 'Searching "' + $routeParams.brandLimit + '"';
            }
        },
        searchTerm: function(){
            if(this.search){
                $location.path("search/" + this.search);
                this.searching = true;
            }else{
                $location.path("/");
                this.searching = false;
            }
        }
    };
    return Products;
});

And HTML:

<pagination ng-show="Products.numPages" total-items="Products.totalItems" ng-model="Products.currentPage" max-size="Products.maxSize" class="pagination-small" boundary-links="true" rotate="false" num-pages="Products.numPages"></pagination>

<table class="table table-striped">
    <tr>
        <th>Maker</th>
        <th>Title</th>
        <th ng-bind="product.priceDealer">Dealer Price</th>
        <th>MSRP</th>
    </tr>
    <tr ng-repeat="product in Products.pagedProducts">
        <td>{{product.brand}}</td>
        <td><a href="#/product-detail/{{product.id}}/{{product.title | slug}}">{{product.title}}</a></td>
        <td ng-bind="product.priceDealer | currency"></td>
        <td>{{product.msrp | currency:"$"}}<td>
        </tr>
    </table>
Jazzy
  • 6,029
  • 11
  • 50
  • 74
0

No Need of all that, use attribute of angular UI Bootstrap:

HTML

<pager total-items="totalItems" ng-model="currentPage" items-per-page="itemsPerPage"></pager>

==== and add below code in your controller

===========

$scope.totalItems = $scope.testimonials.length;
$scope.itemsPerPage = 5;
$scope.currentPage = 1;

$scope.$watch('currentPage + itemsPerPage', function () {
        var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
            end = begin + $scope.itemsPerPage;

        $scope.filteredtestimonials= $scope.alerts.slice(begin, end);
    });

===========

Note that you need to mention ng-repeat="testimonial in filteredtestimonials"

and attribute should be in same scope of where you have used you used ng-repeat

Please let me know if you still face any issue and you can see more examples of this on: http://angular-ui.github.io/bootstrap/#/pagination

Do include :

in your page or layout page and items-per-page will not take direct value, it seems

Amit Yadav
  • 31
  • 5