Go Back   CodingForums.com > :: Client side development > JavaScript programming > JavaScript frameworks

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 07-27-2009, 10:07 AM   PM User | #1
Spudhead
Senior Coder

 
Spudhead's Avatar
 
Join Date: Jun 2002
Location: London, UK
Posts: 1,856
Thanks: 8
Thanked 110 Times in 109 Posts
Spudhead is on a distinguished road
review/comments invited on a pagination plugin

I recently worked on a project where there may be several listings modules on a page; I wrote a jQuery plugin to manage the pagination for these and would really appreciate any feedback or thoughts.

It currently manages the loading of content via AJAX on a pagination link click, with dedicated parameters for filtering and sorting the output. Basically speaking, it'll look for two UL elements, identified by classes, inside your target container; one for the links list, and one for the content list.

It's my first real effort at a plugin, and there are likely to be some omissions. I'm aware that there's stuff hardcoded that could easily be transferred to the defaults (like the "Prev" / "Next" text).

One thing I really don't like about it is that it is a bit AJAX-happy. Each pagination module on a page requires two server-side pages: one to return a count of the total number of items to paginate (I'd assume that this was running off a database), and one to return the actual listing content for a pagination 'page'. I can't see how you can get around it; you have to get the total number of items in order to know how many pagination links to create. But any observations would be welcomed.

Anyway here it is. If you think it might be useful in whatever form, feel free to use it. If you do tweak it, it would be nice if you could put a comment up here so we can see what you did



Code:
(function($) {

	$.fn.paginate = function(params) {
	
		// default / initial settings 
		var defaults = {
			
			itemsPerPage :		2,							//	number of items to show per page 
			currentPage :		1,							//	current page number 
			itemCount :			0,							//	total number of items to paginate
			linksToShow :		5,							//	maximum amount of numbered links to show 
			
			contentURLPrefix :	"/php/ajax/_ajaxlist_",		//	prefix for filename to load listings from 
			contentURLSuffix :	".php",						//	suffix for filename to load listings from
			countURLPrefix :	"/php/ajax/_ajaxcount_",	//	prefix for filename to load item count from 
			countURLSuffix :	".php",						//	suffix for filename to load item count from
			
			loadInitialContent:	true,						//	if true, go and fetch the first page of content (otherwise assume that the containing page has already done so)
			onPagedLoad:		null,						//	callback function fired when a page of content is loaded
			
			queryfilters:		{},							//	key:value pairs of filter parameters to pass to content-fetching / count pages
			querysort:			"",							//	comma-separated list of sort columns to pass to content-fetching pages
			
			ajaxvars:			{},							//	key:value pairs of miscellaneous vars to pass to content-fetching / count pages.
															//	Treated the same way as queryfilters except they're not written to pagination links
			
			contentContainer:	".modulecontentlist",		//	the classname of the container that the content will be loaded in to
			linksContainer:		".pagelinks"				//	the classname of the container that the numbered page links will be loaded into
		
		};
		
		var options = $.extend(defaults, params);
		
		
		
		return this.each(function() {
			
    		var $this = $(this);
			
			//	update the itemCount via AJAX if it's not been passed in.
			if (options.itemCount == 0){
			
				var countSourceURL = options.countURLPrefix + $this.attr("id") + options.countURLSuffix;
				
				$.get(countSourceURL, options.queryfilters, function(ct){
																	 
					options.itemCount = parseInt(ct);
					
					if (options.loadInitialContent){
						getInitialContent($this);
					}else{
						drawPaginationLinks($this);
						if ($.isFunction(options.onPagedLoad)) {
							options.onPagedLoad($this);
						}
					}
					
				});
				
				
			}else{
			
				if (options.loadInitialContent){
					getInitialContent($this);
				}else{
					drawPaginationLinks($this);
					if ($.isFunction(options.onPagedLoad)) {
						options.onPagedLoad($this);
					}
				}
			
			}
		
		});
		
		
		
		function drawPaginationLinks($this){
		// draw a list of pagination links 
			
			if (options.itemCount > options.itemsPerPage){
				
				var maxPageNumber = Math.ceil(options.itemCount / options.itemsPerPage);
				var linkCount = options.linksToShow - 1					// make linkCount 0-based, not 1-based.
				
				// normally start numbering at one below the current page, unless we're at page 1.
				var startPageNumber	= (options.currentPage > 1) ?  options.currentPage - 1 : options.currentPage;

				// keep listing page number links until we get to linkCount, unless we hit maxPageNumber first.
				var endPageNumber = startPageNumber + linkCount;
				endPageNumber = (endPageNumber > maxPageNumber) ? maxPageNumber : endPageNumber;
				
				// if we're close enough to the end that we're not listing enough pages, and we're far enough away from the beginning, begin numbering earlier.
				if (((endPageNumber - startPageNumber) < linkCount) && (startPageNumber > 1)){
					startPageNumber = (endPageNumber > linkCount) ? endPageNumber - linkCount : 1;
				}
				
				// create filter list for adding to numbered link hrefs
				var filterlist = "";
				$.each(options.queryfilters, function(key, val){
					if (filterlist==""){
						filterlist = key + "=" + val;
					}else{
						filterlist += "&" + key + "=" + val;
					}
				});
				
				
				
				// now create list of numbered links
				var sNumberingHTML = '';
				
				//	add "Prev" link if appropriate 
				if (options.currentPage > 1){
					sNumberingHTML += '<li><a href="#'+filterlist+'">Prev</a></li>';
				}
				for (var i = startPageNumber; i <= endPageNumber; i++){
					if (options.currentPage == i){
						sNumberingHTML += '<li class="current">'+ i +'</li>';
					}else{
						sNumberingHTML += '<li><a href="#'+filterlist+'">'+ i +'</a></li>';
					}
				}
				//	add "Next" link if appropriate 
				if (options.currentPage < maxPageNumber){
					sNumberingHTML += '<li><a href="#'+filterlist+'">Next</a></li>';
				}
				
				//	add numbered links to container UL 
				$this.find(options.linksContainer).html(sNumberingHTML);
				
				//	add event handlers to newly-added numbering links 
				$this.find('.' + options.linksContainer + ' li a').click(function(){
					getPaginationContent(this,$this);
					return false;
				});
			
			
			}else{	//(options.itemCount <= options.itemsPerPage) 	- don't show pagelinks
				$this.find(options.linksContainer).html("");
			}
					

		}
		
		
		function getInitialContent($this){
			// get the content for the first page and draw the pagination links.
			var contentSourceURL = options.contentURLPrefix + $this.attr("id") + options.contentURLSuffix;
			
			var paginationParams = {pageNumber: options.currentPage, itemsPerPage: options.itemsPerPage, sortby: options.querysort};
			var allParams = $.extend(paginationParams, options.queryfilters, options.ajaxvars);
			
			$($this).find(options.contentContainer).load(contentSourceURL, allParams, function(){
				drawPaginationLinks($this);
				
				if ($.isFunction(options.onPagedLoad)) {
					options.onPagedLoad($this);
				}
			});
			
		}
		
		

		function getPaginationContent(pageListLink,$this){
			// get the content for the required page, draw the pagination links, and increment the current page count.
			var contentSourceURL = options.contentURLPrefix + $this.attr("id") + options.contentURLSuffix;
			var pageNumberToGet = $(pageListLink).text();
			if (!isNaN(pageNumberToGet)){
				pageNumberToGet = parseInt(pageNumberToGet);
			}else if (pageNumberToGet == "Next"){
				pageNumberToGet = options.currentPage + 1;
			}else if (pageNumberToGet == "Prev"){
				pageNumberToGet = options.currentPage - 1;
			}
			
			var paginationParams = {pageNumber: pageNumberToGet, itemsPerPage: options.itemsPerPage, sortby: options.querysort};
			var allParams = $.extend(paginationParams, options.queryfilters, options.ajaxvars);
			
			$($this).find(options.contentContainer).load(contentSourceURL, allParams, function(){
				options.currentPage = pageNumberToGet;
				drawPaginationLinks($this);
				
				if ($.isFunction(options.onPagedLoad)) {
					options.onPagedLoad($this);
				}
				
			});
			
		}
		
		
	};

})(jQuery);
Usage:


