jQuery Pagination Plugin

Author: Carlo Tasca
Version: 1.1
Date: July 5, 2009
License: GPL license
Dependency: jQuery Pagination plugin (version 1.2.1)
Plugin project link: http://plugins.jquery.com/project/Paginator
For help and comments:  http://programmissimo.blogspot.com/

Note: jQuery paginator is based on the jQuery Pagination plugin originally written by Gabriel Birke. For information, documentation and license please visit http://plugins.jquery.com/project/pagination

jQuery paginator plugin file already includes the required jQuery pagination plugin.

Added functionality:

  • page X of Y can be optionally added to the left/right of paginator's navigation links;
  • cookie to hold current selected page number (it will keep page selected if user get back to pagination page within 24 hours);
  • configuration value postUrl for URL to server file path to load paginator data;
  • configuration value elementModel: to define html model for each paginator item. (@see paginator tutorial below for usage).

Plugin Configuration

paginatorClass

Assigns CSS class to paginator element. Default is pagination

paginatorContentId

Assigns CSS id to paginator content element. Default is paginator_content

itemsPerPage

The number of items per page

totalEntries

Maximum number of pagination links that are visible. Set to 0 to display a simple "Previous/Next"-Navigation. Default: 10.

currentPage

The page that is selected when the pagination is initialized. Default: 0

totalEdgeEntries

If this number is set to 1, links to the first and the last page are always shown, independent of the current position and the visibility constraints set by totalEntries (num_display_entries for pagination plugin options). You can set it to bigger numbers to show more links. Default: 0

prevText

Text for the "Previous"-link that decreases the current page number by 1. Leave blank to hide the link. Default: "PREV"

nextText

Text for the "Next"-link that increases the current page number by 1. Leave blank to hide the link. Default: "PREV"

ellipseText

When there is a gap between the numbers created by totalEdgeEntries and the displayed number interval, this text will be inserted into the gap. Can be left blank. Default: "..."

showPrev

If this is set to false, the "Previous"-link is only shown when the page number can be decreased. Default: true.

showNext

If this is set to false, the "Next"-link is only shown when the page number can be increased. Default: true.

showPageXofY

If this is set to true, the "Page X of Y" is displayed to the left or right of the paginator's navigation, depening on settings for xofyLeft and xofyRight boolean values.

xofyLeft

Set to true for diplaying "Page X of Y" to the left of the paginator's navigation.

Note: it is not possible to set both xofyLeft and xofyRight to true

xofyRight

Set to true for diplaying "Page X of Y" to the right of the paginator's navigation.

elementModel

Model for each paginator item. Please see plugin tutorial for proper usage.

postUrl

Path to server-side paginator's data file. Please see plugin example for file template.

fieldnames

An array of field names of mysql table field names. (Parallel with elementModel)


Paginator example

In this example I will paginate data from a mysql database table that stores news for a web site, and use PHP to return my query result to the paginator (in JSON format).

Listed below is the structure for the table used for this example.

`id` int(11) unsigned NOT NULL auto_increment,
`title` varchar(255) default NULL,
`title_wwwsafe` varchar(255) default NULL,
`thumb_cmimg` varchar(255) default NULL,
`nbody_cmtxt` longtext,
`date_dpicker` date default NULL,
`norder` int(10) NOT NULL default '0',
`status` enum('enabled','disabled') NOT NULL default 'disabled',
PRIMARY KEY  (`id`)

