1(function($){ 2 /** 3 * @class Class for calculating pagination values 4 */ 5 $.PaginationCalculator = function(maxentries, opts) { 6 this.maxentries = maxentries; 7 this.opts = opts; 8 } 9 10 $.extend($.PaginationCalculator.prototype, { 11 /** 12 * Calculate the maximum number of pages 13 * @method 14 * @returns {Number} 15 */ 16 numPages:function() { 17 return Math.ceil(this.maxentries/this.opts.items_per_page); 18 }, 19 /** 20 * Calculate start and end point of pagination links depending on 21 * current_page and num_display_entries. 22 * @returns {Array} 23 */ 24 getInterval:function(current_page) { 25 var ne_half = Math.floor(this.opts.num_display_entries/2); 26 var np = this.numPages(); 27 var upper_limit = np - this.opts.num_display_entries; 28 var start = current_page > ne_half ? Math.max( Math.min(current_page - ne_half, upper_limit), 0 ) : 0; 29 var end = current_page > ne_half?Math.min(current_page+ne_half + (this.opts.num_display_entries % 2), np):Math.min(this.opts.num_display_entries, np); 30 return {start:start, end:end}; 31 } 32 }); 33 34 // Initialize jQuery object container for pagination renderers 35 $.PaginationRenderers = {} 36 37 /** 38 * @class Default renderer for rendering pagination links 39 */ 40 $.PaginationRenderers.defaultRenderer = function(maxentries, opts) { 41 this.maxentries = maxentries; 42 this.opts = opts; 43 this.pc = new $.PaginationCalculator(maxentries, opts); 44 } 45 $.extend($.PaginationRenderers.defaultRenderer.prototype, { 46 /** 47 * Helper function for generating a single link (or a span tag if it's the current page) 48 * @param {Number} page_id The page id for the new item 49 * @param {Number} current_page 50 * @param {Object} appendopts Options for the new item: text and classes 51 * @returns {jQuery} jQuery object containing the link 52 */ 53 createLink:function(page_id, current_page, appendopts){ 54 var lnk, np = this.pc.numPages(); 55 page_id = page_id<0?0:(page_id<np?page_id:np-1); // Normalize page id to sane value 56 appendopts = $.extend({text:page_id+1, classes:""}, appendopts||{}); 57 if(page_id == current_page){ 58 lnk = $("<span class='current'>" + appendopts.text + "</span>"); 59 } 60 else 61 { 62 lnk = $("<a>" + appendopts.text + "</a>") 63 .attr('href', this.opts.link_to.replace(/__id__/,page_id)); 64 } 65 if(appendopts.classes){ lnk.addClass(appendopts.classes); } 66 lnk.data('page_id', page_id); 67 return lnk; 68 }, 69 // Generate a range of numeric links 70 appendRange:function(container, current_page, start, end, opts) { 71 var i; 72 for(i=start; i<end; i++) { 73 this.createLink(i, current_page, opts).appendTo(container); 74 } 75 }, 76 getLinks:function(current_page, eventHandler) { 77 var begin, end, 78 interval = this.pc.getInterval(current_page), 79 np = this.pc.numPages(), 80 fragment = $("<div class='pagination'></div>"); 81 82 // Generate "Previous"-Link 83 if(this.opts.prev_text && (current_page > 0 || this.opts.prev_show_always)){ 84 fragment.append(this.createLink(current_page-1, current_page, {text:this.opts.prev_text, classes:"prev"})); 85 } 86 // Generate starting points 87 if (interval.start > 0 && this.opts.num_edge_entries > 0) 88 { 89 end = Math.min(this.opts.num_edge_entries, interval.start); 90 this.appendRange(fragment, current_page, 0, end, {classes:'sp'}); 91 if(this.opts.num_edge_entries < interval.start && this.opts.ellipse_text) 92 { 93 jQuery("<span>"+this.opts.ellipse_text+"</span>").appendTo(fragment); 94 } 95 } 96 // Generate interval links 97 this.appendRange(fragment, current_page, interval.start, interval.end); 98 // Generate ending points 99 if (interval.end < np && this.opts.num_edge_entries > 0) 100 { 101 if(np-this.opts.num_edge_entries > interval.end && this.opts.ellipse_text) 102 { 103 jQuery("<span>"+this.opts.ellipse_text+"</span>").appendTo(fragment); 104 } 105 begin = Math.max(np-this.opts.num_edge_entries, interval.end); 106 this.appendRange(fragment, current_page, begin, np, {classes:'ep'}); 107 108 } 109 // Generate "Next"-Link 110 if(this.opts.next_text && (current_page < np-1 || this.opts.next_show_always)){ 111 fragment.append(this.createLink(current_page+1, current_page, {text:this.opts.next_text, classes:"next"})); 112 } 113 $('a', fragment).click(eventHandler); 114 return fragment; 115 } 116 }); 117 118 // Extend jQuery 119 $.fn.paginations = function(maxentries, opts){ 120 121 // Initialize options with default values 122 opts = jQuery.extend({ 123 items_per_page:10,
124 num_display_entries:11, 125 current_page:0, 126 num_edge_entries:0, 127 link_to:"#", 128 prev_text:"Prev", 129 next_text:"Next", 130 ellipse_text:"...", 131 prev_show_always:true, 132 next_show_always:true, 133 renderer:"defaultRenderer", 134 load_first_page:false, 135 callback:function(){return false;} 136 },opts||{}); 137 138 var containers = this, 139 renderer, links, current_page; 140 141 /** 142 * This is the event handling function for the pagination links. 143 * @param {int} page_id The new page number 144 */ 145 function paginationClickHandler(evt){ 146 var links, 147 new_current_page = $(evt.target).data('page_id'), 148 continuePropagation = selectPage(new_current_page); 149 if (!continuePropagation) { 150 evt.stopPropagation(); 151 } 152 return continuePropagation; 153 } 154 155 /** 156 * This is a utility function for the internal event handlers. 157 * It sets the new current page on the pagination container objects, 158 * generates a new HTMl fragment for the pagination links and calls 159 * the callback function. 160 */ 161 function selectPage(new_current_page) { 162 // update the link display of a all containers 163 containers.data('current_page', new_current_page); 164 links = renderer.getLinks(new_current_page, paginationClickHandler); 165 containers.empty(); 166 links.appendTo(containers); 167 // call the callback and propagate the event if it does not return false 168 var continuePropagation = opts.callback(new_current_page, containers); 169 return continuePropagation; 170 } 171 172 // ----------------------------------- 173 // Initialize containers 174 // ----------------------------------- 175 current_page = opts.current_page; 176 containers.data('current_page', current_page); 177 // Create a sane value for maxentries and items_per_page 178 maxentries = (!maxentries || maxentries < 0)?1:maxentries; 179 opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0)?1:opts.items_per_page; 180 181 if(!$.PaginationRenderers[opts.renderer]) 182 { 183 throw new ReferenceError("Pagination renderer '" + opts.renderer + "' was not found in jQuery.PaginationRenderers object."); 184 } 185 renderer = new $.PaginationRenderers[opts.renderer](maxentries, opts); 186 187 // Attach control events to the DOM elements 188 var pc = new $.PaginationCalculator(maxentries, opts); 189 var np = pc.numPages(); 190 containers.bind('setPage', {numPages:np}, function(evt, page_id) { 191 if(page_id >= 0 && page_id < evt.data.numPages) { 192 selectPage(page_id); return false; 193 } 194 }); 195 containers.bind('prevPage', function(evt){ 196 var current_page = $(this).data('current_page'); 197 if (current_page > 0) { 198 selectPage(current_page - 1); 199 } 200 return false; 201 }); 202 containers.bind('nextPage', {numPages:np}, function(evt){ 203 var current_page = $(this).data('current_page'); 204 if(current_page < evt.data.numPages - 1) { 205 selectPage(current_page + 1); 206 } 207 return false; 208 }); 209 210 // When all initialisation is done, draw the links 211 links = renderer.getLinks(current_page, paginationClickHandler); 212 containers.empty(); 213 links.appendTo(containers); 214 // call callback function 215 if(opts.load_first_page) { 216 opts.callback(current_page, containers); 217 } 218 } // End of $.fn.pagination block 219 220})(jQuery);
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.