Download the EasyCFM.COM Browser Toolbar!
Easy Pagination With MySQL and ColdFusion
Introduction
This Tutorial will show you an example of a more efficient pagination method than those commonly used on small web sites. Although the query does run on every new page view, it ONLY returns the rows needed for the current page. Another great thing about this method is that the url variable to go to any page is simply the page number that you want to go to.

Download the CFML Code Here
Download the SQL for the Sample Database Here
A Working Example


Requirements
Cold Fusion 5, 6, or 7 (tested on 6 and 7)
MySQL (tested with version 4.0x and 4.1x)


Set Up Variables
A few variables are required to run this script:

The default page is always the first page. If no page number is specified, then page 1 will be shown

<cfparam name="url.page" default="1">


Here we set how many page number links will be shown at one time. If there are 100 pages of records, we probably do not want 100 page links running across the screen.

<cfset page_links_shown = 5>


How many records do we want on each page? I will set this to 5 for this tutorial. 1 to n is acceptable. Choosing how many records per page depends on your web site and how you want it to look and feel.

<cfset records_per_page = 5>


The variable start_record will tell MySQL the first record we want to get. Take the start page (let's say we are viewing page three) 3, multiply by records_ per_page (we set that to 5) and minus records_per_page (5) That leaves us with 3 * 5 - 5 = 10. Now we know the first row that we need (start_record) should be 10.

<cfset start_record = url.page * records_per_page - records_per_page>


The Queries...
The database that this tutorial uses is extremely simple. It has an 'id' field and a 'names' field. We will pull out the names to display.

This Query will give us the total number of records available. We will us the result of this later.

<cfquery name="get_count" datasource="#dsn#">
   SELECT COUNT(id) AS records FROM pages_names
</cfquery>


This Query will get the actual records for the page to display. This query actually has the secret to this whole tutorial. The MySQL LIMIT function. We tell it what row to start on, and how many rows after that to get. Simply plug in our variables start_record and records_per_page.

<cfquery name="get_names" datasource="#dsn#" result="get_data">
   SELECT names
   FROM pages_names
   ORDER BY names
   LIMIT #start_record#, #records_per_page#
</cfquery>


The Page Links...
The page links can come in many different varieties. I will show a few basic ones here, and a neat way to keep the page number links under control so they don't spread across the screen when there are a LOT of pages

Each of the Following section can be used separately or put in a different order. (previous / next links, first / last links, and the pages index)

First we will set up a few more variables that some of these page link examples will use.

Variable total_pages finds out how many pages total there will be by simply calculating the records per page and total records that we got earlier.

<cfset total_pages = ceiling(get_count.records / records_per_page)>


And let's start up our cfoutput so our variables can be used on screen.

<cfoutput>


We will output the query first. Remember, page one is default.

<cfloop query="get_names">
   #start_record + currentrow#. #names#<br/>
</cfloop>
<hr>


Previous Page Link:
The previous page link is dead simple. If the current page does not equal 1, then the previous page = current page minus 1. If the current page = 1, then show the text only, no link.

<cfif url.page EQ 1>
   Prev Page
<cfelse>
   <a href="pages.cfm?page=#url.page-1#">Prev Page</a>
</cfif>
<hr>


Next Page Link:
Next link is just as simple. If the current page multiplied by the records_per_page variable is Less than the total number of records, then there must be a next page, so show the link. Otherwise, show the text only.

<cfif url.page * records_per_page LT get_count.records>
   <a href="pages.cfm?page=#url.page+1#">Next Page</a>
<cfelse>
   Next Page
</cfif>
<hr>


Page Numbers Links Index:
Page number links are a little trickier, and can be done several ways. Here is a method I like. We need to set a few more variables if we are going to use this method. We need to know how many page links to display at one time. If there are too many page links on the screen, it can look bad. Imaging the numbers 1 through 100 on the screen on every page.

start_page is the default page to start showing links to. This is different than the default page of records to show. This variable only applies to the first page that we want to link to, and by default, it must be 1.

<cfparam name="start_page" default="1">


show_pages will determine how many page links to show at a time. We said 5 for this tutorial, but 10 or 15 is on too. If there are not enough records to fill the default, we will later set this to a lower number.

<cfparam name="show_pages" default="#min(page_links_shown,total_pages)#">


Now this next bit of code simply makes sure that our current page link is listed in the currently displayed page links index, since we are not showing every page link at a time. This code will 'roll' through the page links. This will make more sense in the working example. So if we have 10 pages, and at first we show links to pages 1,2,3,4,5 and click on page 5, when the page reloads, we will have links to pages 3,4,5,6,7 showing. You can dissect the code if you wish, but thats what it does. It gives us a value for start_page that will be used in the loop that write the page links out in the next step.
<cfif url.page + int(show_pages / 2) - 1 GTE total_pages>
   <cfset start_page = total_pages - show_pages + 1>
<cfelseif url.page + 1 GT show_pages>
   <cfset start_page = url.page - int(show_pages / 2)>
</cfif>


We need to set an end page for our page links to this is simply our start_page + show_pages variable that we set earlier minus 1.

<cfset end_page = start_page + show_pages - 1>


Now that we have a start_page and end_page variable, we'll loop from one to the other. We do a quick check that if the current page equals the page link we are writing, then don't make a link. The cfif within this loop is optional, but the loop and the output of the a href is required.

<cfloop from="#start_page#" to="#end_page#" index="i">
    <cfif url.page EQ i>
       #i#
   <cfelse>
       <a href="pages.cfm?page=#i#">#i#</a>
    </cfif>
</cfloop>
<hr>


First Page Link:
First Page / Last Page links are as easy as previous / next. First page ALWAYS is page 1.

 <a href="pages.cfm?page=1">First Page</a>
<hr>


Last Page Link:
Last page is ALWAYS the total_pages variable that we set earlier! That simple.
 <a href="pages.cfm?page=#total_pages#">Last Page</a>
<hr>


Finish the cfoutput

</cfoutput>


Optional features
· You may want to use the int() function on your outputs of page numbers in case some goober types a decimal into the url page= variable. This way, it will still work, but show whole numbers instead of decimal numbers for page links.

· Check for non-numerical url.page values. For the simplicity of this tutorial, I did not. This code will throw an error if url.page is a non-numeric value.

· You can also add a more complex page link index that has a (next 10) and (previous 10) pages option. Do what you choose, and whatever fits your layout and data the best.

CFDump To see your query results, query execution time, etc...
<cfdump var="#get_names#">
<cfdump var="#get_data#">

All ColdFusion Tutorials By Author: Kevin
  • Securing Your Dynamic Applications With CFLOGIN
    MX based view of secuirty ... contains components and infrastructure to support/manage users from both admin and user perspectives as well as an in-depth look at securing your apps at the application level, page level, and data level.
    Author: Kevin Bridges
    Views: 93,298
    Posted Date: Tuesday, December 17, 2002
  • (x)html compliant dynamic columns display
    This tutorial will show you how to display yout query results in a horizontal format x number of columns without loosing (x)html compliance. It may look slightly more complicated than others you may have seen, but this example provides full html and xhtml compatibility by cloasing all end tags and properly nesting td and tr.
    Author: Kevin
    Views: 14,403
    Posted Date: Thursday, April 21, 2005
  • Easy Pagination With MySQL and ColdFusion
    This tutorial will show you how to implement easy and effective pagination in your ColdFusion application. This works great for breaking up and displaying large query results one page at a time.
    Author: Kevin
    Views: 30,969
    Posted Date: Friday, October 14, 2005
  • Side By Side Product Comparison
    This Tutorial will show you how to allow your web sites users to select items to compare side by side. Your items could be anything from products for sale to statistical information. Users can add and remove Items or Products to compare in a table. A great feature for sites seilling products, especially products with many variations for models in a series.
    Author: Kevin
    Views: 11,038
    Posted Date: Thursday, January 12, 2006