Skip to content


showResults – jQuery plugin to add Ajax / JSON results with pagination, history and sorting

Download showResults Version 2.0.6:
Latest Major Version (6.68KB)
Latest Major Version Minified (4.09KB)

Dependencies:
jQuery v.1.3.x
jQuery History Plugin

Current Version Demo:
http://www.stephenrhoades.com/demos/showResults-demo.html

Download showResults Stand Alone Version 1.1.2:
Stand Alone Version

Requires:
jQuery v.1.3.x

Old Version Demo:
http://www.stephenrhoades.com/demos/showResults-demo-deprecated.html

What’s New

In the latest release 2.0.2 I have implemented a column level sorting feature. Currently, the sorting feature will sort strings, numbers and dates in MM/DD/YYYY format. I plan on adding more sorting options as the need arises. In addition to the results sorting, I have also added browser history to both the sorting and pages of the showResults plugin, added in version 2.0.1. This plugin does require the jQuery History Plugin.

Overview

Like most developers I find that I am consistently utilizing paginated result sets in my projects. The idea behind this plugin is to virtually eliminate the server side need to handle this coding. Simply send the full result set to the browser and let the client handle the rest. I have tested this plugin sending over 80,000 results (roughly 3MB of data) and it runs flawlessly.

Because this plugin is template driven, the way in which you can utilize it is virtually limitless.

This plugin allows dropping in templatized, paginated, Ajax driven “JSON” results a synch. The plugin expects a numerically indexed array of objects (Could be JSON). The container should contain a tokenized “template” so that the plugin knows how to handle the results. If you are familiar with template systems such as Smarty this should be familiar to you.

How does it work

Below you will find example data to dump into the result set. If pages are not greater than 1 than no pages are displayed. The showResults plugin will loop through the array and replace your tokens with the Key value of your objects. For instance, using the example data below, %name% would be replaced by the data[n]['name'] value.

var data = [
     {"name" : "Steve", "age" : "31", "birthday" : "12/1/1977"},
     {"name" : "John", "age" : "24", "birthday" : "2/1/1985"}
];
 
$(document).ready(function() {
     $("#myContainer").showResults(data);
});

Options

callback – Function to be executed once results are shown. Will be called on each result set change.
pages – Number of pages to display (Default is 10)
limit – Number of results to display (Default is 5)
start – Offset to start the display at. For example if you are displaying 10 results per page and choose to start at the 100th record, you would start on page 11.
resultTarget – Container name to send the parsed result to
pagesTarget – Container name to send pagination to
*changed in 2.0.2* bgColors (was alternateBackground in previous versions) – Array of 2 values that will be used to populate a %bgcolor% tag in your template. The plugin will alternate color assignments, this value can be a class name or a style color.
*new as of 2.0.2* arrows – an Array of Ascending and Descending indicators respectively. ['ASC','DSC']. These values can be any valid HTML and will get placed into a “.sort-marker” container.
Example 2.0.2 Usage:

$(document).ready(function() {
     $("#myContainer").showResults(data, {
             callback: callback,
             limit: 20,
             pages: 15,
             resultTarget: "#results",
             pagesTarget: ".myPaginator",
             bgColors: ['color1','color2'],
             arrows: ['','']
      });
});
function callback() {
	$("#searchResults > tr").click(function() {
		$(this).find("td").toggleClass("background");
	});
}

Template

Template tokens should be encapsulated between % symbols. These tokens will automatically get replaced by your object values. You must use the class name “template” to identify which container is a template.

Example of template formatting.

<div id="myContainer">
<table style="display: none;" border="0">
<tbody class="template">
			<!--// Start Template //-->
<tr class="%bgcolor%">
<td>%name%</td>
<td>%age%</td>
<td>%birthday%</td>
</tr>
<!--// End Template //--></tbody></table>
<table id="searchResult" border="0" width="450">
<thead>
<tr>
<!--// add links and classes to enable sorting //-->
<th width="45"><a class="sort" href="#sort-name">NAME</a></th>
<th width="60"><a class="sort" href="#sort-age">AGE</a></th>
<th width="60"><a class="sort" href="#sort-birthday-date">BIRTHDAY</a></th>
<!--// birthday takes a 3rd option in the hash "date" to indicate it's data type //--></tr>
</thead>
<tbody id="searchResults">
		<!--// Result Set Goes Here //--></tbody></table>
