Historical Stock Quote Price

HTML

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="StockHistoryApp" ng-controller="StockHistoryController">
    <thead>
        <tr>
            <th colspan="4"><b>Historical Stock Quote Price<b/></th>
        </tr>
    </thead>
    <tbody when-scroll-ends="loadMoreRecords()">
        <tr ng-repeat="stock in stockList">
            <td>{{stock.dateValue | date:'mediumDate'}}</td>
            <td>{{stock.price | currency:'$':2}}</td>
        </tr>
    </tbody>
</table>

CSS

thead {
    background: lightgray;
    align-content: center;
}
tbody {
    display:block;
    overflow:auto;
    height:250px;
    border-collapse: collapse;
}
th {
    height:40px;
    width:auto;
    border: 1px solid black;
    text-align: center;
}
td {
    height:30px;
    width:120px;
    margin:0px;
    padding: 5px;
    border: 1px solid black;
}

JavaScript

(function () {
    'use strict';

    var appModule = angular.module('StockHistoryApp', []);

    appModule.constant('chunkSize', 50);

    appModule.controller('StockHistoryController', function ($scope, chunkSize) {
        $scope.stockList = [];

        var currentIndex = 0;
        var todayDate = new Date();
        $scope.loadMoreRecords = function () {
            // Mocking stock values 
            // In an real application, data would be retrieved from an external system

            var stock;
            var i = 0;
            while (i < chunkSize) {
                currentIndex++;
                var newDate = new Date();
                newDate.setDate(todayDate.getDate() - currentIndex);
                if (newDate.getDay() >= 1 && newDate.getDay() <= 5) {
                    stock = {
                        dateValue: newDate,
                        price: 20.0 + Math.random() * 10
                    };
                    $scope.stockList.push(stock);
                    i++;
                }
            }
        };

        $scope.loadMoreRecords();
    });

    appModule.directive('whenScrollEnds', function () {
        return {
            restrict: "A",
            link: function (scope, element, attrs) {
                var processingScroll = false;

                var visibleHeight = element.height();
                var threshold = 100;

                element.scroll(function () {
                    var scrollableHeight = element.prop('scrollHeight');
                    var hiddenContentHeight = scrollableHeight - visibleHeight;

                    if (hiddenContentHeight - element.scrollTop() <= threshold) {
                        // Scroll is almost at the bottom. Loading more rows
                        scope.$apply(attrs.whenScrollEnds);
                    }
                });
            }
        };
    });

}());