Code:
<div id="listItems">
	<ul class="pagelinks"></ul>
	<ul class="modulecontentlist"></ul>
</div>
Code:
$(document).ready(function(){
	$('#listItems').paginate({
		itemsPerPage: 24,
		queryfilters:{
				myParam1:myVal1,
				myParam2:myVal2,
		}
	});

});
Spudhead is offline   Reply With Quote
Old 07-27-2009, 03:50 PM   PM User | #2
Fumigator
UE Antagonizer


 
Fumigator's Avatar
 
Join Date: Dec 2005
Location: Utah, USA, Northwestern hemisphere, Earth, Solar System, Milky Way Galaxy, Alpha Quadrant
Posts: 7,687
Thanks: 42
Thanked 637 Times in 625 Posts
Fumigator is a glorious beacon of lightFumigator is a glorious beacon of lightFumigator is a glorious beacon of lightFumigator is a glorious beacon of lightFumigator is a glorious beacon of light
Do you have a demo page? Or have you submitted this plugin to the jquery.com plugin repository?
__________________
Fumigator is offline   Reply With Quote
Old 07-29-2009, 10:26 AM   PM User | #3
Spudhead
Senior Coder

 
Spudhead's Avatar
 
Join Date: Jun 2002
Location: London, UK
Posts: 1,856
Thanks: 8
Thanked 110 Times in 109 Posts
Spudhead is on a distinguished road
I haven't submitted it, but a demo page isn't a bad idea. Here you are.
Spudhead is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:32 AM.


Advertisement
Log in to turn off these ads.