</div>

Pagination

The plugin adds a .pagination container with a span with a class of .active to represent the current selected page.

Example:

<div class="pagination">
    <span class="active">1</span>
    <a href="#unique_url">2</a>
    <a href="#another_unique_url-next">Next</a></div>

To Do

  • Multiple instance browser history.
  • When history is invoked, sorting is acting opposite of selected sort order. This is due to a switch based sorting mechanism to determine Ascending and Descending sort respectively. Need to append hash to indicate which sort order is being applied.
  • Ability to narrow result set by predefined column values.

In Development

I have received several requests to decouple the history functions from the main app. I am working on seperating this functionality via a plugin interface. I would love to receive your feedback, have features you would like to see? Please let me know.

Releases

  • 2.0.6

    • Fixed a bug relating to the hash and history. Script now validates against isNaN to ensure a number is passed for the offset, otherwise script simply returns.
  • 2.0.5

    • Some internal variables were exposed as options, these variables are now correctly encapsulated. Further reduced file size.
  • 2.0.4

    • Reduced filesize. Increased performance by reducing selectors.
  • 2.0.3

    • Major Version. Optimized sorting code, reduced filesize.
  • 2.0.2

    • Adds column level sorting. Plugin listens for .sort, sortable columns are designated by a #sort-column. Allows for custom arrow indicators via the arrows option.
  • 2.0.1

    • Added browser history for pagination & results. Plugin generates a unique hash that can be bookmarked as well as included in the browser history BACK and FORWARD buttons.
  • 1.1.2

    • fixed rendering issue with IE.
  • 1.1.1

    • Added a callback function to be executed when results are drawn. (Occurs once per page).
    • Improved container detection
    • Template rendering now replaces ALL Tokens, Previously only replaced the first token.
    • Now throws error if array is not passed to plugin.

Posted in jQuery Plugins & Framework. Tagged with .

