Infinity scroll pagination

Infinity scroll pagination using TypeKit API

by Sajeetharan Sinnathurai

HTML

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container-fluid"> <a class="brand" href="#">Infinity Scroll Pagination in AngularJS</a> 
            <p
            class="navbar-text pull-right"> <a href="http://www.ivivelabs.com" class="navbar-link" target="_blank">iViveLabs</a>
                </p>
        </div>
    </div>
</div>
<div class="container">
    <div ng-controller="ScrollCtrl">
        <div class="row">
            <div class="alert alert-success pull-left small">{{status_bar}}</div>
            <div class="pull-right"><span id="loading"
                class="loading-bar"><span class="label label-success">Loading..</span></span></div>
        </div>
        <div class="row-fluid" id="fixed" when-scrolled="loadMore()">
            <table class="table table-hover table-striped">
                    <tr ng-repeat="family in families">
                        <td>
                            <div class="row-fluid">                                
                                <span class="span12"><span class="badge">{{family.id}}</span></span>
                                <span class="span12"> {{family.name}}<br /> {{family.link}}</span>
                            </div>
                        </td>                                                
                    </tr>
            </table>
        </div>        
        <div class="row">
            <p><div class="alert alert-success pull-left small">{{status_bar}}</div></p>
        </div>
    </div>
</div>

CSS

@import url(http://fonts.googleapis.com/css?family=Roboto+Condensed:400, 700);
 * {
    font-family:roboto;
}
.small {
    font-size:11px;
}

#fixed {
    height: 400px;
    overflow: auto;
    /*border: 1px solid #DDD;*
}

JavaScript

'use strict';

var App = angular.module('PagingApp', ['services.SharedServices']);

App.controller('ScrollCtrl', ['$scope','$filter', 'TypekitService', function($scope, $filter, Typekit){        
    $scope.families = [];
    $scope.status_bar = "";
    
    var page = 1;
    var per_page = 10;
    $scope.loadMore = function() {        
        for (var i = 0; i < 1; i++) {
            Typekit.getTypekits(page, per_page).then(function(res){
                $scope.families = $scope.families.concat(res.data.library.families);
                $scope.status_bar = "Showing " + ($scope.families.length === 0 ? "0" : "1") + " to " + $filter('number')($scope.families.length) + " of " + $filter('number')(res.data.library.pagination.count) + " entries";                
            });                                         
            page +=1;
        }
                
    };
    
    $scope.loadMore();
}]);

App.factory('TypekitService',['$http',function($http){
    return {
        getTypekits : function(page, per_page){
            return $http.jsonp('https://typekit.com/api/v1/json/libraries/full?page='+page+'&per_page='+per_page+'&callback=JSON_CALLBACK');
        }
    }
}]);

App.directive('whenScrolled', function() {
    return function(scope, elm, attr) {
        var raw = elm[0];
        
        elm.bind('scroll', function() {
            if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                scope.$apply(attr.whenScrolled);
            }
        });
    };
});

/** Ajax Spinner **/
angular.module('services.SharedServices', []).config(function($httpProvider) {
	$httpProvider.responseInterceptors.push('myHttpInterceptor');
	var spinnerFunction = function(data, headersGetter) {
			$("#loading").show();
			return data;
		};
	$httpProvider.defaults.transformRequest.push(spinnerFunction);
}).factory('myHttpInterceptor', function($q, $window) {
	return function(promise) {
		return promise.then(function(response)...