The pagination process will have to display the following data for each paginator item:

  1. News thumbnail
  2. News heading
  3. News date
  4. News body text (limited to first 30 words formatted as a paragraph)
  5. A "read more" link that loads, via a search-engine friendly URL, news_reader.php (this file receives the row id for showing full news body text).
  1. Include jQuery, a paginator skin and paginator plugin within the head block of your document:

    <!-- jQuery paginator skin + js -->
    <link href="jquery_pagination/skins/default.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="jquery_pagination/jquery.paginator-min_jso.js"></script>
    <!-- /jQuery paginator skin + js -->

    Please note that the above code includes the minified and obfuscated version of jquery.paginator.js

  2. Default HTML markup structure for body block

    <div id="paginator" class="pagination"></div>
    <div style="clear:both;">
    <div id="paginator_content"></div>
    </div>
  3. The server-side data provider

    Let's prepare now the server-side PHP file responsible to provide data to jQuery Paginator. Create a PHP file that does the following:

    1. sets HTTP headers for JSON output

      header('Cache-Control: no-cache, must-revalidate');
      header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
      header('Content-type: application/json');
    2. verifies that the request originated from a permitted HTTP referer (i.e. the location of pagination file)

    3. connects and queries the database to obtain data result as an associative array. The following is the var_dump() of the result array of my query:

      array(5) {
        [0]=>
        array(6) {
          ["id"]=>
          string(1) "8"
          ["title"]=>
          string(15) "dummy heading d"
          ["title_wwwsafe"]=>
          string(15) "dummy_heading_d"
          ["thumb_cmimg"]=>
          string(47) "http://www.myjquery.co.uk/depot/logo_176x32.png"
          ["nbody_cmtxt"]=>
          string(16) "<p>news body</p>"
          ["date_dpicker"]=>
          string(10) "2009-07-05"
        }
        [1]=>
        array(6) {
          ["id"]=>
          string(1) "7"
          ["title"]=>
          string(15) "dummy heading c"
          ["title_wwwsafe"]=>
          string(15) "dummy_heading_c"
          ["thumb_cmimg"]=>
          string(47) "http://www.myjquery.co.uk/depot/logo_176x32.png"
          ["nbody_cmtxt"]=>
          string(16) "<p>news body</p>"
          ["date_dpicker"]=>
          string(10) "2009-07-04"
        }
        [2]=>
        array(6) {
          ["id"]=>
          string(1) "6"
          ["title"]=>
          string(15) "dummy heading b"
          ["title_wwwsafe"]=>
          string(15) "dummy_heading_b"
          ["thumb_cmimg"]=>
          string(47) "http://www.myjquery.co.uk/depot/logo_176x32.png"
          ["nbody_cmtxt"]=>
          string(17) "<p>news  body</p>"
          ["date_dpicker"]=>
          string(10) "2009-07-02"
        }
        [3]=>
        array(6) {
          ["id"]=>
          string(1) "5"
          ["title"]=>
          string(15) "dummy heading a"
          ["title_wwwsafe"]=>
          string(15) "dummy_heading_a"
          ["thumb_cmimg"]=>
          string(47) "http://www.myjquery.co.uk/depot/logo_176x32.png"
          ["nbody_cmtxt"]=>
          string(16) "<p>news body</p>"
          ["date_dpicker"]=>
          string(10) "2009-07-01"
        }
        [4]=>
        array(6) {
          ["id"]=>
          string(1) "4"
          ["title"]=>
          string(25) "welcome to myjquery.co.uk"
          ["title_wwwsafe"]=>
          string(25) "welcome_to_myjquery.co.uk"
          ["thumb_cmimg"]=>
          string(47) "http://www.myjquery.co.uk/depot/logo_176x32.png"
          ["nbody_cmtxt"]=>
          string(16) "<p>news body</p>"
          ["date_dpicker"]=>
          string(10) "2009-06-29"
        }
      }
            
    4. limits to 30 words, and removes any HTML formatting tag, each news body text.

      Before echoing the JSON encoded version of the result array, loop the result array and alter the value for the news body text field. I have achieved this by doing the following:

      for($i = 0; $i < count((array) $result); $i++)
      {
         foreach ($result[$i] as $k => $v)
         {
            if ($k == 'nbody_cmtxt')
            {
                $result[$i][$k] = '<p>' . StringHelper::limitWords(stripslashes($v), 30) . '</p>';
             }
          }
      }     
            

      To strip tags and limit the body text string to 30 words I used the static method limitWords(string, int) of the StringHelper class for the value of each nbody_cmtxt field (also applied stripslashes() function). For those who might find it useful the code for the method is:

         /**
          * Limits word count of argument $aText to the value of $wordCountLimit
          * 
          * Html tags are removed from string
          * 
          * @param string $aText
          * @param integer $wordCountLimit
          * @return string
          */
         public static function limitWords ($aText, $wordCountLimit)
         {
            if (strlen($aText) > 0)
            {
               $tagStrippedText = strip_tags($aText);
               if (str_word_count($tagStrippedText) <= $wordCountLimit)
               {
                  return $tagStrippedText;
               }
               return implode(' ', array_slice(explode(' ', $tagStrippedText, $wordCountLimit), 0, ($wordCountLimit - 1))) . '...';
            }
            return '';
         }      
            
    5. outputs JSON encoded version of the result array. For array at step 3 the output is:

      [[{"id":"8","title":"Dummy Heading D","title_wwwsafe":"dummy_heading_d","thumb_cmimg":"http:\/\/www.myjquery.co.uk\/depot\/logo_176x32.png","nbody_cmtxt":"<p>news body<\/p>","date_dpicker":"2009-07-05"},{"id":"7","title":"Dummy Heading C","title_wwwsafe":"dummy_heading_c","thumb_cmimg":"http:\/\/www.myjquery.co.uk\/depot\/logo_176x32.png","nbody_cmtxt":"<p>news body<\/p>","date_dpicker":"2009-07-04"},{"id":"6","title":"Dummy Heading B","title_wwwsafe":"dummy_heading_b","thumb_cmimg":"http:\/\/www.myjquery.co.uk\/depot\/logo_176x32.png","nbody_cmtxt":"<p>news","date_dpicker":"2009-07-02"},{"id":"5","title":"Dummy Heading A","title_wwwsafe":"dummy_heading_a","thumb_cmimg":"http:\/\/www.myjquery.co.uk\/depot\/logo_176x32.png","nbody_cmtxt":"<p>news body<\/p>","date_dpicker":"2009-07-01"},{"id":"4","title":"Welcome to myjquery.co.uk","title_wwwsafe":"welcome_to_myjquery.co.uk","thumb_cmimg":"http:\/\/www.myjquery.co.uk\/depot\/logo_176x32.png","nbody_cmtxt":"<p>news body<\/p>","date_dpicker":"2009-06-29"}]]
            

      Note: If you run PHP 5 (or greater) on your server you can use the function json_encode() to obtain the above output. For more info about json_encode() function please refer to the php manaul at http://php.net/manual/en/function.json-encode.php

  4. On DOM ready

    On DOM ready active the paginator by supplying configuration options values and initiating the pagination. Check the woking demo to view example of this step

       <script type="text/javascript">
          $(function(){
               var cpn = parseInt(readCookie('px'));
               cpn = !cpn ? 0 : cpn;
               var options = {postUrl:"http://www.myjquery.co.uk/paginators_data/demo_news_data.php",
                   itemsPerPage: 2,
                   elementModel: ['<div style="margin-bottom:20px;"><img src="{0}"/>', '<h1><span class="date">{2}</span>', ' - <span style="font-size:12px;color:red;">{1}</span></h1>','<p class="text">{3}</p>', '<a href="http://www.myjquery.co.uk/news/read/{4}/', '{5}.php"><div class="sub_btn"><h4 class="span">Read More</h4></div></a><br class="clear" /><div class="dotted_spacer"></div></div>'],
                   fieldnames:["thumb_cmimg", "title", "date_dpicker","nbody_cmtxt", "id", "title_wwwsafe"],
                   currentPage: cpn,
                   showPrev: true,
                   showNext: true,
                   showPageXofY : true,
                   xofyLeft : true,
                   xofyRight : false
                };
                $("#paginator").paginator(options);
          });
       </script>
       

    Current page number

    var cpn = parseInt(readCookie('px'));
    cpn = !cpn ? 0 : cpn;   
       

    These two lines of code are responsible for setting the current page number by reading the cookie for the last page viewed by user. If the cookie does not exist or is expired page number is set to 0 (i.e. 1 in pages naviation)

    Element Model

    elementModel: ['<div style="margin-bottom:20px;"><img src="{0}"/>',...]
    fieldnames:["thumb_cmimg", "title", "date_dpicker","nbody_cmtxt", "id", "title_wwwsafe"]   
       

    The elementModel and fieldnames are parallel arrays and are also a reflection of the array for each row held in the server-side database query result array. The elementModel array defines the html for each paginator item. The fieldnames array defines which value from the database query should replace {n} in elementModel.
    Each value originated from querying the database is wrapped around each element of the elementModel array. In this example, the first element to be displayed for each paginator item is the thumbnail image for a news. So I set the src attribute of the img tag to be {0} and set the first element of fieldnames array to the db field name for the thumbnail image thumb_cmimg

    <div style="margin-bottom:20px;"><img src="{0}"/>'
    

    Note that I have opened a div element as well; this will be closed in the last element of the elementModel array.

  5. To implement the 'read more' link I edit the .htaccess file to generate a search-engine indexable URL for the news_reader file.

    In the .htaccess file, I enable the rewrite engine and set up engine rule by writing the following:

    RewriteEngine On
    RewriteRule ^news/read/([0-9]+)/([0-9a-z_-]+).(html|php)$ /news_reader.php?i=$1  [QSA]  
       

    The goal is to rewrite something like news_reader.php?newsid=n, where n is an id referencing a database table row, to something more search-engine friendly like news/read/x/news_title.php. This is when the `title_wwwsafe` field I created in the database comes into play as I want to use this value to create the file name for my news reader.

    I do this by setting element 4 in elementModel array to be '<a href="http://www.myjquery.co.uk/news/read/{4}/' and element 5 to '{5}.php">'.

    I have to set now the value of element 4 in fieldnames array to 'id' and element 5 to 'title_wwwsafe'.

    '<a href="http://www.myjquery.co.uk/news/read/{4}/', '{5}.php">'

    jQuery paginator plugin will output a link for each 'read-more' paginator item like similar to http://www.myjquery.co.uk/news/read/8/dummy_heading_d.php

    If you cannot create an .htaccess file or dont have a server with mod_rewrite you can still generate a parameted link such as http://yoursite.com/news_read.php?anewsid=n. The pagination will work just fine.

Downloads

jQuery Plugins