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