Saturday, June 18, 2011

jQuery Tablesorter, The Missing Docs

If you need support for my fork of tablesorter, please contact me here:

The Missing Docs for jQuery Tablesorter 2.0

These docs have been incorporated into my

All Defaults


Appearance
cssHeader: "header"The CSS style used to style the header in its unsorted state.
cssAsc: "headerSortUp"The CSS style used to style the header when sorting ascending.
cssDesc: "headerSortDown"The CSS style used to style the header when sorting descending.
cssChildRow: "expand-child"This allows you to add a child row that is always attached to the parent. See the children rows section below.
widgetZebra: { css: ["even", "odd"] }Set the CSS classes used for zebra striping the table. See the updating zebra striping section below.
widthFixed: falseIndicates if tablesorter should apply fixed widths to the table columns. This is useful for the Pager companion. Requires the jQuery dimension plugin to work. See the main demo page
onRenderHeader: nullThis function is called when classes are added to the th tags. You can use this to append HTML to each header tag. See the Render Header section below.
Sort Options
sortInitialOrder: "asc"A string of the inital sorting order can be "asc" or "desc". This is overridden bt the sortList settings.
sortForce: nullUse to add an additional forced sort that is prepended to sortList. For example, sortForce: [[0,0]] will sort the first column in ascending order. See the main demo page
sortList: []Add an array of the order the table should be initially sorted; e.g. sortList: [[0,1], [1,0]]. The first part "[0,1]" will sort the first column (zero based index) in decending order and the second part "[1,0]" is to sort the second column in ascending order. See the main demo page.
sortAppend: nullUse to add an additional default sorting rule, that is appended to the sortList.
Parsers & Widgets
headers: {}See the Change how you sort a column section below or see the main demo page
textExtraction: "simple"See the Text Extraction section below or see the main demo page
sortLocaleCompare: trueBoolean flag indicating whenever to use String.localeCampare method or not. This is only used when comparing text strings.
parsers: {}Internal list of all of the parsers. See a complete list of parsers below.
widgets: []Initialize widgets using this option (e.g. widgets : ['zebra'], or custom widgets widgets: ['zebra', 'myCustomWidget']; see this demo on how to add a custom widget.)
selectorHeaders: 'thead th'jQuery selectors used to find the header cells. You can change this, but the table will still need the required thead and tbody before this plugin will work properly.
headerList: []Internal list of each header element as selected using jQuery selectors in the selectorHeaders option.
dateFormat: "us"Set the date format. See the dataFormat section below.
Interaction
sortMultiSortKey: "shiftKey"The key used to select more than one column for multi-column sorting. Defaults to the shift key. Other options might be ctrlKey, altKey. See the main demo page
cancelSelection: trueIndicates if tablesorter should disable selection of text in the table header (TH). Makes header behave more like a button.
Unknown
decimal: '/\.|\,/g'Regex to find the decimal "." for U.S. format and "," for European format... but I can't find it being used anywhere in the plugin.
Debugging
debug: falseBoolean flag indicating if tablesorter should display debuging information usefull for development. This displays information in the console, if available, or in alerts. See the main demo page

Update Default Settings

Update any of the default settings above using this format:
$(selector).data("tablesorter").{default name} = newValue;
Here are a few examples:
// Change sortForce
$("table").data("tablesorter").sortForce = [[1,0]];
// it appears that the only way to update the table is to resort it
$("table").trigger("sorton", [[0,1]]);
// Add zebra sorting after the table has initialized
$("table").data("tablesorter").widgets = ["zebra"];
// there is a method to apply widgets!
$("table").trigger("applyWidgets");

Child Rows

To add a row that remains attached to a parent row, add the "expand-child" class to the row.

You can add some scripting to hide these child rows and have them expand when you click on a link; this is the original reason for the css name.

Here is the original mod page, the code was added into the TableSorter core but remains undocumented.

This makes the tablesorter plugin keep these rows together. This css class can be changed using the "cssChildRow" option.

Here is some example markup:
<table width="100%" border="1">
  <thead>
    <tr>
      <th>Item #</th>
      <th>Name</th>
      <th>Available</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>12345</td>
      <td>Toy Car</td>
      <td>5</td>
    </tr>
    <tr class="expand-child"> <!-- this row will remain attached to the above row, and not sort separately -->
      <td colspan="3">
        It's a toy car!
      </td>
    </tr>
    <tr>
      <td>23456</td>
      <td>Toy Plane</td>
      <td>2</td>
    </tr>
    <tr class="expand-child"> <!-- this row will remain attached to the above row, and not sort separately -->
      <td colspan="3">
        It's a toy plane!
      </td>
    </tr>
    <tr class="expand-child"> <!-- this row will remain attached to the above two rows, and not sort separately -->
      <td colspan="3">
        and it flies!
      </td>
    </tr>
  </tbody>
