<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.6/smart-table.min.js"></script>
<script src="smart-table-improved.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.css" />
</head>
<body>
<section ng-controller="demoCtrl">
<table class="table" st-table="displayedCollection" st-safe-src="rowCollection" sti-table default-sort="age" default-sort-reverse="true">
<thead>
<tr>
<th st-sort="id" st-skip-natural="true">ID</th>
<th st-sort="name">Name</th>
<th st-soft="firstName">First Name</th>
<th st-sort="age">Age</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.firstName }}</td>
<td>{{ row.age }}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="15" st-displayed-pages="10"></div>
</td>
</tr>
</tfoot>
</table>
</section>
</body>
</html>
var appModule = angular.module('myApp', ['smart-table-improved', 'ui.bootstrap']);
appModule.controller('demoCtrl', ['$scope', function ($scope) {
$scope.rowCollection = [
{id: 1, name: 'Renard', firstName: 'Laurent', age: 66},
{id: 2, name: 'Francoise', firstName: 'Frere', age: 99},
{id: 3, name: 'Renard', firstName: 'Olivier', age: 33},
{id: 4, name: 'Leponge', firstName: 'Bob', age: 22},
{id: 5, name: 'Faivre', firstName: 'Blandine', age: 44},
{id: 6, name: 'Seth', firstName: 'Blick', age: 54},
{id: 7, name: 'Rebecca', firstName: 'Welch', age: 29},
{id: 8, name: 'Felton', firstName: 'Auer', age: 58},
{id: 9, name: 'Ramiro', firstName: 'Crona', age: 60},
{id: 10, name: "Skiles", firstName: "Ashley", age: 46},
{id: 11, name: "Jenkins", firstName: "Nicola", age: 10},
{id: 12, name: "Cruickshank", firstName: "Jeanie", age: 87},
{id: 13, name: "Gutkowski", firstName: "Elmo", age: 92},
{id: 14, name: "Reichert", firstName: "Monique", age: 17},
{id: 15, name: "Champlin", firstName: "Cristal", age: 82},
{id: 16, name: "Ward", firstName: "Leilani", age: 79},
{id: 17, name: "Kunde", firstName: "Yazmin", age: 87},
{id: 18, name: "Langworth", firstName: "Ed", age: 71},
{id: 19, name: "Hodkiewicz", firstName: "Talia", age: 77},
{id: 20, name: "O'Kon", firstName: "Dortha", age: 50},
{id: 21, name: "Jakubowski", firstName: "Vinnie", age: 32},
{id: 22, name: "Conroy", firstName: "Otis", age: 9},
{id: 23, name: "Sauer", firstName: "Phyllis", age: 85},
{id: 24, name: "Senger", firstName: "Ike", age: 47},
{id: 25, name: "Durgan", firstName: "Delfina", age: 67},
{id: 26, name: "Herman", firstName: "Gennaro", age: 52},
{id: 27, name: "Fay", firstName: "Antonina", age: 45},
{id: 28, name: "Swaniawski", firstName: "Hobart", age: 11},
{id: 29, name: "Lockman", firstName: "Nathaniel", age: 5},
{id: 30, name: "Dach", firstName: "Hassan", age: 36},
{id: 31, name: "Christiansen", firstName: "Reilly", age: 42},
{id: 32, name: "Ruecker", firstName: "Abe", age: 75},
{id: 33, name: "Barton", firstName: "Arlie", age: 18},
{id: 34, name: "Frami", firstName: "Ada", age: 88},
{id: 35, name: "Morissette", firstName: "Kathlyn", age: 93},
{id: 36, name: "Gusikowski", firstName: "Jeanette", age: 98},
{id: 37, name: "Rempel", firstName: "Nichole", age: 50},
{id: 38, name: "Swaniawski", firstName: "Selena", age: 76},
{id: 39, name: "Koch", firstName: "Madaline", age: 66},
{id: 40, name: "Wisoky", firstName: "Jeffrey", age: 49},
{id: 41, name: "Crooks", firstName: "Marcelle", age: 15},
{id: 42, name: "Ebert", firstName: "Elbert", age: 5},
{id: 43, name: "Stark", firstName: "Sarina", age: 80},
{id: 44, name: "Reynolds", firstName: "Weldon", age: 97},
{id: 45, name: "Schmitt", firstName: "Ettie", age: 11},
{id: 46, name: "Wyman", firstName: "Timmy", age: 70},
{id: 47, name: "Hessel", firstName: "Irving", age: 71},
{id: 48, name: "Corkery", firstName: "Callie", age: 59},
{id: 49, name: "Wyman", firstName: "Abdul", age: 45},
{id: 50, name: "Treutel", firstName: "Ova", age: 79},
{id: 51, name: "Lind", firstName: "Mikel", age: 59},
{id: 52, name: "Schuppe", firstName: "Rogers", age: 29},
{id: 53, name: "Heaney", firstName: "Kiana", age: 78},
{id: 54, name: "Jakubowski", firstName: "Allen", age: 94},
{id: 55, name: "Kilback", firstName: "Gianni", age: 5},
{id: 56, name: "Kunde", firstName: "Telly", age: 39},
{id: 57, name: "Jenkins", firstName: "Johnathon", age: 24},
{id: 58, name: "Zieme", firstName: "Jacinthe", age: 92},
{id: 59, name: "Stamm", firstName: "Mitchell", age: 87},
{id: 60, name: "Homenick", firstName: "Seamus", age: 43},
{id: 61, name: "Morissette", firstName: "Nathanial", age: 15},
{id: 62, name: "Heaney", firstName: "Itzel", age: 31},
{id: 63, name: "Champlin", firstName: "Wilburn", age: 84},
{id: 64, name: "Hackett", firstName: "Kaya", age: 32},
{id: 65, name: "Bechtelar", firstName: "Abbie", age: 30},
{id: 66, name: "Armstrong", firstName: "Stephan", age: 17},
{id: 67, name: "Weber", firstName: "Jayme", age: 82},
{id: 68, name: "Streich", firstName: "Ora", age: 92},
{id: 69, name: "Hilll", firstName: "Ruthie", age: 90},
{id: 70, name: "Brekke", firstName: "Lewis", age: 5},
{id: 71, name: "Feeney", firstName: "Alba", age: 45},
{id: 72, name: "McCullough", firstName: "Sienna", age: 24},
{id: 73, name: "Bogan", firstName: "Heidi", age: 39},
{id: 74, name: "Johnson", firstName: "Sherwood", age: 2},
{id: 75, name: "Bergnaum", firstName: "Jaeden", age: 8},
{id: 76, name: "Hills", firstName: "Amari", age: 27},
{id: 77, name: "Maggio", firstName: "Haylie", age: 56},
{id: 78, name: "Barton", firstName: "Monserrat", age: 72},
{id: 79, name: "Marvin", firstName: "Monserrat", age: 93},
{id: 80, name: "Morissette", firstName: "Ezra", age: 40},
{id: 81, name: "Schuster", firstName: "Kari", age: 37},
{id: 82, name: "Dooley", firstName: "Sister", age: 22},
{id: 83, name: "Williamson", firstName: "Monroe", age: 32},
{id: 84, name: "Wisoky", firstName: "Delbert", age: 30},
{id: 85, name: "Hoppe", firstName: "Ludwig", age: 45},
{id: 86, name: "Kuphal", firstName: "Nina", age: 66},
{id: 87, name: "Casper", firstName: "Gretchen", age: 26},
{id: 88, name: "Prosacco", firstName: "Lera", age: 82},
{id: 89, name: "Little", firstName: "Velda", age: 55},
{id: 90, name: "Jakubowski", firstName: "Stanford", age: 30},
{id: 91, name: "Turner", firstName: "Cornell", age: 60},
{id: 92, name: "Ankunding", firstName: "Oswaldo", age: 49},
{id: 93, name: "Cummerata", firstName: "Hortense", age: 89},
{id: 94, name: "Denesik", firstName: "Christy", age: 23},
{id: 95, name: "Moen", firstName: "Berenice", age: 92},
{id: 96, name: "Bernier", firstName: "Carolyn", age: 26},
{id: 97, name: "Padberg", firstName: "Augustus", age: 94},
{id: 98, name: "Farrell", firstName: "Libby", age: 41},
{id: 99, name: "Lemke", firstName: "Skyla", age: 74},
{id: 100, name: "O'Conner", firstName: "Jordy", age: 33},
{id: 101, name: "Moore", firstName: "Sarai", age: 78},
{id: 102, name: "Orn", firstName: "Adelle", age: 78},
{id: 103, name: "Feeney", firstName: "Lucienne", age: 84},
{id: 104, name: "Runolfsdottir", firstName: "Mariane", age: 49},
{id: 105, name: "Jast", firstName: "Myrna", age: 19},
{id: 106, name: "Blick", firstName: "Toni", age: 98},
{id: 107, name: "Kassulke", firstName: "Mohamed", age: 51},
{id: 108, name: "Hermiston", firstName: "Okey", age: 51},
{id: 109, name: "Hamill", firstName: "Eli", age: 92},
{id: 110, name: "Macejkovic", firstName: "Elise", age: 86},
{id: 111, name: "Wyman", firstName: "Dewayne", age: 75},
{id: 112, name: "Sporer", firstName: "Barbara", age: 92},
{id: 113, name: "Schultz", firstName: "Danial", age: 44},
{id: 114, name: "Ritchie", firstName: "Sallie", age: 9},
{id: 115, name: "Hartmann", firstName: "Nyasia", age: 80},
{id: 116, name: "Harvey", firstName: "Helen", age: 86},
{id: 117, name: "Connelly", firstName: "Jeramy", age: 23},
{id: 118, name: "Grant", firstName: "Mattie", age: 14},
{id: 119, name: "Lemke", firstName: "Madisyn", age: 4},
{id: 120, name: "Nolan", firstName: "Cristobal", age: 75},
{id: 121, name: "Sawayn", firstName: "Teagan", age: 34},
{id: 122, name: "Murray", firstName: "Robbie", age: 33},
{id: 123, name: "Wilkinson", firstName: "King", age: 29},
{id: 124, name: "Yost", firstName: "Jamison", age: 51},
{id: 125, name: "Armstrong", firstName: "Natalia", age: 6},
{id: 126, name: "Crist", firstName: "Dino", age: 5},
{id: 127, name: "Emmerich", firstName: "Rosalia", age: 65},
{id: 128, name: "Balistreri", firstName: "Prudence", age: 38},
{id: 129, name: "Wehner", firstName: "Lucinda", age: 40},
{id: 130, name: "Kunde", firstName: "Angelina", age: 84},
{id: 131, name: "Abshire", firstName: "Walter", age: 72},
{id: 132, name: "Dibbert", firstName: "Jabari", age: 96},
{id: 133, name: "Dicki", firstName: "Jean", age: 94},
{id: 134, name: "Simonis", firstName: "Webster", age: 62},
{id: 135, name: "Eichmann", firstName: "Caleb", age: 70},
{id: 136, name: "Thompson", firstName: "Oran", age: 92},
{id: 137, name: "Bauch", firstName: "Jackeline", age: 64},
{id: 138, name: "Ryan", firstName: "Nasir", age: 5},
{id: 139, name: "Bruen", firstName: "Melba", age: 45},
{id: 140, name: "Larson", firstName: "Ross", age: 97},
{id: 141, name: "Kreiger", firstName: "Shawn", age: 56},
{id: 142, name: "Jerde", firstName: "Idell", age: 92},
{id: 143, name: "Metz", firstName: "Audie", age: 50},
{id: 144, name: "Jenkins", firstName: "Dahlia", age: 57},
{id: 145, name: "Russel", firstName: "Domenic", age: 23},
{id: 146, name: "Wisozk", firstName: "Dillon", age: 5},
{id: 147, name: "Konopelski", firstName: "Lacy", age: 35},
{id: 148, name: "Ryan", firstName: "Arnoldo", age: 30},
{id: 149, name: "Kulas", firstName: "Edison", age: 15},
{id: 150, name: "Hilpert", firstName: "Wade", age: 46},
{id: 151, name: "Kshlerin", firstName: "Adriana", age: 89},
{id: 152, name: "Mayert", firstName: "Joan", age: 87},
{id: 153, name: "MacGyver", firstName: "Reynold", age: 73},
{id: 154, name: "Lesch", firstName: "Freddy", age: 26},
{id: 155, name: "Powlowski", firstName: "Gladys", age: 40},
{id: 156, name: "Roob", firstName: "Jeff", age: 10},
{id: 157, name: "Kessler", firstName: "Elisa", age: 75},
{id: 158, name: "Quitzon", firstName: "Carlie", age: 52},
{id: 159, name: "Langosh", firstName: "Daisha", age: 63},
{id: 160, name: "Volkman", firstName: "Shaina", age: 11},
{id: 161, name: "Zieme", firstName: "Jasen", age: 98},
{id: 162, name: "Huels", firstName: "Thea", age: 47},
{id: 163, name: "Gutmann", firstName: "Cristina", age: 60},
{id: 164, name: "Goodwin", firstName: "Madaline", age: 37},
{id: 165, name: "Mann", firstName: "Isaac", age: 36},
{id: 166, name: "Haag", firstName: "Julianne", age: 4},
{id: 167, name: "Bergnaum", firstName: "Enrique", age: 80},
{id: 168, name: "Kilback", firstName: "Moses", age: 92},
{id: 169, name: "Kuhn", firstName: "Devante", age: 10},
{id: 170, name: "Marks", firstName: "Kelsie", age: 95},
{id: 171, name: "Spinka", firstName: "Walton", age: 47},
{id: 172, name: "Nader", firstName: "Cordell", age: 30},
{id: 173, name: "Paucek", firstName: "Carmelo", age: 33},
{id: 174, name: "Gerhold", firstName: "Thomas", age: 33},
{id: 175, name: "Casper", firstName: "Albertha", age: 3},
{id: 176, name: "Medhurst", firstName: "Lucinda", age: 17},
{id: 177, name: "Brown", firstName: "Garrett", age: 53},
{id: 178, name: "Sporer", firstName: "Eldon", age: 29},
{id: 179, name: "Ernser", firstName: "Katharina", age: 80},
{id: 180, name: "Schultz", firstName: "Edd", age: 61},
{id: 181, name: "Bruen", firstName: "Georgiana", age: 6},
{id: 182, name: "Hane", firstName: "Estefania", age: 66},
{id: 183, name: "Denesik", firstName: "Armani", age: 42},
{id: 184, name: "Larson", firstName: "Euna", age: 19},
{id: 185, name: "Waelchi", firstName: "Jammie", age: 92},
{id: 186, name: "Durgan", firstName: "Bernhard", age: 93},
{id: 187, name: "Altenwerth", firstName: "Zoe", age: 70},
{id: 188, name: "Grady", firstName: "Reymundo", age: 58},
{id: 189, name: "Cruickshank", firstName: "Trent", age: 78},
{id: 190, name: "Jakubowski", firstName: "Raheem", age: 92},
{id: 191, name: "Lueilwitz", firstName: "Alaina", age: 8},
{id: 192, name: "Cormier", firstName: "Aurelia", age: 35},
{id: 193, name: "Runolfsson", firstName: "Terrill", age: 39},
{id: 194, name: "Miller", firstName: "Jeramie", age: 99},
{id: 195, name: "Schowalter", firstName: "Porter", age: 59},
{id: 196, name: "Parisian", firstName: "Baby", age: 63},
{id: 197, name: "Kautzer", firstName: "Kyler", age: 4},
{id: 198, name: "Kreiger", firstName: "Godfrey", age: 97},
{id: 199, name: "Heathcote", firstName: "Sophia", age: 81}
];
}]);
.st-sort-ascent:before{
content: '\25B2';
}
.st-sort-descent:before{
content: '\25BC';
}
/*
* angular-smart-table-improved v0.4.1
* https://github.com/timonwong/smart-table-improved
*
* (c) 2016 Timon Wong
* License: MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('angular')) :
typeof define === 'function' && define.amd ? define(['angular'], factory) :
factory(global.angular);
}(this, function (angular) { 'use strict';
angular.module('smart-table-improved.templates', []);
angular.module('smart-table-improved', ['smart-table', 'smart-table-improved.templates']);
var prefix = 'stiTable';
var EventNames = {
rowSelected: prefix + ':rowSelected'
};
angular.module('smart-table-improved').controller('StiTableController', StiTableController).directive('stiTable', stiTable);
/**
* @ngdoc controller
* @name smart-table-improved.controller:StiTableController
* @description
* Controller used by `stiTable`
*/
StiTableController.$inject = ['$scope'];
function StiTableController($scope) {
var ctrl = this;
$scope.$stiSelected = {};
$scope.$stiNumSelected = 0;
ctrl.isSelected = isSelected;
ctrl.select = select;
ctrl.updateSelectedStatus = updateSelectedStatus;
/**
* Return true if the row is selected.
* @param {Object} row
* @returns {Boolean}
*/
function isSelected(row) {
var rowIdField = $scope.$stiRowIdField;
var rowState = $scope.$stiSelected[row[rowIdField]];
return rowState && rowState.checked;
}
/**
* Set row checked state
* @param {Object} row
* @param {Boolean} checkedState
* @param {Boolean} broadcast (default false)
*/
function select(row, checkedState) {
var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var _ref$broadcast = _ref.broadcast;
var broadcast = _ref$broadcast === undefined ? false : _ref$broadcast;
var rowIdField = $scope.$stiRowIdField;
$scope.$stiSelected[row[rowIdField]] = {
checked: checkedState,
row: row
};
if (checkedState) {
$scope.$stiNumSelected++;
} else {
$scope.$stiNumSelected--;
}
if (broadcast) {
var rowObj = {
row: row,
checked: checkedState
};
$scope.$broadcast(EventNames.rowSelected, rowObj);
}
}
/**
* Update current selection status from latest collection
*/
function updateSelectedStatus(collection) {
var rowIdField = $scope.$stiRowIdField;
var lastSelected = $scope.$stiSelected;
var nextSelected = {};
var nextNumSelected = 0;
angular.forEach(collection, function (item) {
var id = item[rowIdField];
var selectedItem = lastSelected[id];
if (!selectedItem) {
return;
}
nextSelected[id] = selectedItem;
if (selectedItem.checked) {
nextNumSelected++;
}
});
$scope.$stiNumSelected = nextNumSelected;
$scope.$stiSelected = nextSelected;
}
}
/**
* @ngdoc directive
* @name smart-table-improved.directive:stiTable
* @restrict A
* @scope true
*
* @description
* The stiTable directive is a helper to stTable directive.
*
* @element table st-table='rowCollection'
* @param {string} defaultSort
* @param {Boolean} defaultSortReverse (default false)
* @param {Expression} onPagination Expression to evaluate upon pagination state
* changes. (Pagination object is available as $pagination, with `currentPage`,
* `numberOfPages` and `totalItemCount` inside)
* @param {string} rowIdField (default '$$hashkey')
* @param {string|Boolean} trackSelectedMode (default false)
*
*/
stiTable.$inject = ['$parse'];
function stiTable($parse) {
return {
restrict: 'A',
require: ['stTable', 'stiTable'],
scope: true,
controller: 'StiTableController',
controllerAs: 'stiTableCtrl',
link: link
};
function link(scope, element, attrs, ctrls) {
var stTableCtrl = ctrls[0];
var stiTableCtrl = ctrls[1];
scope.$stiRowIdField = angular.isDefined(attrs.rowIdField) ? attrs.rowIdField : '$$hashKey';
if (attrs.trackSelectedMode === 'all') {
// Track all collection (from st-safe-src attribute)
scope.$watchCollection(attrs.stSafeSrc, stiTableCtrl.updateSelectedStatus.bind(stiTableCtrl));
} else if (attrs.trackSelectedMode === 'displayed') {
// Track displayed collection only
scope.$watchCollection(attrs.stTable, stiTableCtrl.updateSelectedStatus.bind(stiTableCtrl));
}
if (attrs.defaultSort) {
var reverse = angular.isDefined(attrs.defaultSortReverse) ? scope.$parent.$eval(attrs.defaultSortReverse) : false;
stTableCtrl.sortBy(attrs.defaultSort, reverse);
}
var onPaginationHandler = undefined;
if (attrs.onPagination) {
onPaginationHandler = $parse(attrs.onPagination);
scope.$watch(function () {
return stTableCtrl.tableState().pagination;
}, handlePaginationChange, true);
}
function handlePaginationChange() {
var paginationState = stTableCtrl.tableState().pagination;
var pagination = {
currentPage: Math.floor(paginationState.start / paginationState.number) + 1,
numberOfPages: paginationState.numberOfPages,
totalItemCount: paginationState.totalItemCount
};
onPaginationHandler(scope, { $pagination: pagination });
}
}
}
angular.module('smart-table-improved').constant('stiPaginationConfig', {
itemsPerPage: 10,
maxSize: 10,
templateUrl: 'sti/template/sti-pagination.html'
}).directive('stiPagination', stiPagination);
stiPagination.$inject = ['stiPaginationConfig'];
function stiPagination(stiPaginationConfig) {
return {
restrict: 'EA',
require: '^stTable',
scope: {
itemsPerPage: '=?',
maxSize: '=?',
onPageChange: '&',
autoHide: '=?'
},
templateUrl: function templateUrl(element, attrs) {
return attrs.templateUrl || stiPaginationConfig.templateUrl;
},
link: link
};
function link(scope, element, attrs, ctrl) {
scope.itemsPerPage = scope.itemsPerPage ? scope.itemsPerPage : stiPaginationConfig.itemsPerPage;
scope.maxSize = scope.maxSize ? scope.maxSize : stiPaginationConfig.maxSize;
scope.autoHide = angular.isDefined(scope.autoHide) ? scope.autoHide : false;
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;
scope.paginationClass = attrs.paginationClass || '';
var paginationRange = Math.max(scope.maxSize, 5);
scope.pages = [];
scope.pagination = {
last: 1,
current: 1
};
scope.range = {
lower: 1,
upper: 1
};
// table state --> view
scope.$watch(function () {
return ctrl.tableState().pagination;
}, redraw, true);
// scope --> table state (--> view)
scope.$watch('itemsPerPage', function (newValue, oldValue) {
if (newValue !== oldValue) {
scope.selectPage(1);
}
});
scope.$watch('maxSize', redraw);
// view -> table state
scope.selectPage = function (page) {
if (page > 0 && page <= scope.numPages) {
ctrl.slice((page - 1) * scope.itemsPerPage, scope.itemsPerPage);
}
};
if (!ctrl.tableState().pagination.number) {
ctrl.slice(0, scope.itemsPerPage);
}
/**
* Custom "track by" function which allows for duplicate "..." entries on long lists,
* yet fixes the problem of wrongly-highlighted links which happens when using
* "track by $index" - see https://github.com/michaelbromley/angularUtils/issues/153
* @param id
* @param index
* @returns {string}
*/
scope.tracker = function (id, index) {
return id + '_' + index;
};
function redraw() {
var paginationState = ctrl.tableState().pagination;
var prevPage = scope.currentPage;
scope.currentPage = Math.floor(paginationState.start / paginationState.number) + 1;
scope.totalItemCount = paginationState.totalItemCount;
scope.numPages = paginationState.numberOfPages;
scope.pages = generatePagesArray(scope.currentPage, paginationState.totalItemCount, scope.itemsPerPage, paginationRange);
scope.range.lower = paginationState.start + 1;
scope.range.upper = paginationState.start + paginationState.number + 1;
if (prevPage !== scope.currentPage) {
scope.onPageChange({ newPage: scope.currentPage });
}
}
}
/**
* Generate an array of page numbers (or the '...' string) which is used in an ng-repeat to generate the
* links used in pagination
*
* @param currentPage
* @param rowsPerPage
* @param paginationRange
* @param collectionLength
* @returns {Array}
*/
function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) {
var pages = [];
var totalPages = Math.ceil(collectionLength / rowsPerPage);
var halfWay = Math.ceil(paginationRange / 2);
var position = undefined;
if (currentPage <= halfWay) {
position = 'start';
} else if (totalPages - halfWay < currentPage) {
position = 'end';
} else {
position = 'middle';
}
var ellipsesNeeded = paginationRange < totalPages;
var i = 1;
while (i <= totalPages && i <= paginationRange) {
var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages);
var openingEllipsesNeeded = i === 2 && (position === 'middle' || position === 'end');
var closingEllipsesNeeded = i === paginationRange - 1 && (position === 'middle' || position === 'start');
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
pages.push('...');
} else {
pages.push(pageNumber);
}
i++;
}
return pages;
}
/**
* Given the position in the sequence of pagination links [i], figure out what page number corresponds to that position.
*
* @param i
* @param currentPage
* @param paginationRange
* @param totalPages
* @returns {*}
*/
function calculatePageNumber(i, currentPage, paginationRange, totalPages) {
var halfWay = Math.ceil(paginationRange / 2);
if (i === paginationRange) {
return totalPages;
} else if (i === 1) {
return i;
} else if (paginationRange < totalPages) {
if (totalPages - halfWay < currentPage) {
return totalPages - paginationRange + i;
} else if (halfWay < currentPage) {
return currentPage - halfWay + i;
} else {
return i;
}
} else {
return i;
}
}
}
angular.module('smart-table-improved').directive('stiSelect', stiSelect);
stiSelect.$inject = [];
function stiSelect() {
return {
restrict: 'A',
require: '^stiTable',
scope: {
row: '=stiSelect'
},
link: link
};
function link(scope, element, attrs, ctrl) {
var stiTableCtrl = ctrl;
element.on('click', clickHandler);
// Select or unselect row
function clickHandler() {
scope.$apply(function () {
var checkedState = element.prop('checked');
stiTableCtrl.select(scope.row, checkedState, { broadcast: true });
});
}
}
}
angular.module('smart-table-improved').directive('stiSelectAll', stiSelectAll);
stiSelectAll.$inject = [];
function stiSelectAll() {
return {
restrict: 'A',
require: ['^stiTable', '^stTable'],
scope: {
rows: '=stiSelectAll'
},
link: link
};
function link(scope, element, attrs, ctrls) {
var stiTableCtrl = ctrls[0];
var stTableCtrl = ctrls[1];
element.on('click', clickHandler);
// Watch the table state for changes (sort, filter, pagination, etc)
scope.$watch(function () {
return stTableCtrl.tableState();
}, updateRowCheckState, true);
// Watch the row length for added/removed rows
scope.$watch('rows.length', updateRowCheckState);
// Watch for row selection
scope.$on(EventNames.rowSelected, updateRowCheckState);
// Toggle checked state for "select all" checkbox
function clickHandler() {
scope.$apply(function () {
var checked = element.prop('checked');
angular.forEach(scope.rows, function (row) {
var selected = stiTableCtrl.isSelected(row);
if (selected !== checked) {
stiTableCtrl.select(row, checked);
}
});
});
}
// Update "select all" checkbox when table state changes
function updateRowCheckState() {
var visibleRows = scope.rows;
var numVisibleRows = visibleRows.length;
var checkedCount = visibleRows.filter(stiTableCtrl.isSelected).length;
element.prop('checked', numVisibleRows > 0 && numVisibleRows === checkedCount);
}
}
}
angular.module("smart-table-improved.templates").run(["$templateCache", function ($templateCache) {
$templateCache.put("sti/template/sti-pagination.html", "<ul class=\"pagination {{ paginationClass }}\" ng-if=\"pages.length > 1 || !autoHide\">\n <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: currentPage === 1}\">\n <a href=\"\" ng-click=\"selectPage(1)\">«</a>\n </li>\n <li ng-if=\"::directionLinks\" ng-class=\"{disabled: currentPage === 1}\">\n <a href=\"\" ng-click=\"selectPage(currentPage - 1)\">‹</a>\n </li>\n <li ng-repeat=\"pageNumber in pages track by tracker(pageNumber, $index)\" ng-class=\"{active: currentPage === pageNumber, disabled: pageNumber === \'...\'}\" class=\"pagenumbers\">\n <a href=\"\" ng-click=\"selectPage(pageNumber)\">{{ pageNumber }}</a>\n </li>\n <li ng-if=\"::directionLinks\" ng-class=\"{disabled: currentPage === numPages}\">\n <a href=\"\" ng-click=\"selectPage(currentPage + 1)\">›</a>\n </li>\n <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: currentPage === numPages}\">\n <a href=\"\" ng-click=\"selectPage(numPages)\">»</a>\n </li>\n</ul>\n");
}]);
}));