23 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Osvel said

    I’m getting error: $.historyInit is not a function

  2. Steve Rhoades said

    Osvel, Please ensure that you are also including the jQuery History Plugin. If you are using v2 of showResults it depends on that plugin.
    http://www.mikage.to/jquery/jquery.history.js

    Please let me know if you continue to have issues.

  3. Sebastian said

    Really nice work. Simple to use and implement, and seems to work flawlessly even in IE6. :-)

    One thing that would make it even more flexible would be to be able to traverse deeper into the json in the template. i.e. %address.city%. Sometimes we can’t control what data we’re getting, and it would really be neat not to have to restructure the json-data for such requests.

    All in all, nice work!

  4. Sebastian said

    Please note that this kind of development is not my forte. Although I did manage a hack for my above mentioned problem. Thought I’d share it here for people to use or (more likely) enhance and re-write in a proper manner. :-)


    function replaceTemplateVariables(template, jsonBranch, currentPosition) {
    for(var node in jsonBranch) {
    var regex = new RegExp("%" + currentPosition + node + "%", "g");
    template = template.replace(regex, jsonBranch[node]);
    if(typeof jsonBranch[node] == 'object')
    template = replaceTemplateVariables(template, jsonBranch[node], currentPosition + node + ".")
    }
    return template;
    }

    And in the code you just call it like so:

    template = replaceTemplateVariables(template, p.r[i], "");

  5. Steve Rhoades said

    Sebastian,

    Excellent improvement. I will be including this in the next release with a credit to you.

    Cheers!

    Steve

  6. .Nile said

    Where could I find the CSS files mentioned in the demo? Is there a way to grab those?

  7. I might concur with wanting the css files on the simple non-paginated demo. My efforts fail to get the output in separate cells, nor are separate cells even created under the table. I also needed to change the #results to:
    resultTarget: “#searchResults”,
    to get any output to the screen. I don’t need pagination, I just want the sorting, and this is perhaps a bit too involved to make that worth the effort

  8. Steve Rhoades said

    David, hard for me to understand where you are running into the disconnect. I would be happy to assist you if you wish to point me to where you are utilizing the code. The #searchResults (ID) can really be called whatever you want, you just need to inform the plugin what the ID of the results container is.

    CSS File is located at:
    http://www.stephenrhoades.com/demos/css/showResults.css

  9. Mike said

    Great tool & solved a headache I was having. However I did run into one problem in which I needed the starting index of the data array available in the callback.

    My first solution involved parsing the URL anchor in the callback which worked great of FF and IE. It failed miserably on Safari though. It appears the callback executed before the dom was updated with the new URL. So I modified the library to pass the offset to the callback function.


    if (typeof o.callback == "function") {
    o.callback(o.start);
    }

    @Steve – Do you plan standardize any arguments to the callback function? Something akin to the event object? Or is there a better way of obtaining the starting index that I missed?

  10. Sergio said

    I’m having problems after rendering a request.
    The results render ok on the paginator but
    when I delete an item (submitting the operation to the DB)
    and I try to render again the results on the paginator,
    it doesn’t appear anything.
    Could you help with this issue?

    Thank you!!

  11. Mikkel Breum said

    suggestion: Add option to render empty results table

    Descr: sometimes a query might return no match, and in that case this plugin will not re-render the resultslist, but instead output a message (defined with the option emptyMsg: ‘no results’). Instead I wanted it to render an empty table, and output no messages.

    I changed the following in the file showResults.2.0.6.js:

    Where the default parameter values are set:

    (function($) {
    $.fn.showResults = function(oR, opt) {
    if(!$.isArray(oR)) {
    throw "showResults expects an array";
    }
    var o = {
    limit: 5,
    pages: 10,
    start: 0,
    resultTarget: '',
    pagesTarget: '',
    bgColors: [],
    arrows: [" Ascending"," Descending"],
    emptyMsg: 'No Results',
    allowempty: true,
    callback: null
    };

    And where the empty resultset is handled:

    // modified to make table clear without showing warning if empty resultset is returned
    if(p.t == 0) {
    if(o.allowempty == false){
    $(this).append(o.emptyMsg);
    return;
    }
    }
    ///////////////////////////////////////////////////////////

    The optional parameter allowempty can then be set to true or false when applying the plugin.

  12. Rasmus said

    Im trying to get your plugin to work. I get the results showing, but all and tags in the template is missing!

    Im using jquery 1.3.2 and i have tried to copy paste your code exactly, but still no luck

    Can you help me?

  13. Steve Rhoades said

    I am happy to help. Please respond with a public URL of where your code is located and I will take a look.

    Regards,

    Steve

  14. Rasmus said

    Take a look at http://www.bandspot.micah.dk

    I have copy-pasted your code examples and i now i dont get anything at all. Before, i got the data without the template.

  15. Mo said

    For those not getting anything on their initial screen. I think I found the bug that’s causing the problem. On line 270 of the javascript file there’s a line

    $.historyInit(self._history);

    This line doesn’t actually call the “_history” method, which initializes the data loading. I added a line that explicitly calls the method right before that line. The code I have now reads:

    self._history(“”);
    $.historyInit(self._history);

    which seems to have solved the problem. It assumes that there are no hashes related to paging and sorting since it is the initial call, which is why no hash parameter (characters following # in the URL) is submitted.

  16. John Jimenez said

    So what’s the deal with the plugin? Is it still be developed or has it been abandoned?

    It looks like it is incompatible with the latest jquery history code, and I am getting a number of issues in chrome. Just curious if this is a plugin I should invest in or not.

  17. Tom said

    Hi Stephen, any chance you can provide a demo zip project to download and run. have tried the latest showResults.2.0.6.js and nothing is rendered to my screen. have tried some of the above suggestions but unfortunately i’m a jquery beginner.

    Thanks

  18. Tom said

    also debugging through the code and
    $(“.template”, this).html(); returns null. hence p.tpl = null. this causes issues further down when the template is set..
    anyone seen this behaviour?

    thanks

  19. Steve Rhoades said

    @Tom You need to declare on the parent to your template the “template” class. If you view the source for the demo you should see this.

  20. Steve Rhoades said

    @John It’s been quite some time since I have had any time to dedicate to this plugin – I have not tested this with the latest version of jQuery. You can view the source for the demo page and see the files utilized at the stage this was left in development.

  21. KS said

    How do you prevent the hashtags from being added to the URL in the address bar?

  22. KS said

    Got it sorted had to edit the history.js file. and used location.hash=’ ‘;

Continuing the Discussion

  1. PHP 5, MySQL and showResults jQuery Plugin - Stephen Rhoades linked to this post on February 21, 2009

    [...] In this article you will see an example of pushing JSON encoded data to the browser for use in the showResults jQuery plugin. [...]

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.