Code review feedback & back-ground traffic support
[samplevnf.git] / VNF_Catalogue / public / 3rd_party / materialize-pagination.js
1 /*
2  materialize Pagination v0.2.2
3  http://mirjamsk.github.io/materialize-pagination/
4
5  Sample usage:
6     $('#pagination').materializePagination({ 
7         align: 'left',
8         lastPage:  10,
9         firstPage:  1,
10         urlParameter: 'page',
11         useUrlParameter: true,
12         onClickCallback: function(requestedPage){
13             console.log('Requested page is '+ requestedPage)
14         }
15     });  
16 */
17 ;(function($, window, document, undefined) {
18
19     var MaterializePagination = function(elem, options) {
20         this.$elem   = $(elem);
21         this.options = options;
22         this.$container    = null;
23         this.$prevEllipsis = null;
24         this.$nextEllipsis = null;
25         this.currentPage   = null;
26         this.visiblePages  = [];
27         this.maxVisiblePages = 3;
28     };
29
30     MaterializePagination.prototype = {
31         defaults: {
32             align: 'center',
33             lastPage: 1,
34             firstPage: 1,
35             urlParameter: 'page',
36             useUrlParameter: true,
37             onClickCallback: function(){}
38         },
39
40         init: function() {
41             // Combine defaults with user-specified options
42             this.config = $.extend({}, this.defaults, this.options);
43             // Get page defined by the urlParameter
44             var requestedPage =  this.config.useUrlParameter ? this.parseUrl() : this.config.firstPage;
45             // Create initial pagination and add it to the DOM
46             if(this.createPaginationBase(requestedPage))
47                 this.bindClickEvent();
48         },
49
50         createPaginationBase: function(requestedPage) {
51             //alert('getting called');
52             if (isNaN(this.config.firstPage) || isNaN(this.config.lastPage) ){
53                 console.error('Both firstPage and lastPage attributes need to be integer values');
54                 return false;
55             }
56             else if (this.config.firstPage > this.config.lastPage ){
57                 console.error('Value of firstPage must be less than the value of lastPage');
58                 return false;
59             }
60             this.config.firstPage = parseInt(this.config.firstPage);
61             this.config.lastPage = parseInt(this.config.lastPage);
62             this.currentPage = this.config.firstPage - this.maxVisiblePages;
63
64             this.$container = $('<ul>')
65                 .addClass('pagination')
66                 .addClass(this.config.align + '-align');
67
68             this.$prevEllipsis = this.util.Ellipsis();
69             this.$nextEllipsis = this.util.Ellipsis();
70
71             var $firstPage   = this.util.createPage(this.config.firstPage);
72             var $prevChevron = this.util.createChevron('prev');
73             var $nextChevron = this.util.createChevron('next');
74
75             this.$container
76                 .append($prevChevron)
77                 .append($firstPage)
78                 .append(this.$prevEllipsis.$elem)
79                 .append(this.$nextEllipsis.$elem)
80                 .append($nextChevron);
81
82             if (this.config.lastPage > this.config.firstPage) {
83                 var $lastPage = this.util.createPage(this.config.lastPage);
84                 $lastPage.insertBefore($nextChevron);
85             }
86
87             this.requestPage(requestedPage, true);
88             this.renderActivePage();
89             this.$elem.append(this.$container);
90             return true;
91         },
92
93         requestPage: function(requestedPage, initing){
94             //alert(initing);
95             switch (requestedPage) {
96                 case this.currentPage:
97                     return;
98                 case this.currentPage - 1:
99                     this.requestPrevPage();
100                     break;
101                 case this.currentPage + 1:
102                     this.requestNextPage();
103                     break;
104                 default:
105                     this.requestPageByNumber(requestedPage);
106             }
107             if (!initing)
108                 this.config.onClickCallback(this.currentPage);
109             this.renderActivePage();
110
111             if ( this.config.useUrlParameter )
112                 this.updateUrlParam(this.config.urlParameter, this.currentPage);  
113         },
114
115         requestPrevPage: function() {
116             this.currentPage -= 1;
117             this.visiblePages.pop().remove();
118             this.visiblePages.unshift(this.insertPrevPaginationComponent(this.currentPage - 1));
119         },
120
121         requestNextPage: function() {
122             this.currentPage += 1;
123             this.visiblePages.shift().remove();
124             this.visiblePages.push(this.insertNextPaginationComponent(this.currentPage + 1));
125         },
126
127         requestPageByNumber: function(requestedPage) {
128             this.purgeVisiblePages();
129             this.currentPage = requestedPage;
130             this.visiblePages.push(this.insertNextPaginationComponent(this.currentPage - 1));
131             this.visiblePages.push(this.insertNextPaginationComponent(this.currentPage));
132             this.visiblePages.push(this.insertNextPaginationComponent(this.currentPage + 1));
133         },
134
135         renderActivePage: function() {
136             this.renderEllipsis();
137             this.$container.find('li.active').removeClass('active');
138             var currentPageComponent = $(this.$container.find('[data-page="' + this.currentPage + '"]')[0]);
139                 currentPageComponent.addClass('active');
140         },
141
142         renderEllipsis: function() {
143             if (this.$prevEllipsis.isHidden && 
144                 this.currentPage >= this.config.firstPage + this.maxVisiblePages)
145                 this.$prevEllipsis.show();
146             
147             else if (!this.$prevEllipsis.isHidden && 
148                 this.currentPage <= this.config.firstPage + this.maxVisiblePages - 1)
149                 this.$prevEllipsis.hide();
150
151             if (this.$nextEllipsis.isHidden && 
152                 this.currentPage <= this.config.lastPage - this.maxVisiblePages)
153                 this.$nextEllipsis.show();
154             
155             else if (!this.$nextEllipsis.isHidden && 
156                 this.currentPage >= this.config.lastPage - this.maxVisiblePages + 1)
157                 this.$nextEllipsis.hide();
158         },
159
160         bindClickEvent: function() {
161             var self = this;
162             this.$container.on('click', 'li', function() {
163                 var requestedPage = self.sanitizePageRequest($(this).data('page'));
164                 self.requestPage(requestedPage, false);
165             });
166         },
167
168         insertPrevPaginationComponent: function(pageNumber) {
169             if (pageNumber > this.config.firstPage && pageNumber < this.config.lastPage) {
170                 var $paginationComponent = this.util.createPage(pageNumber);
171                 return $paginationComponent.insertAfter(this.$prevEllipsis.$elem);
172             }
173             return $('');
174         },
175
176         insertNextPaginationComponent: function(pageNumber) {
177             if (pageNumber > this.config.firstPage && pageNumber < this.config.lastPage) {
178                 var $paginationComponent = this.util.createPage(pageNumber);
179                 return $paginationComponent.insertBefore(this.$nextEllipsis.$elem);
180             }
181             return $('');
182         },
183
184         sanitizePageRequest: function(pageData) {
185             var requestedPage = this.config.firstPage;
186
187             if (pageData === 'prev') {
188                 requestedPage =
189                     this.currentPage === this.config.firstPage ?
190                     this.currentPage : this.currentPage - 1;
191             }
192             else if (pageData === 'next') {
193                 requestedPage =
194                     this.currentPage === this.config.lastPage ?
195                     this.currentPage : this.currentPage + 1;
196             }
197             else if (!isNaN(pageData) &&
198                 pageData >= this.config.firstPage &&
199                 pageData <= this.config.lastPage) {
200                 requestedPage = parseInt(pageData);
201             }
202             return requestedPage;
203         },
204
205         purgeVisiblePages: function() {
206             var size = this.visiblePages.length;
207             for (var page = 0; page < size; page += 1)
208                 this.visiblePages.pop().remove();
209         },
210
211         parseUrl: function(){
212             var requestedPage = this.getUrlParamByName(this.config.urlParameter) || this.config.firstPage;
213             return this.sanitizePageRequest(requestedPage);
214         },
215
216         getUrlParamByName: function(name) {
217             name = name.replace(/[\[\]]/g, "\\$&");
218             var url = window.location.href;
219             var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
220             var results = regex.exec(url);
221             if (!results)  return null;
222             if (!results[2]) return '';
223             return decodeURIComponent(results[2].replace(/\+/g, " "));
224         },
225
226         updateUrlParam: function (key, value) {
227             var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
228                 urlQueryString = document.location.search,
229                 newParam = key + '=' + value,
230                 params = '?' + newParam;
231
232             if (urlQueryString) { // If the "search" string exists, then build params from it
233                 keyRegex = new RegExp('([\?&])' + key + '[^&]*');
234
235                 if (urlQueryString.match(keyRegex) !== null) { // If param exists already, update it
236                     params = urlQueryString.replace(keyRegex, "$1" + newParam);
237                 }
238                 else { // Otherwise, add it to end of query string
239                     params = urlQueryString + '&' + newParam;
240                 }
241             }
242             window.history.pushState('', '', params);
243         },
244
245         util: {
246             createPage: function(pageData){
247                 return $('<li>')
248                     .text(pageData)
249                     .addClass('waves-effect')
250                     .attr('data-page', pageData);
251             },
252             createChevron: function(type){
253                 var direction = type === 'next' ? 'right' : 'left';
254                 
255                 var $icon = $('<i>')
256                     .addClass('waves-effect')
257                     .addClass('material-icons')
258                     .text('chevron_' + direction);
259                 
260                 return this.createPage(type).text('')
261                     .attr('data-page', type)
262                     .append($icon);
263             },
264             Ellipsis: function() {
265                 var $ellipsis = $('<li>');
266                     $ellipsis.text('...');
267                     $ellipsis.addClass('hide disabled');
268                 return {
269                     $elem: $ellipsis,
270                     isHidden:   true,
271                     show: function() {
272                         this.isHidden = false;
273                         this.$elem.removeClass('hide');},
274                     hide: function() {
275                         this.isHidden = true;
276                         this.$elem.addClass('hide');}
277                 };
278             }
279         }
280     };
281
282     MaterializePagination.defaults = MaterializePagination.prototype.defaults;
283     $.fn.materializePagination = function(options) {
284         return this.each(function() {
285             new MaterializePagination(this, options).init();
286         });
287     };
288 })(jQuery, window, document);