</table>


Update Zebra Striping After Sorting

Actually the zebra striping widget does this for you automatically.

By default the odd and even rows are styled using "odd" and "even" class names ({ css: [ "even", "odd" ] }).

Change these css class names using the widgetZebra option as follows:
$(function(){
  $("table").tablesorter({
    widgets: ["zebra"], // initialize zebra striping of the table
    widgetZebra: { css: [ "normal-row", "alt-row" ] }
  });

Modify the Header Markup

The onRenderHeader option allows you to add a function that which can modify the HTML of each header tag. In the example below, the header cell (th) content is wrapped with a span tag to allow for better styling (source).
$(function(){
  $("table").tablesorter({
    onRenderHeader: function (){
      this.wrapInner('<span class="roundedCorners"></span>');
    }
  });
});
and you'll end up with this (only the thead is shown):
<thead>
  <tr>
    <th class="header"><span class="roundedCorners">Column 1</span></th>
    <th class="header"><span class="roundedCorners">Column 2</span></th>
  </tr>
</thead>


Change how you sort a column

The plugin attempts to detect the type of data that is contained in a column, but if it can't figure it out then it defaults to alphabetical.

You can easily override this by setting the header argument (or column parser).
$(function(){
  $("table").tablesorter({
    headers: {
      0: { sorter: false },      // disable first column
      1: { sorter: "digit" },    // sort second column numerically
      4: { sorter: "shortDate" } // sort the fifth column by date (e.g. mm/dd/yyyy if the date format is "us")
    }
  });
});
*Note* the header number starts with zero (zero based index).

Here is a list of available sorter values/parsers:

sorter: falsedisable sort for this column.
sorter: "text"Sort alphabetically.
sorter: "digit"Sort numerically.
sorter: "currency"Sort by currency value (supports "£$€").
sorter: "ipAddress"Sort by IP Address.
sorter: "url"Sort by url.
sorter: "isoDate"Sort by ISO date (YYYY-MM-DD or YYYY/MM/DD).
sorter: "percent"Sort by percent.
sorter: "usLongDate"Sort by date (U.S. Standard, e.g. Jan 18, 2001 9:12 AM).
sorter: "shortDate"Sort by a shorten date (see "dateFormat").
sorter: "time"Sort by time (23:59 or 12:59 pm).
sorter: "metadata"Sort by the sorter value in the metadata - requires the metadata plugin.

Change the Date Format (dateFormat)

"us""mm-dd-yyyy" or "mm/dd/yyyy"
"uk""dd-mm-yyyy" or "dd/mm/yyyy"
"dd/mm/yy" or
"dd-mm-yy"
Sort by short year (it appears to sort by day first, not the year)




Change the Sorted Columns

There are three options to determine the sort order and this is the order of priority:
  1. sortForce forces the user to have this/these column(s) sorted first (null by default).
  2. SortList is the initial sort order of the columns.
  3. SortAppend is the default sort that is added to the end of the users sort selection (null by default).
The value of these sort options is an array of arrays and can include one or more columns. The format is an array of instructions for per-column sorting and direction in the format: [[columnIndex, sortDirection], ... ] where columnIndex is a zero-based index for your columns left-to-right and sortDirection is 0 for Ascending and 1 for Descending. A valid argument that sorts ascending first by column 1 and then column 2 looks like: [[0,0],[1,0]]
$(function(){
  $("table").tablesorter({
    sortForce  : [[0,0]],        // always sort first column first
    sortList   : [[1,0], [2,0]], // initial sort columns (2nd and 3rd)
    sortAppend : [[3,0]]         // always add this sort on the end (4th column)
  });
});
*NOTE* When writing this post, I didn't realize that the sortAppend option was listed as an option, but the code for it did not exist. This problem is fixed in my fork of tablesorter (example).

Text Extraction

This is demonstrated in the Dealing with markup inside cells demo page, but the example uses vanilla javascript to find the desired text, like this:
$(function(){
  $("table").tablesorter({
    textExtraction: function(node) {
      return node.childNodes[0].childNodes[0].innerHTML;
    }
  });
});
But you could make your life easier and just make the node into a jQuery object and then "find" what you need:
$(function(){
  $("table").tablesorter({
    textExtraction: function(node) {
      return $(node).find("span:last").text();
    }
  });
});
Now if the text you are finding in the script above is say a number, then just include the headers sorter option to specify how to sort it. Also in this example, we will specify that the special textExtraction code is only needed for the second column ("1" because we are using a zero-based index). All other columns will ignore this textExtraction function.


*NOTE* When writing this post, I didn't realize that the textExtraction option did not allow defining it per column, as shown below, but this has been fixed in the forked github version - example.
$(function(){
  $("table").tablesorter({
    textExtraction: {
      1: function(node) {
           return $(node).find("span:last").text();
      }
    },
    headers: {
      1: { sorter : "digit" }
    }
  });
});


Methods

See examples of each further down
sortonResort the table using new sort parameters.
updateUpdate the stored tablesorter data and the table.
appendCacheUpdate a table that has had its data dynamically updated; used in conjunction with "update"
updateCellUpdate a table cell in the tablesorter data.
applyWidgetIdApply a widget (wrapped in square brackets) to the table one time only.
applyWidgetsApply previously selected widgets to the table - will update the widget with new sort.

Resort the table - "sorton" method

See the full example in the tablesorter docs: Sort table using a link outside the table
// Choose a new sort order
var sort = [[0,0],[2,0]];
// Note that the sort value below is inside of another array (inside another set of square brackets)
$("table").trigger("sorton", [sort]);

Update the Table

See the full example in the tablesorter docs: Appending table data with ajax
// Add new content
$("table tbody").append(html);
// let the plugin know that we made a update
$("table").trigger("update");
// set sorting column and direction, this will sort on the first and third column
var sorting = [[2,1],[0,0]];
// sort on the first column
$("table").trigger("sorton", [sorting]);

Append Cache

If you dynamically change the table content, more than just one cell like in the "updateCell" example above, you may possibly have to trigger two events: "update" and "appendCache".

This answer is from a StackOverflow answer
// Table data was just dynamically updated
$(table)
  .trigger("update")
  .trigger("appendCache");

Update a Table Cell

Example from these alternate tablesorter docs: Updating the table cache - the demo doesn't work, but I've tested the example code below and it works properly.
$(function() {
  $("table").tablesorter();
  $("td.discount").click(function(){
      // randomize a number
      var discount = '$' + Math.round(Math.random() * Math.random() * 100) + '.' + ('0' + Math.round(Math.random() * Math.random() * 100)).slice(-2);
      $(this).text(discount);
      // update the table, so the tablesorter plugin knows its value
      $("table").trigger("updateCell",[this]);
      // set sorting column and direction, this will sort on the first and third column
      var sorting = [[3,1]];
      // sort on the first column
      $("table").trigger("sorton",[sorting]);
      return false;
  });
});
<table class="tablesorter" cellspacing="1">
  <thead>>
    <tr>
      <th>first name</th>
      <th>last name</th>
      <th>age</th>
      <th>total</th>
      <th>discount</th>
      <th>date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>peter</td>
      <td>parker</td>
      <td>28</td>
      <td class="discount">$9.99</td>
      <td>20%</td>
      <td>jul 6, 2006 8:14 am</td>
    </tr>
    <tr>
      <td>john</td>
      <td>hood</td>
      <td>33</td>
      <td class="discount">$19.99</td>
      <td>25%</td>
      <td>dec 10, 2002 5:14 am</td>
    </tr>
    <tr>
      <td>clark</td>
      <td>kent</td>
      <td>18</td>
      <td class="discount">$15.89</td>
      <td>44%</td>
      <td>jan 12, 2003 11:14 am</td>
    </tr>
    <tr>
      <td>bruce</td>
      <td>almighty</td>
      <td>45</td>
      <td class="discount">$153.19</td>
      <td>44%</td>
      <td>jan 18, 2001 9:12 am</td>
    </tr>
    <tr>
      <td>bruce</td>
      <td>evans</td>
      <td>22</td>
      <td class="discount">$13.19</td>
      <td>11%</td>
      <td>jan 18, 2007 9:12 am</td>
    </tr>
  </tbody>
</table>

Apply a New Widget "applyWidgetId"

Apply a widget to the table. In this example, we apply the zebra striping to the table after it has been initialized.
$(function(){
  // initialize tablesorter without the widget
  $("table").tablesorter();
  
  // click a button to apply the zebra striping
  $("button").click(function(){
    $('table').trigger('applyWidgetId', ['zebra']);
});

Apply Chosen Widgets "applyWidgets"

Reapply a widget to the table. In this example, we apply the zebra striping to the table after it has been initialized.

This is basically an alternate method to the "applyWidgetId", but in the example below you can add or remove widgets from the chosen list.
// Update the list of widgets to apply to the table (add or remove)
$("table").data("tablesorter").widgets = ["zebra"];
$("table").trigger('applyWidgets');




Triggered Events

sortStartThis event fires when the tablesorter plugin is about to start resorting the table.
sortEndThis event fires when the tablesorter plugin has completed resorting the table.


Bind to the "sortStart" and/or the "sortEnd" events as shown on the example page
$(function(){
  // initialize the tablesorter plugin
  $("table").tablesorter();
  // bind to sort events
  $("table")
    .bind("sortStart",function() {
      $("#overlay").show();
    })
    .bind("sortEnd",function() {
      $("#overlay").hide();
    });
});
Or here is another example from StackOverflow
$(function(){
  $("table")
    .tablesorter()  
    .bind("sortEnd", function(){  
      $("table tr").removeClass("block");
      // adds the "block" class to every 8th row
      $("table tr:nth-child(8)").addClass("block");
    });
});

84 comments:

  1. Thanks very much for this post Mottie.

    I wonder if you might be able to help me with a sorting issue I'm having. The table I have is sorting a bunch of product id numbers, I thought they were all going to be only numerical but the client gave me the data and the cells I need to sort are mixed alpha-numeric, for example RuR 14, Rur 28, PT 6, things like that.

    The problem is it won't sort alphabetically and numberically, for example

    Pt 1
    Pt 12
    RuR 1
    RuR 10
    RuR 11
    RuR 12
    RuR 2
    RuR 21

    Is there any way to have sort first alphabetically then numerically?

    Any advice would be much appreciated, this is the last outstanding item in this project.

    Thanks!
    Mike

    ReplyDelete
  2. Hi Mike!

    Well there is no easy way to get Tablesorter to sort alphanumerically. So I thought I'd just add it :P

    So, I added the updated plugin to my Github repository and made a demo showing the new alphanumeric sort.

    I hope you find it useful!

    ReplyDelete
  3. Hi!

    Is there anyway to make the list of columns that tablesorter does NOT sort be something other than zero-based? Maybe by name or ID?

    I have a table who's columns are dynamically generated so column 5/Price isn't always Price. Which means that the following code isn't always correct...

    headers: {
    5: {sorter: 'digit'}
    }

    Is there a way to go off of the column name or column ID so no matter where that column is in the table it isn't sortable?

    headers: {
    'price' :{sorter:'digit'}
    }

    Thanks

    ReplyDelete
  4. Hi goratriki!

    If you leave out the specific sorter in the header, it should figure it out by itself. So just completely remove the "headers" option when you initialize the sorter.

    If the content of the table is changed dynamically, then you'll also have to use the code from the post above under "Update the Table".

    ReplyDelete
  5. The tablesorter documents hosted in my github repository have been updated with these missing docs! I hope someone finds them useful!

    ReplyDelete
  6. Hi!

    Thanks! I have done this way:

    Delete all this from the js

    headers: {
    6: {
    sorter: 'digit'
    },
    7: {
    sorter: 'fechas'
    }
    }

    Add jquery.metadata.js

    And add this by code in each header I want to sort by digit or data:
    objTblCell.CssClass = "{sorter: 'digit'}"

    ReplyDelete
  7. Hi,

    textExtraction: {
    1: function(node)...

    textExtraction for certain column is not working and looking at the tablesorter code I do not see how this should work at all since the only check is for function, not an object.

    Thanks

    ReplyDelete
  8. Hi Eugene Ivakhiv!

    Thanks for bringing this to my attention, I thought that was built in functionality. Anyway, I've added it and updated the textExtraction demo. Check it out!

    Thanks!
    Rob

    ReplyDelete
  9. Fix looks good!

    I've found another issue unrelated: multisort crashes on empty table. Looked thru the code and looks like no checks for empty row cache. I've tried to add checks before appendToTable() calls but it is not enough. Headers clicks are not working for empty table so I think it needs better fix.

    Thanks,
    Eugene

    ReplyDelete
  10. Hey again!

    Ok, I've fixed that problem as well :)

    ReplyDelete
  11. Hello Mottie,

    I've checked your fix. Script is not crashing but header clicks on empty table are still not working.

    Assume the following scenario which is pretty valid:
    1) user has empty table which values are dynamic and will be filled in later;
    2) user sorts columns (empty yet) by clicking headers as he wishes;
    3) values are filled in table with sort order already set.

    Right now headers click handling is bypassed if row count is 0. However it is not correct and it should be handled in order to trigger events like sortStart, sortEnd and proper widget handling.

    Thanks.
    Eugene

    ReplyDelete
  12. Thanks for your work on this documentation, it's helpful. I just wanted to say, I think you should make it clearer that in some parts you're documenting your own mod, not Christian Bach's latest version. I spent a long time trying to figure out why the textExtraction by column syntax you show wasn't working, until I went down and read the comments to see that it doesn't work with the original code. It should be clear right at the top of the article, and wherever you're documenting changes you made. I'm happy to try your mod from github, but it would have saved me a lot of time if I knew that's what you were talking about before reading the comments. But I appreciate your work nonetheless, it's great and thanks for doing it.

    ReplyDelete
  13. Ahhh, good point, I'll update the docs. Thanks for the feedback :)

    ReplyDelete
  14. I do not understand the usage of cancelSeletion option. Setting it to true does not change much for me. I want to have a search box in my header to be used as a filter for the column. Is there a way to do that. Currently clicking on the search box sorts the column still. I do not way that. Only clicking outside the search box (but within the header cell) should perform sorting.
    Thanks

    ReplyDelete
  15. Hi Aditya!

    The "cancelSelection" option prevent you from mouse clicking and dragging the text in the header. That way when you click and move the mouse, it's not highlighting text there.

    As for adding a filter, I could throw something together (a widget maybe), but thinking about it, it may not work well with the pager plugin. So it'll take a bit more work to get a good solution. Please keep an eye on the github repository for further updates.

    ReplyDelete
  16. Thanks for the documentation, it's great.
    Is there a way to dynamically sortAppend? I've got 3 column table(status, date, doc type), clicking on status should sort status & date, clicking on date should sort date & doc type, clicking on doc type should sort doc type & date. sortAppend is appended to all columns, right?

    ReplyDelete
  17. Hi David,

    Hmm, sortAppend isn't dynamic, I tried to tie into the "sortStart" event, but it isn't defined at that point... I guess I could add another event immediately before the sort to adjust the sortList. I'm going to open a issue with your request. I would love some input on how you would like to make this setting dynamic. I'll work on ideas, and please monitor the tablesorter github repository for updates, thanks!

    ReplyDelete
  18. Hi David, I've updated the repository and made a demo for you here.

    ReplyDelete
  19. Great post Mottie. Was stuck with a problem but your missing doc helped me out. As for the official tablesorter's documentation, it needs serious work.

    ReplyDelete
  20. I need day-month-year in this order and also in french.Kindly replay for this post..
    For example:
    jour - mois - année or jj-mm-aaaa

    Thnx,
    vasa

    ReplyDelete
  21. Hi Vasanth!

    I made a demo for you using that format, but I also improved my github version - new demo.

    ReplyDelete
  22. Thanx for your replay mottie.But still the dates are display in numbers , i like to display in french lang...:) kindly replay for this comment.



    Thax,
    vasa

    ReplyDelete
  23. Can you share some example HTML? Just the HTML in a jsFiddle would help because I'm not sure what the layout looks like.

    ReplyDelete
  24. Is it possible to retain a users pagersize preferences ?

    ReplyDelete
  25. Hi @crush123!

    Thanks for reporting this problem. I've updated the github version to fix it :)

    ReplyDelete
  26. Thank you very much for this post Mottie.

    ReplyDelete
  27. Tablesorter always sort in the ascending direction.If user wants to do it descending in the first click it will not work.

    ReplyDelete
  28. Hi @predeep!

    The "sortInitialOrder" option might be what you are looking for. You can set the overall initial sort direction using that option (demo), or you can set the initial sort order in the header option (demo).

    ReplyDelete
  29. Hi Mottie, hope you can get your head round this one!

    I am using table sorter on a table that passes mySQL ID's to another page to allow me to update multiple records at a time.

    If I pass the records before sorting it works fine but if I sort and then try to pass the data, nothing is sent.

    I have tried to post the code here but as it won't allow me to post the word TABLE it didn't work!

    Is this something that anyone else has tried before?

    Regards
    Steve

    ReplyDelete
  30. Hi Whinge & Moan!

    I would appreciate it if you could email me a basic example of the HTML you are using and the initialization code. I use gmail with wowmotty as my user name, thanks!

    ReplyDelete
  31. Hi,

    I would appreciate it. i am using your code for sorting HTML Table i am sorting html table with following code. its working perfectly. but i need to pass dynamic value where colum 0 and colum 1.

    How can i do please help me.

    can i do like this ? i know its wrong but please try to solve my problem.

    $(document).ready(function() {
    var A =0;
    var B =4;

    $("#myTable").tablesorter({
    headers:{
    A: { sorter: false}, // disable 1st column
    B: { sorter: false} // disable 2nd column
    }
    });
    });

    ReplyDelete
  32. Hi @Bhavik Dharaiya!

    Actually the easiest solution would be to just use class names

    // disable first and third columns using class names
    $('#myTable thead').find('th:eq(0), th:eq(2)').addClass('sorter-false');

    Here is a demo

    ReplyDelete
  33. Wow, thanks for this wonderful script ;) But I hadgot a problem with Php number_format function. I have to use this function to make more "readable" a currency column. But using this function, the column was no more sortable.. as you can see here

    http://jsfiddle.net/Z9wdn/6/

    I fixed this bay adding

    ts.addParser({
    id: "currencyNuberFormat",
    is: function(s){
    return (/^[\u00a3$\u20ac\u00a4\u00a5\u00a2?.\s]/).test(s); // £$€¤¥¢?.
    },
    format: function(s){
    return $.tablesorter.formatFloat(s.replace(/\,/g,'.').replace(new RegExp(/[^0-9]/g), ""));
    },
    type: "numeric"
    });

    I'm not an expert in regex but it seems to work..

    ReplyDelete
  34. Thanks locationRoura! I added your demo to this wiki page to share it with others.

    ReplyDelete
  35. Do you have a solution to use the pager with the persistent header ? I have problem with the width of the columns...

    ReplyDelete
    Replies
    1. Yes its works well, until you have a widther entry. Try this :
      Go there http://jsfiddle.net/aEL9t/4/
      scroll down to active your persistent header
      click on next button on the pager

      Delete
    2. Hmm, yeah, but that doesn't happen if you set the "widthFixed" to "true". Either way, it's an easy fix - I'll update soon.

      Delete
    3. Cool, I haden't seen this, sorry..

      Delete
    4. Done.. test out version 2.0.25.2

      Delete
    5. It's perfect, thanks ;)

      Delete
  36. Hi Mottie

    Is there a way to set the title attribute for the table headers so that they change with the css for the images?

    ReplyDelete
  37. I just answered that same question over on StackOverflow - was that you?

    ReplyDelete
  38. Hi Mottie - I just upgraded from version 2.05 to 2.0.28
    I'm having trouble with tables i'm updating dynamically. basically the table is originally displayed with a single row "select a product to populate table".
    i have a javascript function that first calls:
    $('#productDetailTable').find('tbody').empty();
    then populates the table with new row data.
    then i update and resort the table.
    $('#productDetailTable').trigger("update");
    var sorting = [[5,0], [6,1], [2,0]];
    $('#productDetailTable').trigger("sorton", [sorting]);
    the row i removed "select a product to populate table" is still displayed in the table.
    is it reloaded from cached data?
    i see the same issue when selecting a new product. i need to remove the previously displayed row data, and display data for the new product. instead i see data for both products displayed in the table.

    this was working 2.0.5, but i was interested in using some of your new features, and upgraded .... now i'm pulling my hair out.

    thanks for any thoughts.
    Tia

    ReplyDelete
  39. Hi Tia!

    Try something like this:

    $('#productDetailTable')[0].config.sortList = [[5,0], [6,1], [2,0]];
    $('#productDetailTable').trigger("update");

    ReplyDelete
  40. Is there a way to have a row be ignored from the sort? I've got a "total" column at the bottom of my table, and would not like it sorted for obvious reasons.

    ReplyDelete
    Replies
    1. There isn't a way to ignore a row, but if it's a total row, then maybe you could stick it into the <tfoot>, that way it'll always stay at the bottom.

      Delete
  41. Mottie, in your fork it's great that you trigger "sorton" within "update". This fixes the worst single bug in 2.0.5.

    However I see that "update" is still implemented inside a setTimeout and there are two more timeouts in the code. Given that javascript is single threaded, there must be a concern that method chaining and even separate commands executed following a .trigger("update") will be not take account of the update or the re-applied sort.

    I wonder if you have given any thought to achieving tablesorter functionality with strictly synchronous code; ie purging the timeouts.

    ReplyDelete
    Replies
    1. You know, I think I just left those in there from the original plugin. I might have added one for the sortEnd trigger because it wasn't firing at the correct time, but if you look they are all set for 0 or 1 millisecond. So I don't really think it's that much of a concern, but I'll look into removing them and see how the script behaves and completely remove them if they aren't necessary. Thanks!

      Delete
    2. Hi me again. The concern over timeouts is that, they fire at the first available opportunity when all statements queued within javascript's single thread have completed. Hence, even with a timeout delay of 0 ms, all statements in the same "event-thread", following the timeout's inception, are guaranteed to have completed before the timed-out function executes. This is an oft-unappreciated aspect of js. With timeouts in the code for some tableSorter actions, statements that rely on tableSorter having completed those actions would need to be implemented in a callback executed from within the timed out function (or, unsatisfactorily, implemented in another timeout with longer delay). So I contend that, either (a) timeouts should be avoided or (b) provision should be made for callbacks.

      Delete
    3. I have tried to illustrate the problem here - http://jsfiddle.net/vQzNL/

      Delete
    4. Alright, I tested the script after completely removing the setTimeouts and it seems to still function properly and as expected. Thanks for the information and the input - I'm still learning something new everyday :)

      Delete
    5. Well, I think I'm going to have to add one setTimeout back into the code. The issue is that I want to add an animated gif over the header while the table is being sorted or filtered, and without a setTimeout, the class name gets added, but the icon doesn't get a chance animate. So what I'm going to do is add the timeout, but provide a callback function after the appendToTable function is called - this will be included in version 2.4.

      Delete
  42. Sounds promising Mottie. I hope it holds together in all browsers. It would be nice to know why Christian found it necessary to use timeouts in the first place.

    ReplyDelete
  43. How can I configure text sort on a column to sort null values to the top of the list? The default behavior is to sort asc and desc all text with values to the top, but regardless of sort order all nulls sort to the bottom of the list.
    Thanks!

    ReplyDelete
  44. Maybe it would be more clear to say that I want to sort empty cells to the top of the table when sorting asc. I've attempted to write a custom parser. I was hoping to use the format method to modify empty cell contents to something that could be sorted properly, but it appears that the format method is not called for empty cells.

    $.tablesorter.addParser({
    id : "nullSort",
    is : function(s) {
    return false;
    },
    format : function(s, table, cell, cellIndex) {
    alert(s);
    alert(cell);

    if (s== null) {
    s=" ";
    }
    return s;
    },
    type : "text"
    });

    ReplyDelete
    Replies
    1. It would require modifying the plugin core. Please follow this enhancement request so you know when the option has been added (soon)

      Delete
    2. thanks for the new feature! this works great.

      Delete
  45. While I'm requesting features, I would love to have the ability to sort dates in this format: MM/dd/yyyy hh:mm a
    It looks like only the usLongDate handles sorting time with the date.

    ReplyDelete
    Replies
    1. Ok, I've updated the plugin to version 2.1.14 with a fix that allows you to use the "shortDate" parser for dates and dates with time. Here is the updated demo

      Delete
  46. Hi,

    May be you could help me ;)

    When I delete a row, the table doesn't refresh.
    I'm explaining 10 rows (page1), 5 rows (page2). When I remove a row in page 1, I have 9 rows (page1) and 5 rows (page2). Normally, it would be: 10 rows (page1) and 4 rows (page2)

    I tried this code but nothing good :(

    $(".deleteBtn").click(function(){

    var id = $(this).attr("id");
    var dataString = 'id='+ id;

    $.ajax({
    type: "POST",
    url: "deleteData.php",
    data: dataString,
    //cache: false,
    //async: false,
    success: function(retour){
    if(retour == 0){
    $("#manageImage").hide();
    $("#noList").show();
    }else{
    $(".bar"+id).animate({ opacity: "hide" }, "slow");
    $('table').find('tbody').empty();
    $('table')[0].config.sortList = [[0,0], [1,1]];
    $('table').trigger("update");
    $('table').trigger("sorton", [sorting]);

    Do you have an idea, please?!

    ReplyDelete
    Replies
    1. Sorry for not replying earlier. I'm guessing you are using the pager plugin? This won't work with the original one, but if you set the pager plugin option "removeRows" to false (ref), it should start working properly.

      Delete
  47. hai i am work in jquery tablesorter code but 1,5, 10 one is not sorting and also other data is just jump up and down my data is dynamic data first page load time table is created after that when click on button data is fetch into table when click on sort above problem is coming please give me solution please

    ReplyDelete
    Replies
    1. Hi M.Pradeep!

      I'm not quite sure what problem you are describing. Could you please modify this demo or share a link to the page you are having problems with.

      Delete
  48. Thank you very much for this documentation, it was extremely helpful for me.

    ReplyDelete
  49. Thank you extremely for your work on this.

    I have been using Tablesorter 2.0.5 successfully with the help of the Pager Plugin and I was asked to build in a way to Enable or Disable the Pager Plugin.

    I discovered your work and your updated plugins and now have the system working successfully on my site.

    Try though I might, however, I cant get the Enable / Disable Button to work unless I have the Word "Enable" in the text inside the button.

    Is there a way to have other text in the button and still have the Enable / Disable functionality work?

    as an example - (button)Disable Pager(/button)
    to become something like - (button)Salami Pancakes(/button)

    Thanks in advance for your generosity and time.
    Cheers Al

    ReplyDelete
    Replies
    1. Worked it out!

      // Disable / Enable
      // **************
      $('button:contains(Disable)').click(function(){
      var mode = /Disable/.test( $(this).text() );
      $('table').trigger( (mode ? 'disable' : 'enable') + '.pager');
      $(this).text( (mode ? 'Enable' : 'Disable') + 'Pager');
      });

      becomes

      // Disable / Enable
      // **************
      $('button:contains(Print-Page)').click(function(){
      var mode = /Print-Page/.test( $(this).text() );
      $('table').trigger( (mode ? 'disable' : 'enable') + '.pager');
      $(this).text( (mode ? 'Table' : 'Print-Page') + ' View');
      });

      with button
      (button)Print-Page View(/button)

      For anyone looking for this.

      Delete
    2. Throwing one more out there.

      Any idea how I could use an image in the Pager Disable/Enable button?

      (or even two images, one for Disable, one for Enable).

      Possibly pushing it but if any one has any ideas, I would be very grateful.

      Cheers Al.

      Delete
    3. Hi Al

      You could just use an image or use an input type image. Here is the basic code:

      <img class="enable" src="image1.jpg">
      <img class="disable" src="image2.jpg">

      $('.enable').click(function(){
      $('table').trigger('enable.pager');
      });
      $('.disable').click(function(){
      $('table').trigger('disable.pager');
      });

      But since it looks like you want to show all the rows it might be easier to just use something like this:

      @media print {
      tr { display: table-row !important; }
      }

      instead of worrying about javascript.

      Delete
  50. Almost there!

    I have almost successfully completed my upgrade from 2.0.5 to 2.5

    I am however stumped by one last thing.

    In 2.0.5 in the file jquery.tablesorter.pager.js you can set the default initial number of rows to display here:
    this.defaults = {
    size: 20,
    (line 125)

    however in 2.5 jquery.tablesorter.pager.js setting
    this.defaults = {
    size: 20,
    (line 40)

    has no effect and only 10 rows are initially displayed.

    Does anyone have any idea what could be causing this?
    I have set the value of the select in the Pager to 20 as the first value as well just in case.

    ReplyDelete
    Replies
    1. Worked it out.

      There are options on the html page that holds the table.
      ...
      var pagerOptions = {
      ...
      size: 20,

      Cheers Al,

      Delete
  51. Hi would it be possible to have four tables sort simultaneously on the page - I am using wordpress and formidable forms and so far looks great except each table head and foot is showing (no biggy) and it will only sort per each table. I have each table with class="tablesort" for the styling and id="myTable".
    So far I have been using this and looks good so far for date range etc.
    $(function() {

    $("table.tablesorter").tablesorter({
    theme: 'blue',
    sortMultiSortKey: 'shiftKey',

    cssInfoBlock : "tablesorter-no-sort",
    // hidden filter input/selects will resize the columns, so try to minimize the change
    widthFixed : true,

    // initialize zebra striping and filter widgets
    widgets: ["zebra", 'stickyHeaders','columns', "filter"],

    widgetOptions : {
    filter_cssFilter: 'tablesorter-filter',
    // jQuery selector string of an element used to reset the filters
    filter_reset : 'button.reset',
    // add custom selector elements to the filter row
    filter_formatter : {
    3 : function($cell, indx){
    return $.tablesorter.filterFormatter.uiDatepicker( $cell, indx, {
    from : '12/1/2012',
    to : '2/1/2020',
    changeMonth: true,
    changeYear : true
    });
    },
    }
    }
    });


    });

    I would really like to know how to change this to work on all tables, would I need to give them a different id?
    Many Thanks
    Theresa

    ReplyDelete
    Replies
    1. Hi Theresa!

      Can you email me, since it's hard to format code and carry on a conversation here, about when you want the four tables to sort? More specifically, do you want one table sort to change all the other tables? Or, modifying the filter on one table to change all others? I use gmail and my user name is wowmotty.

      Thanks!
      Rob

      Delete
  52. Thanks for sharing such a great blog... I am impressed with you taking time to post a nice info.
    Mobile App Development Company

    ReplyDelete
  53. Thanks for sharing valuable Information, I really very impressive on your blog. I hope you continue on blogging job.
    Mobile App Development Company in Mumbai

    ReplyDelete