/** * this jquery plugin displays pagination links inside the selected elements. * * @author gabriel birke (birke *at* d-scribe *dot* de) * @version 1.1 * @param {int} maxentries number of entries to paginate * @param {object} opts several options (see readme for documentation) * @return {object} jquery object */ jquery.fn.pagination = function(maxentries, opts) { opts = jquery.extend({ items_per_page: 10, num_display_entries: 10, current_page: 0, num_edge_entries: 0, link_to: "#", prev_text: "prev", next_text: "next", ellipse_text: "...", prev_show_always: true, next_show_always: true, callback: function() { return false; } }, opts || {}); return this.each(function() { /** * calculate the maximum number of pages */ function numpages() { return math.ceil(maxentries / opts.items_per_page); } /** * calculate start and end point of pagination links depending on * current_page and num_display_entries. * @return {array} */ function getinterval() { var ne_half = math.ceil(opts.num_display_entries / 2); var np = numpages(); var upper_limit = np - opts.num_display_entries; var start = current_page > ne_half ? math.max(math.min(current_page - ne_half, upper_limit), 0) : 0; var end = current_page > ne_half ? math.min(current_page + ne_half, np) : math.min(opts.num_display_entries, np); return [start, end]; } /** * this is the event handling function for the pagination links. * @param {int} page_id the new page number */ function pageselected(page_id, evt) { current_page = page_id; drawlinks(); var continuepropagation = opts.callback(page_id, panel); if (!continuepropagation) { if (evt.stoppropagation) { evt.stoppropagation(); } else { evt.cancelbubble = true; } } return continuepropagation; } /** * this function inserts the pagination links into the container element */ function drawlinks() { panel.empty(); var interval = getinterval(); var np = numpages(); // this helper function returns a handler function that calls pageselected with the right page_id var getclickhandler = function(page_id) { return function(evt) { return pageselected(page_id, evt); } } // helper function for generating a single link (or a span tag if it's the current page) var appenditem = function(page_id, appendopts) { page_id = page_id < 0 ? 0 : (page_id < np ? page_id : np - 1); // normalize page id to sane value appendopts = jquery.extend({ text: page_id + 1, classes: "current" }, appendopts || {}); if (page_id == current_page) { var lnk = $("" + (appendopts.text) + ""); } else { var lnk = $("" + (appendopts.text) + "") .bind("click", getclickhandler(page_id)) .attr('href', opts.link_to.replace(/__id__/, page_id)); } if (appendopts.classes) { lnk.removeattr('class'); lnk.addclass(appendopts.classes); } panel.append(lnk); } // generate "previous"-link if (opts.prev_text && (current_page > 0 || opts.prev_show_always)) { appenditem(current_page - 1, { text: opts.prev_text, classes: "disabled" }); } // generate starting points if (interval[0] > 0 && opts.num_edge_entries > 0) { var end = math.min(opts.num_edge_entries, interval[0]); for (var i = 0; i < end; i++) { appenditem(i); } if (opts.num_edge_entries < interval[0] && opts.ellipse_text) { jquery("" + opts.ellipse_text + "").appendto(panel); } } // generate interval links for (var i = interval[0]; i < interval[1]; i++) { appenditem(i); } // generate ending points if (interval[1] < np && opts.num_edge_entries > 0) { if (np - opts.num_edge_entries > interval[1] && opts.ellipse_text) { jquery("" + opts.ellipse_text + "").appendto(panel); } var begin = math.max(np - opts.num_edge_entries, interval[1]); for (var i = begin; i < np; i++) { appenditem(i); } } // generate "next"-link if (opts.next_text && (current_page < np - 1 || opts.next_show_always)) { appenditem(current_page + 1, { text: opts.next_text, classes: "disabled" }); } } // extract current_page from options var current_page = opts.current_page; // create a sane value for maxentries and items_per_page maxentries = (!maxentries || maxentries < 0) ? 1 : maxentries; opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0) ? 1 : opts.items_per_page; // store dom element for easy access from all inner functions var panel = jquery(this); // attach control functions to the dom element this.selectpage = function(page_id) { pageselected(page_id); } this.prevpage = function() { if (current_page > 0) { pageselected(current_page - 1); return true; } else { return false; } } this.nextpage = function() { if (current_page < numpages() - 1) { pageselected(current_page + 1); return true; } else { return false; } } // when all initialisation is done, draw the links drawlinks(); }); }