Pagination widget/control

kick it on DotNetKicks.com

Want a JavaScript that draws a paging control into a <div>? It’s not unique in appearance, but there are no frameworks (e.g. Prototype, JQuery) requried, it’s relatively small (2.49 kb) before being compressed (1.2 kb after Packering), it’s cross-browser, and canby stylized using CSS. Here’s how she looks, stock:

PagerControl

Here’s the source and a small test page so you can figure out how it behaves. Create an “.htm” file, paste in this code, then enjoy:

<html>
<head>
	<style type="text/css">
		.spanPagerControlUnselected, .spanPagerControlSelected
		{
			font-family: arial;
			font-size: 9pt;
			font-weight: bold;
			border: 1px solid black;
			margin-right: 2px;
			margin-left: 2px;
			padding-left: 8px;
			padding-right: 8px;
			padding-top: 4px;
			padding-bottom: 4px;
			text-decoration:none;
			color:black;
		}

		.spanPagerControlSelected:hover
		{
			background-color:gray;
		}

		.spanPagerControlSelected, .spanPagerControlUnselected:hover
		{
			background-color:#1e4490;
			color:white;
		}

		.hellip
		{
			font-weight: normal;
			font-size: 8pt;
		}
	</style>
</head>
<body>
	<div id="divPager"></div>
</body>
</html>

<script type="text/javascript">

function PagerControl(parameters) {

	var PagerControl = new Object();

	// Public 

	PagerControl.page = function(pageNumber) {
		parameters.pagedCallback(pageNumber);
		this.currentPage = pageNumber;
		this.draw();
	};

	// Private

	PagerControl.currentPage = parameters.startPage;
	PagerControl.pageCount = parameters.pageCount;

	PagerControl.hasPreviousPage = function() {
		return (this.currentPage > 1);
	};

	PagerControl.hasNextPage = function() {
		return (this.currentPage < this.pageCount);
	};

	PagerControl.draw = function() {

		var createElement = function(page, selected, text) {	

			var elementNode = document.createElement(selected ? "span" : "a");

			if (!selected)
				elementNode.setAttribute("href", "javascript:" + parameters.varName + ".page(" + page + ")");

			elementNode.setAttribute("class", selected ? parameters.selectedCssClass : parameters.unselectedCssClass);
			elementNode.appendChild(document.createTextNode(text ? text : page));

			targetDiv.appendChild(elementNode);

		}

		var currentPage = this.currentPage;
		var pageCount = this.pageCount;
		var pagesToShow = parameters.pagesToShow;
		var hellipHTML = "<span class=\"" + parameters.hellipCssClass + "\">&hellip;</span>";

		// Reset the pager element; then paint it progressively

		var targetDiv = document.getElementById(parameters.targetDiv);
		targetDiv.innerHTML = "";

		var radius = Math.floor(parameters.pagesToShow/2);
		var start = currentPage - radius;
		var stop = currentPage + radius;

		if (start < 1) {
			start = 1;
			stop = (pagesToShow > pageCount)? pageCount : pagesToShow;
		}

		if (stop > pageCount) {
			stop = pageCount;
			var potentialStart = stop - pagesToShow;
			start = (potentialStart < 1)? 1 : potentialStart;
		}

		if (this.hasPreviousPage())
			createElement(parseInt(currentPage-1), false, parameters.previousPageLabel);

		if (parameters.alwaysShowFirst && start > 1) {
			createElement(1, false);
			if (start > 2)
				targetDiv.innerHTML += hellipHTML;
		}

		for (var i = start; i <= stop; i++)
			createElement(i, (i == currentPage));

		if (parameters.alwaysShowLast && stop < pageCount) {
			if (stop < pageCount - 1)
				targetDiv.innerHTML += hellipHTML;
			createElement(pageCount, false);
		}

		if (this.hasNextPage())
			createElement(parseInt(currentPage+1), false, parameters.nextPageLabel);

		// IE won't display class styles until this:
		targetDiv.innerHTML += "";
	};

	PagerControl.draw();

	return PagerControl;
}

</script>

<script type="text/javascript">

