Angular+JQ+Bootstrap

by andytjoslin

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
<div id="fixed" ng-controller="MyCtrl" 
    scrolly-list items="items" visible="5">
</div>

CSS

.item {
    width: 100%;
    height: 100px;
    border: 1px solid black;
    overflow: auto;
}
#fixed {
    height: 400px;
    overflow: auto;
}

JavaScript

var app=angular.module('myApp', []);

//Helper function. input: array, min, max. 
//Output: items of array between min and max
function getRange(array, min, max) {
    var range = [], i;
    for (i=min; i<max; i++) 
        range.push(array[i]);
    return range;
}

function MyCtrl($scope) {
    var i;
    $scope.items = [];
    for (i=0; i<100; i++) $scope.items.push(i);
}

app.directive('scrollyList', function($timeout) {
    
    var linkFn = function(scope, elm, attrs) {
        var raw=elm[0];
        elm.bind('scroll', function() {
            if (raw.scrollTop+raw.offsetHeight >= raw.scrollHeight) {
                scope.$broadcast('scroll', 'bottom');
            } else if (raw.scrollTop == 0) {
                scope.$broadcast('scroll', 'top');
            }
        });

        scope.$on('scrollyMove', function(evt, direction, number) {
            var childHeight=100;
            raw.offsetHeight = 0;
        });
    };
    
    var controllerFn = function($scope, $element, $attrs) {
        var visible = parseInt($attrs.visible || 5);
        
        $scope.setRange = function(min, max) {
            console.log(min, max);
            $timeout(function() {
                $scope.displayedItems = getRange($scope.items, min, max);
                $scope.range = [min, max];
            });
        };
        $scope.setRange(0, 5);
       
        $scope.$on('scroll', function(evt, pos) {
            console.log('scroll',pos);
            
            if (pos == 'bottom' && $scope.range[1] < $scope.items.length - 1) {
                $scope.$broadcast('scrollyMove', 'down', 1);
                $scope.setRange($scope.range[0]+5, $scope.range[1]+5);
            } else if (pos == 'top' && $scope.range[0] > 0) {
                $scope.$broadcast('scrollyMove', 'up', 1);
                $scope.setRange($scope.range[0]-5, $scope.range[1]-5);
            }
        });
    };
    
    
    return {
        scope: {
            'items': 'evaluate'
        },
    ...