The ajaxPager is a JQuery + Bootstrap plugin that creates a pagination control bar, according to configuration, that will make remote requests for data. The control then passes the response to a developer defined method to create the output. In the example, we used the Handlebars templating engine to create display items of each record in a returned JSON recordset.

ajaxPager is available on GitHub.

 

Demo

This is where the paging content loads...
 

Documentation

The ajaxPager component requires JQuery and Bootstrap be loaded in your template, as well as the stylesheet and script used for the ajaxPager.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <head>Our Test Case</head>
        <link href="/resources/scripts/bootstrap/css/bootstrap.css" rel="stylesheet">
        <link href="/resources/styles/custom/subnav.css" rel="stylesheet">
        <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
        <!--[if lt IE 9]>
            <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
    </head>
    <body>
        <div class="container-fluid">
            <div class="row-fluid">
                <div class="span2"> </div>
                <div class="span8">
                    <!-- Our Paged Container -->
                    <div id="testCont"> This is where the paging content loads...</div>
                </div>
            </div>
        </div>
        <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"></script>
        <script src="/resources/scripts/bootstrap/js/bootstrap.js"></script>
        <script type="text/javascript" src="/resources/scripts/bootstrap.ajaxpager-0.8.js"></script>
        <!-- Our custom script for our demo -->
        <script type="text/javascript" src="/resources/scripts/custom/pagingTest.js"></script>
        <!-- Use whatever templating method you want -->
        <!-- We'll use Handlebars JS for a templating engine in our example -->
        <script src="/resources/scripts/handlebars-1.0.0.0.beta.6.js"></script>
        <script id="line-template" type="text/x-handlebars-template">
            <!-- Handlebars JS Template -->
        </script>
    </body>
</html>
				

In our example we're using HandlebarsJS as our templating engine, but you can use whatever engine you like for rendering your output. The ajaxPager will:

  1. Create the pager bar(s) for your container element
  2. Make the ajax request
  3. Track the page, record count and total records (from the response)
  4. Take the response and process it through your method
  5. Render your output in the primary element

It does most of this behind the scenes. All that's required is instantiating the ajaxPager with a valid configuration.

Options

General Pager Display

position
top|bottom|both - the position(s) of the pager bars in relation to the container element (defaults to "top")
class
any additional classes to add to the pager bars when rendered
stripedrows
will apply a 'striped-row' class to every other element added to the container on data load (defaults to "false")
loadtext
the text that displays on the loading alert (defaults to "Loading")
$(document).ready(function(){
    // Other stuff

    $('div#testCont').ajaxPager({
        position: 'both',
        class: 'someclass',
        stripedrows: true,
        loadtext: 'Retrieving your data...',
        ...
    });
});
				

General Paging

page
the page of results to display (defaults to "1")
limit
the number of records to display in a page (defaults to "25")
limitdd
boolean to determine if the "Limit" dropdown will display (defaults to "true")
limitoptions
an array of numeric values, dilineating the number of records per page (defaults to "[25,50,75,100]")
sortcolumn
the column on which to initially sort results
sortdir
asc|desc - the sort direction (defaults to "asc" if "sortcolumn" is defined)
sortby
an object of key/value pairs, equating to a column name (key) and it's display label (value), to be used in the "Sort By" dropdown on the pager bar(s). If an object is not passed then the "Sort By" dropdown is ommitted.
searchtext
a json string of key/value pairs to pass to the remote method for filtering
$(document).ready(function(){
    //Other stuff

    $('div#testCont').ajaxPager({
        ...
        page: 1,
        limit: 10,
        limitdd: true,
        limitoptions: [10,20,30,40,50],
        sortcolumn: 'title',
        sortdir: 'asc',
        sortby: {
            title: 'Title',
            posted: 'Date Posted',
            views: 'Views'
        },
        searchtext: '{"title":"ColdFusion"}',
        ...
    });
});
				

Remote Request

ajaxoptions
standard options of a JQuery Ajax request
url
the url to which the request is sent
type
the method type of the request (defaults to "POST")
data
an object for any extra values to be passed along with the request
dataType
the data type of the expected request response (defaults to "json")
reader
an object, the parameters of which define the returned response (for json based or xml(?) responses)
success
key of the "success" indicator
message
key of the "message" indicator, used when "success" is false to indicate an error
totalpages
server response indicating the total number of pages of available records for the search criteria passed
totalrecords
server response indicating the total number of records available that meet the search criteria passed
root
dot notation path to the root key of the dataset (record set) associated with the response
params
key/pairs that allow the developer to override the key names, of default data, that are passed in each request (each defaults to their key name)
start
the first record being requested
limit
the number of records to be returned in each response
page
the page of data being requested
sort
the column by which the data is currently being sorted by
dir
the direction by which the data is currently being sorted by
search
a json string denoting search criteria beyond those already mentioned
renderoutput
a function that takes the server response (function(data)) and returns the formatted data to be displayed within the container
$(document).ready(function(){
    // Reference and Compile the Handlebars template
    var tplContent = $('#line-template').html();
    var lineTpl = Handlebars.compile(tplContent);

    $('div#testCont').ajaxPager({
        ...
        ajaxoptions: {
            url: 'com/cc/Blog/Entries.cfc',
            data: {
                method: 'getEntries',
                returnFormat: 'json'
            },
            dataType: 'json'
        },
        params: {
            page: 'pageIndex',
            limit: 'pageSize',
            sort: 'sortCol',
            dir: 'sortDir'
        },
        reader: {
            success: 'success',
            message: 'message',
            totalpages: 'pageCount',
            totalrecords: 'recordCount',
            root: 'data'
        },
        renderoutput: lineTpl, // Apply the Handlebars template to the output
        ...
    });
});
				

Events

listeners
an object containing function methods that fire when specific events occur
init
function(event) - fires when the component has initialized, after pagers have been added, but prior to bindings being set in the "render" event
render
function(event) - fires once the pagers have been rendered, just prior to all internal bindings being put into place
preprocess
function(response) - fires upon successful request, prior to any other processing (good for data conversions prior to creating output)
beforeload
function(event) - fires after "renderoutput", but prior to output being added into the container, typically for the removal of any developer defined bindings
load
function(event) - fires after the formatted output has been added to the container, typically for adding bindings to new content
destroy
function(event) - fires in component's "destroy" method, just prior to the component's removal of bindings, data, and display
$(document).ready(function(){
    ...
    var testHandler = function (){
        console.log(arguments);
    }

    $('div#testCont').ajaxPager({
        ...
        listeners: {
            init: testHandler,
            render: testHandler,
            preprocess: $.serializeCFJSON, // Convert native CF query json to standard name/value json
            beforeload	: testHandler,
            load		: testHandler,
            destroy		: testHandler
        }
    });
});
				

The only thing you really require now is a template for your templating engine. Some kind of definition for how you want each item of the dataset to be rendered. For the above example we used something very basic, using the Handlebars JS engine.

<script id="line-template" type="text/x-handlebars-template">
    {{#each data}}
    <div class="row-fluid data-row" id="{{this.id}}">
        <div class="span2">
            {{this.posted}}
        </div>
        <div class="span9">
            {{this.title}}
        </div>
        <div class="span1">
            {{this.views}}
        </div>
    </div>
    {{/each}}
</script>
				

That's it! Nothing to it! The pager will keep track of what page you're on, change your record counts, make and process your ajax requests, all behind the scenes.