function loadPage(page) {
	// Ssend an XMLHttpRequest off to display the new page's contents in the
	// HTML document.
}

var pager = new PagerControl({

	startPage:1,
	pageCount: 100,
	pagesToShow: 7,
	unselectedCssClass: "spanPagerControlUnselected",
	selectedCssClass: "spanPagerControlSelected",
	hellipCssClass: "hellip",
	previousPageLabel: "previous",
	nextPageLabel: "next",
	alwaysShowFirst: true,
	alwaysShowLast: true,
	varName: "pager",
	targetDiv: "divPager",
	pagedCallback: loadPage

});

/*

Key for the parameters:

startPage (number) - The initial page that is selected.
pageCount (number) - The number of pages that exist.
pagesToShow (number) - The number of pages to show to the
	left and right of the current page for example, if
	startPage (above) is 10 and pagesToShow is 7, the
	buttons for pages 7 - 13 will be displayed.
unselectedCssClass (string) - The CSS class name for the
	page buttons that aren't the current page.
selectedCssClass (string) - The CSS class name for the
	page button that is curreltly selected.
hellipCssClass (string) - The CSS class name for <span>
	that displays "..." between the first and last page
	buttons if alwaysShowFirst and/or alwaysShowLast
	(below) are set to true.
previousPageLabel (string) - The text that appears in the
	page button for the previous page.
nextPageLabel (string) - The text that appears in the
	page button for the next page.
alwaysShowFirst (boolean) - Specify true value to always
	show a button for page 1 (and an ellipsis is
	displayed between page 1 and the curruent page minus
	half of the pagesToShow (above).
alwaysShowLast (boolean) -  Specify true value to always
	show a button for page 1 (and an ellipsis is displayed
	between the last page and the curruent page minus half
	of the pagesToShow (above).
varName (string) - The variable name of this new
	PageControl object.
targetDiv (string) - Where to draw the pager.
pagedCallback (function) - The function to fire when a
	surfer clicks a page.

*/

</script>
About these ads

5 Comments »

  1. Stephen said

    Following shows how to call the function called “PagerControl” and pass the value to its parameter. they call this publically and it is executed at first time. so the page count is 2500 for ever, am using Ajax and when ever http response text, I get a new set of value from database, I need to pass those record count to this pagination function parameter. so i simply call the following constructor inside some function to set its parameter value. but i couldn’t, it only works if I call the function public.how to do this. please guide me over this.

    var pager = new PagerControl({
    startPage:1,
    pageCount: 2500,
    pagesToShow: 10,
    unselectedCssClass: “spanPagerControlUnselected”,
    selectedCssClass: “spanPagerControlSelected”,
    hellipCssClass: “hellip”,
    previousPageLabel: “previous”,
    nextPageLabel: “next”,
    alwaysShowFirst: true,
    alwaysShowLast: true,
    varName: “pager”,
    targetDiv: “divPager”,
    pagedCallback: loadPage
    });

  2. Chris O. said

    Hey Stephen,

    Once you get your AJAX results back and know how many there are, set the PageControl’s .pageCount property to the new number of results:

    // The page control will now display up to 288 pages
    pager.pageCount = 288;

    If you copy the exact code I have posted and replace the loadPage() function with the following:

    function loadPage(page) {
    	pager.pageCount = Math.ceil((Math.random * 100));
    }

    You can see that the number of pages will change from 2500 to another number, each time a button with a page number is clicked. You don’t have to change the pageCount in loadPage() though, you can do it anytime you want. (You may have to call pager.draw() afterward though).

    Does that help?

  3. Stephen said

    Mr.Chris, Tks..it works. instead of load the ctrl outside the functions that is public. is there is any way, after i get the results from ajax, basis on the result i want to load the ctrl, not while page load. please help me this part as well. i really appreciate your earlier outcome..thanks in advance..

  4. Stephen said

    other wise like refresh the pagination ctrl, after set the parameter pager.pageCount, Tq

  5. Greg said

    Is it possible to use this twice (controlling the same content) on one page? I’d like to have the page numbers above and below the paged content. I’ve tried adding in a second target div variable and writing the same thing to it as to the original target div, but only the second one shows up.

    Any suggestions?

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: