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.



This is where the paging content loads...


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>
        <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=""></script>
        <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>
        <script src=""></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-"></script>
        <script id="line-template" type="text/x-handlebars-template">
            <!-- Handlebars JS Template -->

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.


General Pager Display

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

        position: 'both',
        class: 'someclass',
        stripedrows: true,
        loadtext: 'Retrieving your data...',

General Paging

the page of results to display (defaults to "1")
the number of records to display in a page (defaults to "25")
boolean to determine if the "Limit" dropdown will display (defaults to "true")
an array of numeric values, dilineating the number of records per page (defaults to "[25,50,75,100]")
the column on which to initially sort results
asc|desc - the sort direction (defaults to "asc" if "sortcolumn" is defined)
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.
a json string of key/value pairs to pass to the remote method for filtering
    //Other stuff

        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

standard options of a JQuery Ajax request
the url to which the request is sent
the method type of the request (defaults to "POST")
an object for any extra values to be passed along with the request
the data type of the expected request response (defaults to "json")
an object, the parameters of which define the returned response (for json based or xml(?) responses)
key of the "success" indicator
key of the "message" indicator, used when "success" is false to indicate an error
server response indicating the total number of pages of available records for the search criteria passed
server response indicating the total number of records available that meet the search criteria passed
dot notation path to the root key of the dataset (record set) associated with the response
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)
the first record being requested
the number of records to be returned in each response
the page of data being requested
the column by which the data is currently being sorted by
the direction by which the data is currently being sorted by
a json string denoting search criteria beyond those already mentioned
a function that takes the server response (function(data)) and returns the formatted data to be displayed within the container
    // Reference and Compile the Handlebars template
    var tplContent = $('#line-template').html();
    var lineTpl = Handlebars.compile(tplContent);

        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


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

        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="{{}}">
        <div class="span2">
        <div class="span9">
        <div class="span1">

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.