PageSourceSearch

https://www.imperial-rac.com/wp-content/plugins/ng-filter/assets/j…/dirPagination.js?ver=7.1.2

js imperial-rac.com collected 2026-10-04 02:41:36 UTC 13,623 bytes, 327 lines download raw bytes

1/**
2 * dirPagination - AngularJS module for paginating (almost) anything.
3 *
4 *
5 * Credits
6 * =======
7 *
8 * Daniel Tabuenca: https://groups.google.com/d/msg/angular/an9QpzqIYiM/r8v-3W1X5vcJ
9 * for the idea on how to dynamically invoke the ng-repeat directive.
10 *
11 * I borrowed a couple of lines and a few attribute names from the AngularUI Bootstrap project:
12 * https://github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js
13 *
14 * Copyright 2014 Michael Bromley <[email protected]>
15 */
16
17(function() {
18
19    /**
20     * Config
21     */
22    var moduleName = 'angularUtils.directives.dirPagination';
23    var templatePath = 'directives/pagination/dirPagination.tpl.html';
24
25    /**
26     * Module
27     */
28    var module;
29    try {
30        module = angular.module(moduleName);
31    } catch(err) {
32        // named module does not exist, so create one
33        module = angular.module(moduleName, []);
34    }
35
36    module.directive('dirPaginate', ['$compile', '$parse', '$timeout', 'paginationService', function($compile, $parse, $timeout, paginationService) {
37        return  {
38            terminal: true,
39            compile: function(element, attrs){
40                attrs.$set('ngRepeat', attrs.dirPaginate); // Add ng-repeat to the dom element
41                element.removeAttr(attrs.$attr.dirPaginate); // Remove the dir-paginate attribute to prevent infinite recursion of compilation
42
43                var expression = attrs.dirPaginate;
44                // regex taken directly from https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js#L211
45                var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
46
47                var filterPattern = /\|\s*itemsPerPage:[^|]*/;
48                if (match[2].match(filterPattern) === null) {
49                    throw 'pagination directive: the \'itemsPerPage\' filter must be set.';
50                }
51                var itemsPerPageFilterRemoved = match[2].replace(filterPattern, '');
52                var collectionGetter = $parse(itemsPerPageFilterRemoved);
53
54                return function(scope, element, attrs){
55                    var paginationId;
56                    var compiled =  $compile(element); // we manually compile the element again, as we have now swapped dir-paginate for an ng-repeat
57
58                    paginationId = attrs.paginationId || '__default';
59                    paginationService.registerInstance(paginationId);
60
61                    var currentPageGetter;
62                    if (attrs.currentPage) {
63                        currentPageGetter = $parse(attrs.currentPage);
64                    } else {
65                        // if the current-page attribute was not set, we'll make our own
66                        var defaultCurrentPage = paginationId + '__currentPage';
67                        scope[defaultCurrentPage] = 1;
68                        currentPageGetter = $parse(defaultCurrentPage);
69                    }
70                    paginationService.setCurrentPageParser(paginationId, currentPageGetter, scope);
71
72                    if (typeof attrs.totalItems !== 'undefined') {
73                        paginationService.setAsyncModeTrue(paginationId);
74                        scope.$watch(function() {
75                            return $parse(attrs.totalItems)(scope);
76                        }, function (result) {
77                            if (0 < result) {
78                                paginationService.setCollectionLength(paginationId, result);
79                            }
80                        });
81                    } else {
82                        scope.$watchCollection(function() {
83                            return collectionGetter(scope);
84                        }, function(collection) {
85                            if (collection) {
86                                paginationService.setCollectionLength(paginationId, collection.length);
87                            }
88                        });
89                    }
90
91                    // Delegate to the link function returned by the new compilation of the ng-repeat
92                    compiled(scope);
93                };
94            }
95        };
96    }]);
97
98    module.directive('dirPaginationControls', ['paginationService', function(paginationService) {
99        var numberRegex = /^\d+$/;
100        /**
101         * Generate an array of page numbers (or the '...' string) 
101which is used in an ng-repeat to generate the
102         * links used in pagination
103         *
104         * @param currentPage
105         * @param rowsPerPage
106         * @param paginationRange
107         * @param collectionLength
108         * @returns {Array}
109         */
110        function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) {
111            var pages = [];
112            var totalPages = Math.ceil(collectionLength / rowsPerPage);
113            var halfWay = Math.ceil(paginationRange / 2);
114            var position;
115
116            if (currentPage <= halfWay) {
117                position = 'start';
118            } else if (totalPages - halfWay < currentPage) {
119                position = 'end';
120            } else {
121                position = 'middle';
122            }
123
124            var ellipsesNeeded = paginationRange < totalPages;
125            var i = 1;
126            while (i <= totalPages && i <= paginationRange) {
127                var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages);
128
129                var openingEllipsesNeeded = (i === 2 && (position === 'middle' || position === 'end'));
130                var closingEllipsesNeeded = (i === paginationRange - 1 && (position === 'middle' || position === 'start'));
131                if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
132                    pages.push('...');
133                } else {
134                    pages.push(pageNumber);
135                }
136                i ++;
137            }
138            return pages;
139        }
140
141        /**
142         * Given the position in the sequence of pagination links [i], figure out what page number corresponds to that position.
143         *
144         * @param i
145         * @param currentPage
146         * @param paginationRange
147         * @param totalPages
148         * @returns {*}
149         */
150        function calculatePageNumber(i, currentPage, paginationRange, totalPages) {
151            var halfWay = Math.ceil(paginationRange/2);
152            if (i === paginationRange) {
153                return totalPages;
154            } else if (i === 1) {
155                return i;
156            } else if (paginationRange < totalPages) {
157                if (totalPages - halfWay < currentPage) {
158                    return totalPages - paginationRange + i;
159                } else if (halfWay < currentPage) {
160                    return currentPage - halfWay + i;
161                } else {
162                    return i;
163                }
164            } else {
165                return i;
166            }
167        }
168
169        return {
170            restrict: 'AE',
171            templateUrl: function(elem, attrs) {
172                return attrs.templateUrl || templatePath;
173            },
174            scope: {
175                maxSize: '=?',
176                onPageChange: '&?'
177            },
178            link: function(scope, element, attrs) {
179                var paginationId;
180                paginationId = attrs.paginationId || '__default';
181                if (!scope.maxSize) { scope.maxSize = 9; }
182                scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
183                scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;
184
185                if (!paginationService.isRegistered(paginationId)) {
186                    var idMessage = (paginationId !== '__default') ? ' (id: ' + paginationId + ') ' : ' ';
187                    throw 'pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive.';
188                }
189
190                var paginationRange = Math.max(scope.maxSize, 5);
191                scope.pages = [];
192                scope.pagination = {
193                    last: 1,
194                    current: 1
195                };
196
197                scope.$watch(function() {
198                    return (paginationService.getCollectionLength(paginationId) + 1) * paginationService.getItemsPerPage(paginationId);
199                }, function(length) {
200                    if (0 < length) {
201                        generatePagination();
202                    }
203                });
204
205                scope.$watch(function() {
206                    return paginationService.getCurrentPage(paginationId);
207                }, function(currentPage) {
208                    goToPage(currentPage);
209                });
210
211                scope.setCurrent = function(num) {
212                    if (isValidPageNumber(num)) {
213                        paginationService.setCurrentPage(paginationId, num);
214                    }
215                };
216
217                function goToPage(num) {
218                    if (isValidPageNumber(num)) {
219                        scope.pages = generatePagesArray(num, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange);
220                        scope.pagination.current = num;
221
222                        // if a callback has been set, then call it with the page number as an argument
223                        if (scope.onPageChange) {
224                            scope.onPageChange({ newPageNumber : num });
225                        }
226                    }
227                }
228
229                function generatePagination() {
230                    scope.pages = generatePagesArray(1, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange);
231                    scope.pagination.current = parseInt(paginationService.getCurrentPage(paginationId));
232                    scope.pagination.last = scope.pages[scope.pages.length - 1];
233                    if (scope.pagination.last < scope.pagination.current) {
234                        scope.setCurrent(scope.pagination.last);
235                    }
236                }
237
238                function isValidPageNumber(num) {
239                    return (numberRegex.test(num) && (0 < num && num <= scope.pagination.last));
240                }
241            }
242        };
243    }]);
244
245    module.filter('itemsPerPage', ['paginationService', function(paginationService) {
246        return function(collection, itemsPerPage, paginationId) {
247            if (typeof (paginationId) === 'undefined') {
248                paginationId = '__default';
249            }
250            if (!paginationService.isRegistered(paginationId)) {
251                throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.';
252            }
253            var end;
254            var start;
255            if (collection instanceof Array) {
256                itemsPerPage = parseInt(itemsPerPage) || 9999999999;
257                if (paginationService.isAsyncMode(paginationId)) {
258                    start = 0;
259                } else {
260                    start = (paginationService.getCurrentPage(paginationId) - 1) * itemsPerPage;
261                }
262                end = start + itemsPerPage;
263                paginationService.setItemsPerPage(paginationId, itemsPerPage);
264
265                return collection.slice(start, end);
266            } else {
267                return collection;
268            }
269        };
270    }]);
271
272    module.service('paginationService', function() {
273        var instances = {};
274        var lastRegisteredInstance;
275        this.paginationDirectiveInitialized = false;
276
277        this.registerInstance = function(instanceId) {
278            if (typeof instances[instanceId] === 'undefined') {
279                instances[instanceId] = {
280                    asyncMode: false
281                };
282                lastRegisteredInstance = instanceId;
283            }
284        };
285
286        this.isRegistered = function(instanceId) {
287            return (typeof instances[instanceId] !== 'undefined');
288        };
289
290        this.getLastInstanceId = function() {
291            return lastRegisteredInstance;
292        };
293
294        this.setCurrentPageParser = function(instanceId, val, scope) {
295            instances[instanceId].currentPageParser = val;
296            instances[instanceId].context = scope;
297        };
298        this.setCurrentPage = function(instanceId, val) {
299            instances[instanceId].currentPageParser.assign(instances[instanceId].context, val);
300        };
301        this.getCurrentPage = function(instanceId) {
302            return instances[instanceId].currentPageParser(instances[instanceId].context);
303        };
304
305        this.setItemsPerPage = function(instanceId, val) {
306            instances[instanceId].itemsPerPage = val;
307        };
308        this.getItemsPerPage = function(instanceId) {
309            return instances[instanceId].itemsPerPage;
310        };
311
312        this.setCollectionLength = function(instanceId, val) {
313            instances[instanceId].collectionLength = val;
314        };
315        this.getCollectionLength = function(instanceId) {
316            return instances[instanceId].collectionLength;
317        };
318
319        this.setAsyncModeTrue = function(instanceId) {
320            instances[instanceId].asyncMode = true;
321        };
322
323        this.isAsyncMode = function(instanceId) {
324            return instances[instanceId].asyncMode;
325        };
326    });
327})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.