Skip to content

Instantly share code, notes, and snippets.

@enreeco
Created September 29, 2014 16:24
Show Gist options
  • Save enreeco/b4f48ba209e1d34f3897 to your computer and use it in GitHub Desktop.
Save enreeco/b4f48ba209e1d34f3897 to your computer and use it in GitHub Desktop.
AngularJS fully functional table
<html>
<head>
<style>
.active-link{
font-weight: bold;
color: blue;
cursor: pointer;
}
</style>
</head>
<body ng-app="TableController">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" ></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.15/angular.min.js"></script>
<script type="text/javascript">
var myapp = angular.module('TableController', []);
var ITEMS_PER_PAGE = 5;
var PAGE_LINKS_HISTORY_SIZE = 3;
/*
URL encoding filter
*/
myapp.filter('escape', function() {
return window.escape;
});
/*
Filter to handle offset pagination
*/
myapp.filter('slice', function() {
return function(arr, start, end) {
return (arr || []).slice(start, end);
};
});
/*
Directive to load an input file
*/
myapp.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
}
reader.readAsText(changeEvent.target.files[0]);
});
}
}
}]);
var contrl=myapp.controller('ManagerController', function ($scope, $filter, $location, $anchorScroll, $timeout) {
$scope.recordSet = [
{"FirstName":"Enrico", "LastName":"Murru"},
{"FirstName":"AAndrea", "LastName":"Rossi"},
{"FirstName":"BAndrea", "LastName":"SRossi"},
{"FirstName":"CAndrea", "LastName":"HRossi"},
{"FirstName":"DAndrea", "LastName":"YRossi"},
{"FirstName":"FAndrea", "LastName":"RRossi"},
{"FirstName":"GAndrea", "LastName":"MRossi"},
{"FirstName":"GAndrea", "LastName":"DRossi"},
{"FirstName":"TAndrea", "LastName":"NRossi"},
{"FirstName":"DAndrea", "LastName":"LRossi"},
{"FirstName":"KAndrea", "LastName":"ETRossi"},
{"FirstName":"UAndrea", "LastName":"DVRossi"},
{"FirstName":"VAndrea", "LastName":"FNRossi"},
{"FirstName":"SDAndrea", "LastName":"GYRossi"},
{"FirstName":"DFAndrea", "LastName":"HRRossi"},
{"FirstName":"FGAndrea", "LastName":"FMRossi"},
{"FirstName":"GGAndrea", "LastName":"DDRossi"},
{"FirstName":"HTAndrea", "LastName":"GNRossi"},
{"FirstName":"JDAndrea", "LastName":"MLRossi"},
{"FirstName":"KKAndrea", "LastName":"DTRossi"},
{"FirstName":"LUAndrea", "LastName":"DVRossi"},
{"FirstName":"òVAndrea", "LastName":"DNRossi"},
{"FirstName":"FAndrea", "LastName":"SRRossi"},
{"FirstName":"GAndrea", "LastName":"DFMRossi"},
{"FirstName":"GAndrea", "LastName":"DGRossi"},
{"FirstName":"TAndrea", "LastName":"NHRossi"},
{"FirstName":"DAndGrea", "LastName":"LRGossi"},
{"FirstName":"KAndrea", "LastName":"ETRBossi"},
{"FirstName":"UAndrea", "LastName":"DVRoFCssi"},
{"FirstName":"VAnGdrea", "LastName":"FNRosFsi"},
{"FirstName":"SDAndrea", "LastName":"GYRoGssi"},
{"FirstName":"DFAGndrea", "LastName":"HRRosBNsi"},
{"FirstName":"FGAndrea", "LastName":"FMRossBi"},
{"FirstName":"GGAndrea", "LastName":"DDRossi"},
{"FirstName":"HTAndrea", "LastName":"GNGRossi"},
{"FirstName":"JDAndrea", "LastName":"MLGRossi"},
{"FirstName":"KKAGndrea", "LastName":"DTGRossi"},
{"FirstName":"LUAnGdrea", "LastName":"DVGRossi"},
{"FirstName":"òVAGndrea", "LastName":"DNGRossi"},
{"FirstName":"FAndrea", "LastName":"SRRossi"},
{"FirstName":"GAndrea", "LastName":"DFMRossi"},
{"FirstName":"GAndrea", "LastName":"DGRossi"},
{"FirstName":"TAndrea", "LastName":"NHRossi"},
{"FirstName":"DAndGrea", "LastName":"LRGossi"},
{"FirstName":"KAndrea", "LastName":"ETRBossi"},
{"FirstName":"UAndrea", "LastName":"DVRoFCssi"},
{"FirstName":"VAnGdrea", "LastName":"FNRosFsi"},
{"FirstName":"SDAndrea", "LastName":"GYRoGssi"},
{"FirstName":"DFAGndrea", "LastName":"HRRosBNsi"},
{"FirstName":"FGAndrea", "LastName":"FMRossBi"},
{"FirstName":"GGAndrea", "LastName":"DDRossi"},
{"FirstName":"HTAndrea", "LastName":"GNGRossi"},
{"FirstName":"JDAndrea", "LastName":"MLGRossi"},
{"FirstName":"KKAGndrea", "LastName":"DTGRossi"},
{"FirstName":"LUAnGdrea", "LastName":"DVGRossi"},
{"FirstName":"òVAGndrea", "LastName":"DNGRossi"},
];
//pagination
$scope.filteredLabels = []; //this is set in the ng-repeat => allow to filter before pagination
$scope.itemsPerPage = ITEMS_PER_PAGE;
$scope.currentPage = 0;
$scope.prevPage = function(offset) {
if(!offset) offset = 1;
if ($scope.currentPage-(offset-1) > 0) {
$scope.currentPage-=offset;
}
};
$scope.prevPageDisabled = function(offset) {
if(!offset) offset = 1;
return $scope.currentPage-(offset-1) <= 0;
};
$scope.pageCount = function() {
if(!$scope.recordSet || !$scope.recordSet.length) return 0;
return Math.ceil($scope.recordSet.length/$scope.itemsPerPage)-1;
};
$scope.nextPage = function(offset) {
if(!offset) offset = 1;
if(!$scope.recordSet || !$scope.recordSet.length) return;
if ($scope.currentPage+(offset-1) < $scope.pageCount()) {
$scope.currentPage+=offset;
}
};
$scope.nextPageDisabled = function(offset) {
if(!offset) offset = 1;
return $scope.currentPage+(offset-1) >= $scope.pageCount();
};
$scope.range = function(){
if(!$scope.recordSet || !$scope.recordSet.length) return [];
var range = [];
for(var i = $scope.currentPage-PAGE_LINKS_HISTORY_SIZE; i <$scope.currentPage+PAGE_LINKS_HISTORY_SIZE; i++ ){
if(i>=0 && i <= $scope.pageCount()) range.push(i);
}
return range;
//return Array.apply(null, Array($scope.pageCount()+1)).map(function (_, i) {return i;});
}
$scope.setPage = function(pagen){
$scope.currentPage = pagen;
}
/*
Scroll to the label
*/
$scope.scrollToLabel = function (labelName) {
$location.hash('_row_'+labelName);
$anchorScroll();
}
});
</script>
<div ng-controller="ManagerController">
<div>
Show: <select ng-model="itemsPerPage">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<br/>
<span ng-show="!prevPageDisabled(10)">
<a class="active-link" ng-click="prevPage(10)" >Prev 10</a>&nbsp;
</span>
<a ng-click="prevPage()" class="active-link" ng-show="!prevPageDisabled()">Prev</a>
<span ng-show="prevPageDisabled()">Prev</span>&nbsp;
<span ng-repeat="n in range()" ng-class="{'active-page': n == currentPage}">
<a ng-click="setPage(n)" class="active-link" ng-show="n != currentPage">{{n+1}}</a>
<span ng-show="n == currentPage">{{n+1}}</span>
&nbsp;
</span>
<a class="active-link" ng-click="nextPage()" ng-show="!nextPageDisabled()">Next</a>
<span ng-show="nextPageDisabled()">Next</span>&nbsp;
<span ng-show="!nextPageDisabled(10)">
<a class="active-link" ng-click="nextPage(10)" >Next 10</a>&nbsp;
</span>
</div>
<label>Filter:</label><input type="text" ng-model="filterSearch" />
<table class="list" border="0" cellpadding="0" cellspacing="0" ng-init="sortField = 'FirstName'">
<thead class="rich-table-thead">
<tr class="headerRow">
<th class="headerRow" scope="col" colspan="1" >
<div>
<a class="mouse-over no-selection" ng-click="sortField = 'FirstName'; sortReverse=!sortReverse">
First Name
<span ng-show="!sortReverse" class="active-link">^</span>
<span ng-show="sortReverse" class="active-link">v</span>
</a>
</div>
</th>
<th class="headerRow" scope="col" colspan="1" >
<div>
<a class="mouse-over no-selection" ng-click="sortField = 'LastName'; sortReverse=!sortReverse">
Last Name
<span ng-show="!sortReverse" class="active-link">^</span>
<span ng-show="sortReverse" class="active-link">v</span>
</a>
</div>
</th>
</tr>
</thead>
<tbody>
<tr class="dataRow" ng-class-odd="'oddclass'" ng-class-even="'evenclass'"
ng-repeat="record in (filteredRecords = (recordSet | orderBy: sortField : sortReverse | filter: filterSearch)) | slice:(currentPage*itemsPerPage):(currentPage*itemsPerPage)+itemsPerPage">
<td class="dataCell">
{{record.FirstName}}
</td>
<td class="dataCell">
{{record.LastName}}
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment