Contents

Introduction

tablesorter is a jQuery plugin for turning a
standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes.
tablesorter can successfully parse and sort many types of data including linked data in a cell.
It has many useful features including:

Start by telling tablesorter to sort your table when the document is loaded:

$(function(){
$("#myTable").tablesorter();
});

Click on the headers and you'll see that your table is now sortable! You can
also pass in configuration options when you initialize the table. This tells
tablesorter to sort on the first and second column in ascending order.

Work-in-progress

Configuration

tablesorter has many options you can pass in at initialization to achieve different effectsTIP! Click on the link in the property column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

Property

Type

Default

Description

Link

Property

Type

Default

Description

Link

cancelSelection

Boolean

true

Indicates if tablesorter should disable selection of text in the table header (TH). Makes header behave more like a button.

Add this css class to a child row that should always be attached to its parent. Click on the "cssChildRow" link to toggle the view on the attached child row. Previous default was "expand-child" (Modified v2.4).

The CSS style used to style the header cell icon (modified v2.7; v2.21.1).

In v2.21.1, adding multiple class names to this option is now properly supported.

As of v2.7, the icon will only be added to the header if both the cssIcon option is set AND the headerTemplate option includes the icon tag ({icon}).

In v2.4, an <i> element, with this class name, is automatically appended to the header cells. To prevent the plugin from adding an <i> element to the headers, set the cssIcon option to an empty string.

As an example, I've split up this options table into three (3) tbodies. The first contains the active options, the second is the info block with a row that only contains the text "Deprecated Options", and the last tbody contains the deprecated options. Sort the table to see how each tbody sorts separately.

NOTE! The pager plugin will only be applied to the first tbody, as always. I may work on modifying this behavior in the future, if I can figure out the best implementation.

cssNoSort

String

"tablesorter-noSort"

Class name added to element inside header. Clicking on that element, or any elements within it won't cause a sort. (v2.20.0).

Setting this option to true will delay parsing of all table cell data until the user initializes a sort. This speeds up the initialization process of very large tables, but the data still needs to be parsed, so the delay is still present upon initial sort.

For example, to disable sorting on the first two columns of a table: headers: { 0: { sorter: false}, 1: {sorter: false} }.

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 alphanumeric. You can easily override this by setting the header argument (or column parser).
See the full list of default parsers here or write your own.

Please note that the headers index values corresponds to the table header cells index (zero-based) and not the actual columns. For example, given the following table thead markup, the header-index counts the header th cells and does not actually match the data-column index when extra rows and/or colspan or rowspan are included in any of the header cells:

Warning What won't work is if you try to target the header using a filtering selector that uses an index, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.

This is a template string which allows adding additional content to the header while it is being built (v2.7; v2.17.8).

In v2.17.8, if this option is set to an empty string (''), an inner div will no longer be wrapped around the header content.

This template string has two modifying tags: {content} and {icon}.{content} will be replaced by the current header HTML content.{icon} will be replaced by <i class="tablesorter-icon"></i>, but only if a class name is defined in the cssIcon option.

This template string may also contain HTML, e.g ('<em>{content}</em> {icon}')

After the template string is built, the onRenderTemplate function is called to allow further manipulation. Please read more about this onRenderTemplate function and/or check out the example (link to the right).

Used by the image parser to grab the image attribute content (v2.17.5; moved to tablesorter core in v2.18.0; see config.parsers).

Change this setting to grab a different image attribute to be used for sorting:

$(function(){
$('table').tablesorter({
// parse image title (value to be used while sorting & filtering)
imgAttr : 'title',
headers : {
0 : { sorter: 'image' } // this parser is auto-detected, but will only work on the first image
}
});
});

When true, all widgets set by the widgets option will apply after tablesorter has initialized, this is the normal behavior.

If false, the each widget set by the widgets option will be initialized, meaning the "init" function is run, but the format function will not be run. This is useful when running the pager plugin after the table is set up. The pager plugin will initialize, then apply all set widgets.

Why you ask? Well, lets say you have a table with 1000 rows that will have the pager plugin applied to it. Before this option, the table would finish its setup, all widgets would be applied to the 1000 rows, pager plugin initializes and reapplies the widgets on the say 20 rows showing; making the widget application to 100 rows unnecessary and a waste of time. So, when this option is false, widgets will only be applied to the table after the pager is set up.

This function is called after content is to the TH tags (after the template is procressed and added). You can use this to modify the HTML in each header tag for additional styling (v2.18.0).

In versions 2.0.6+, all TH text is wrapped in a div with a class name of "tablesorter-inner" by default. In the example below, the header cell (TH) div is given a class name (source).
Function parameters:

index - zero-based index of the current table header cell; this value is not indicative of the column index, as it is simply a count of header cells. So it will be effected by rowspan, colspan and multiple rows in the header.

config - The current table.config.

$table - This value is the current table jQuery object. If this function is being applied to cloned headers, as is does in the stickyHeaders widget, then this value will contain the sticky header clone added after the current table, and not the main table (v2.18.0).

This function is called after the template string has been built, but before the template string is applied to the header and before the onRenderHeader function is called (v2.7).

The onRenderTemplate function receives a column index and template string parameters. The template string, from the headerTemplate option, will already have the {icon} and {content} tags replaced; it's just a string of formatted HTML. When done manipulating this string, return it. Here is an example:

The template parameter can be manipulated as a string, or if you prefer, turn it into a jQuery object (var $t = $(template)) to find and replace content as desired. Just make sure you return a string (return $t.html())

From the example function above, you'll end up with something similar to this HTML (only the thead is shown)

You can change this, but the table will still need the required thead and tbody before this plugin will work properly.
Added > to the selector in v2.3 to prevent targetting nested table headers. It was modified again in v2.4 to include td cells within the thead.

This CSS class name can be applied to all rows that are to be removed prior to triggering a table update. (v2.1).

It was necessary to add this option because some widgets add table rows for styling (see the writing custom widgets demo) and if a table update is triggered ($('table').trigger('update');) those added rows will automatically become incorporated into the table.

selectorSort

String

"th, td"

jQuery selector of content within selectorHeaders that is clickable to trigger a sort (v2.4).

When this option is true any applied sort on the table will be reapplied after an update method (v2.19.0).

Specifically, this option applies to the "updateAll", "update", "addRows" and "updateCell" methods and is checked after the method has completed updating the internal cache.

If false, the widgets will still be refreshed for all but the "updateCell" method - this "updateCell" behavior was added in v2.19.0.

Note when triggering one of the above methods, and passing a defined resort parameter, it will override this setting.

Note if a sort is not reapplied, problems with some widgets may occur namely the grouping widget.

serverSideSorting

Boolean

false

Set to true if the server is performing the sorting. The ui and events will still be used (v2.5.3).

showProcessing

Boolean

false

Show an indeterminate timer icon in the header when the table is sorted or filtered. Please note that due to javascript processing, the icon may not show as being animated. I'm looking into this further and would appreciate any feedback or suggestions with the coding (v2.4).

For example, sortForce: [[0,0]] will sort the first column in ascending order. After the forced sort, the user selected column(s), or during initialzation, the sorting order defined in the sortList will follow. And lastly, the sort defined in the sortAppend option will be applied. More explicitly:

There are three options to determine the sort order and this is the order of priority:

sortForce forces the user to have this/these column(s) sorted first (null by default).

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]].

The value contains 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]]. Please see sortForce for more details on other sort order options.

Use to add an additional forced sort that will be appended to the dynamic selections by the user.

For example, can be used to sort people alphabetically after some other user-selected sort that results in rows with the same value like dates or money due. It can help prevent data from appearing as though it has a random secondary sort.

The value contains 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]]. Please see sortForce for more details on other sort order options.

Boolean flag indicating whenever to use javascript String.localeCompare method or not.
This is only used when comparing text with international character strings. A sort using localeCompare will sort accented characters the same as their unaccented counterparts.

Setting this option to true and sorting two rows with exactly the same content, the original sort order is maintained (v2.14).

This isn't exactly a stable sort because the sort order maintains the original unsorted order when sorting the column in an ascending direction. When sorting the column in a descending order, the opposite of the original unsorted order is returned. If that doesn't make any sense, please refer to issue #419.

sortMultiSortKey

String

"shiftKey"

The key used to select more than one column for multi-column sorting. Defaults to the Shift key. The other options are "ctrlKey" or "altKey" (reference).

Defines which method is used to extract data from a table cell for sorting (v2.19.0)

* Note This option accepts multiple types (String, Object or Function); see below for further details.

In v2.19.0, the code was further optimized. When set to "basic" (the default), the textExtraction code will check for data-attributes, otherwise, any other string value setting will skip the data-attribute value check; because of this change, there is a noticable lessening of initialization time in Internet Explorer.

In v2.17.0, the textExtraction column can also be referenced by using a jQuery selector (e.g. class name, id or column index) that points to a table header cell.

Warning What won't work is if you try to target the header using a filtering selector that uses an index, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.

As of version 2.16.0,

The default text extraction method has been renamed and updated to get data from a data-attribute (set by the textAttribute option).

If you need to support older versions of IE, this may add a significant delay to the table initialization especially for large tables; in this case, set the textExtraction option to any name other than "basic".

Also, this option can now be set using a data-attribute named "data-text-extraction" on the table.

You can customize the text extraction by writing your own text extraction function "myTextExtraction" which you define like:

tablesorter will pass the current table cell object for you to parse and return. Thanks to Josh Nathanson for the examples; updated to a jQuery example by Rob G (Mottie).

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.

Added table and cellIndex variables to the textExtraction function in version 2.1.2 (this is not part of the original plugin).

The direction parameter (boolean) is merely for informational purposes as the plugin automatically switches a and b depending on the sort direction ( i.e. there's no need to worry about reverse sorting, it's taken care of by the plugin ).

The direction parameter (boolean) is merely for informational purposes as the plugin automatically switches a and b depending on the sort direction ( i.e. there's no need to worry about reverse sorting, it's taken care of by the plugin ).

Prior to v2.4, this option set pixel widths to added colgroups to fix the column widths. This is useful for the Pager companion.
Requires the jQuery dimension plugin to work. This is now part of the jQuery core.

In version 2.1, all widget options have been moved into this option. This is a move to store all widget specific options in one place so as not to polute the main table options. All current widgets have been modified to use this new option. (v2.1).

This option is being deprecated in v2.21.3!
It has been replaced by widgetOptions.storage_fixedUrl; but is still available for backwards compatibility.

This option was added to set a specific page when storing data using the $.tablesorter.storage code (v2.12).
More specifically, when the storage function is used, it attempts to give every table a unique identifier using both the page url and table ID (or index on the page if no id exists). This option allows you to override the current page url (it doesn't need to be a url, just some constant value) and save data for multiple tables across a domain.

When the column styling widget is initialized, it automatically applied the default class names of "primary" for the primary sort, "secondary" for the next sort, "tertiary" for the next sort, and so on (add more as needed)... (v2.0.17).
Use the widgetColumns option to change the css class name as follows:

Used when the ui theme styling widget is initialized. It automatically applies the default class names of "ui-icon-arrowthick-2-n-s" for the unsorted column, "ui-icon-arrowthick-1-s" for the descending sort and "ui-icon-arrowthick-1-n" for the ascending sort. (v2.0.9).
Find more jQuery UI class names by hovering over the Framework icons on this page: http://jqueryui.com/themeroller/

tablesorter widgets have many options, and to better organize them, they now are grouped together inside of the widgetOptions. Thanks to thezoggy for putting together this jQuery-widget compatibility table, but please note:

The applied order of widget is dependent of the widget priority, from low to high.

Widget priority values do not need to be unique. Any new widget without a defined priority will automatically have a priority of 10.

The pager, being a plugin, is actually initialized after tablesorter has initialized and all selected widgets applied.

* The saveSort and resizable widgets use the $.tablesorter.storage function by default and thus need the parseJSON function which is available in jQuery 1.4.1+.

** The stickyHeaders widget was updated in v2.18.0 to use $.isWindow for the xScroll & yScroll options; and therefore now requires jQuery 1.4.3+.

TIP! Click on the link in the property column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

Columns widget: When the column styling widget is initialized, it automatically applied the default class names of "primary" for the primary sort, "secondary" for the next sort, "tertiary" for the next sort, and so on (add more as needed)... (Modified v2.1).

Filter widget: If there are child rows in the table (rows with class name from "cssChildRow" option) and this option is true and a match is found anywhere in the child row, then it will make that row visible.
(Modified v2.1).

Warning What won't work is if you try to target the header using a filtering selector that uses an index, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.

A new file has been included named "widget-filter-formatter-jui.js" & "widget-filter-formatter-html5.js". The files include code to add jQuery UI and HTML5 controls via the filter_formatter option.

Most of the formatter functions have an option named valueToHeader which, when true adds a span to the header cell above the filter row and updates it with the current control's value (see example 2). If the option exists and is set to false, then the current value is added to the control's handle and css can be used to create a popup to show the current value (see example 1).

Another custom option named addToggle is included with the "uiSpinner", "html5Color" and "html5Number" code. This allows the user to disable the control to show all table rows. For the single sliders, "uiSlider" and "html5Range", the minimum value is used to clear the filter (show all rows).

The options included for each jQuery UI control only show basic options, but any or all of the jQuery UI options for that control can be included.

For other examples, please refer to the example pages. Formatter part 1 (example 1) adds jQuery UI controls to the filter row, while formatter part 2 (example 2) adds HTML5 controls, if supported, to the filter row.

Warning What won't work is if you try to target the header using a filtering selector that uses an index, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.

Filter widget: Set this option to true to hide the filter row initially. The row is revealed by hovering over the visible portion of the filter row or by giving any filter input/select focus (tab key) (v2.4).

You can change the style (thickness) of the hidden filter row in the tablesorter theme css. Look for .tablesorter-filter-row (revealed row) and .tablesorter-filter-row.hideme (for the hidden row) css definitions.

Filter widget: If a header contains a select dropdown and this class name, only the available (visible) options in the column will show (v2.10.1; v2.17.6).

In v2.17.6, columns with the only available class name set, that are not currently being filtered will only show the available options. Conversely, the column(s) with a selected option will show all options.

This option is useful after one or more columns have been filtered, then the column select filter with this class applied will only show the contents of the column within the dropdown that are currently visible. See the custom filter widget demo "Discount" column for an example (sort the "First Name" column first).

Caution: The main issue with this functionality is with keyboard accessibility. If the keyboard is used to select an option, only the first and default options will be available for chosing. The only way to select other options is with the mouse.

Filter widget: jQuery selector string of an element used to reset the filters (v2.4; v2.16).

When this option points to a reset element using a jQuery selector string, it is bound using event delegation. So if any additional reset elements, with the same class name, are added to the page dynamically, they will be associated with the same table.

For example, add this button (<button class="reset">Reset</button>) to the table header, or anywhere else on the page. That element will be used as a reset for all column and quick search filters (clears all fields):

If this option contains a jQuery object (v2.16), clicking on any of the elements within that jQuery object will trigger a filter reset. If any additional elements with the same selector are added to the page, they will not be dynamically functional.

If either of these methods do not work as desired, simply trigger a filterReset event on the table.

Filter widget: If the storage utility is available (included with jquery.tablesorter.widgets.js file, the last applied filter is saved to storage (v2.14).

Filters saved to local storage (or cookies) will override any default filters within the header data-attribute (set by the filter_defaultAttrib option) and be available to the pager before any ajax calls are made.

If you want to want to initialize the filter without user input, target any one of the filters and trigger a "search".

// target the first filter input
// this method will begin the search after the searchDelay time
$('input.tablesorter-filter:eq(0)').trigger('search');
// this method will begin the search immediately
$('input.tablesorter-filter:eq(0)').trigger('search', false);

In tablesorter v2.4+, the trigger can be applied directly to the table:

Filter widget: Set this option to allow searching through already filtered rows (in special conditions); this will speed up searching in large tables (v2.17.4).

To better explain this, lets do it by example. Lets say you have a column of color names and you enter "light" and results like "light blue" and "light grey" show up.

When you press the space bar, a space is added, and instead of searching though all of the colors again, the filter widget only searches through the already filtered results that started with "light". This can substantially speed up searching, especially in large tables.

But, there are some special circumstances which would make this method return incorrect results. So, this option was added to allow you to disable this feature in case one of these following conditions doesn't cover your need; but still, please report any issues!

The search through filtered results only occurs if the following conditions are met:

The last search (for all columns) was not completely empty - all rows will be searched anyway.

If there were no changes to the search from the beginning of the search string (changing the above search to "bright" will force a new search of all rows).

If the search does not contain a logical or ( or or |), or a range delimiter ( - or to ) within the search query.

If the search is not looking for an exact match (" or =) or a logical not search (!).

Or, if the search is using a select dropdown without a "filter-match" class name (looking for an exact match).

If the search does not contain an operator greater than or equal to a negative number (>=-10) or less than or equal to a positive number (<=10).

And lastly, only search filtered rows if all rows are not hidden.

If the debug option is set to true, then a message will appear while filtering stating the specific number of rows, or "all" rows, that are being searched.

Warning What won't work is if you try to target the header using a filtering selector that uses an index, e.g. "th:eq()", ":gt()", ":lt()", ":first", ":last", ":even" or ":odd", ":first-child", ":last-child", ":nth-child()", ":nth-last-child()", etc.

A column will have a filter select dropdown when a "filter-select" class name is added to the header cell, or if the filter_functions column value is set to true

This option allows using an alternate source, or customizing options of the filter select dropdown. This option can be set as follows:

null - this value will set the default behavior and return all table cell values from the current column.

An overall function - when this option is a function, it will be used for all filter selects in the table.

onlyAvail - boolean indicating if the returned options should only be from available (non-filtered) rows.

Important Return an array of values which will be added to the filter select dropdown. This array will automatically be stripped of any duplicate values and sorted alphanumerically before being added to the select. If for some reason the custom filter_selectSource function does not obtain the desired array of values, return false and the original method of obtaining column cell content will be used.

Sticky Headers widget: Set the sticky header offset from the top as a Number or jQuery selector string or object (v2.10).

If the page includes a fixed navigation bar at the top, like Bootstrap, set "stickyHeaders_offset" option to offset the sticky table header to be below the fixed navigation by setting this option using any of the following examples:

When a user searches the table using the sticky header filter row the results may reduce the number of rows so that the table would scroll up out of the viewport. So, this option scrolls the table top into view and moves the filter focus to the same input in the original header, instead of the sticky header input.

Set this option to false to prevent the page scroll after filtering the table.

Sticky Headers widget: If true, sticky table headers will resize automatically when content is added to or removed from the table headers (v2.10).

While this option is true, a timer is initialized to check the width of every header cell every 1/4 second. If this causes lag, or any other problems, set this option to false.
When this option is false, sticky table headers are unable to detect and match the width of the original table headers when content is added or removed.

Resizable widget: If this option is set to true, a resizing anchor will be included in the last column of the table (v2.8.3).

If an anchor was included and the table is full width, the column would resize in the opposite direction which my not be intuitive to the user. So set this option as desired, but please be mindful of the user experience.

Resizable widget: When true, the last column will be targetted for resizing (v2.21.3).

When true, resizing a column will change the size of the selected column, and the last column, not the selected column's neighbor.

When false, resizing a column will move the column border between it's neighbors.

Also, in a full width table, if this option is false, the same behavior as when this option is true can be seen when resizing a column while holding down the Shift key on the keyboard - the last column is resized.

Target your one or more pager markup blocks by setting this option with a jQuery selector.

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_selectors.container; additionally you can change the class name that is applied to the pager (used within the jquery.tablesorter.pager.css file) by modifying the widgetOption.pager_css.container class name (default is "tablesorter-pager")

This is some example pager markup. It should contain all of the controls set by the multiple css-named options:

Caution If you use buttons in your pager container, make sure the buttons include a button type (<button type="button">Next</button>) to prevent form submission and page reloading every time the button is clicked.

The ajaxUrl template replaces the following tags with values from the tablesorter plugin and pager addon:

Tag

Replaced with

{page}

Zero-based index of the current pager page

{page+1}

One-based index of the current pager page (replace "+1" with any number) (e.g. {page+3}) (v2.9).

{size}

Number of rows showing, or number of rows to get from the server

{sortList:col} or {sort:col}

Adds the current sort to the ajax url string into a "col" array, so your server-side code knows how to sort the data (v2.4.5).
The col portion of the {sortList:col} tag can be any name string (no spaces) to indicate the name of the variable to apply. So if your current sortList is [[2,0],[3,0]], it becomes "&sort[2]=0&sort[3]=0" in the url. {sort:col} shortened tag also works (v2.9).

{filterList:fcol} or {filter:fcol}

Adds the value of the current filters to the ajax url string into a "fcol" array, so your server-side code knows how to filter the data (v2.6).
The fcol portion of the {filterList:fcol} tag can be any name string (no spaces) to indicate the name of the variable to apply. So if your current filters are ['','Blue',13], it becomes "&fcol[2]=Blue&fcol[3]=13" in the url. {filter:col} shortened tag also works (v2.9).

This option contains the ajax settings for the pager interaction with your database (v2.10).

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_ajaxObject

The ajaxObject is completely customizable, except for the url setting which is processed using the pager's ajaxUrl and customAjaxUrl options. This means you can also add a success callback function which is called after the ajax has rendered.

Your server does not need to return a JSON format, if you want to return pure HTML, set the dataType to "html" and modify the ajaxProcessing function to instead work with HTML; then return a jQuery object or apply the HTML to the table yourself.

This function is required to return the ajax data obtained from your server into a useable format for tablesorter to apply to the table (v2.1, v2.17.3).

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_ajaxProcessing

This function was created and modified to allow you a great deal of flexibility. The only required information that this function needs to return is an array containing the total number of rows, which is needed to calculate total pages.

There are numerous examples below. Choosing which one to use is left to you. For more information, please check out related questions on Stackoverflow, in particular see this thread about how to use the different ajax options together.

In v2.10, the returned rows is now optional. And it can either be an array of arrays or a jQuery object (not attached to the table)

After tablesorter v2.17.3, this function can include a filteredRows property which will update the internal value and thus show a proper filtered row count, and update the "goto" page drop down selector appropriately.

After tablesorter v2.11, the ajaxProcessing function can return an object containing these properties, along with any extra properties. These extra properties will be available for use within the pager output string (see more details in issue #326);

This ajaxProcessing function must return an object with "total", "headers" and "rows" properties! As before, "total" is the only required property; if the headers don't need to be changed, don't return a headers array, and if you append the rows to the table yourself within the ajaxProcessing function, you don't need to return a "rows" property.

This option allows you to format the output display which can show the current page, total pages, filtered pages, current start and end rows, total rows and filtered rows (v2.0.9; v2.17.6).

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_output

This option replaced the original separator option, which only separated the page number from the total number of pages. The formatted output from this option is placed inside the information block targeted by the cssPageDisplay option.

Maintain the height of the table even when fewer than the set number of records is shown (v2.1; updated 2.7.1).

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_fixedHeight

This option replaced the original positionFixed and offset options which set the absolute position of the pager block.

If true, it should maintain the height of the table, even when viewing fewer than the set number of records (go to the last page of any demo to see this in action). It works by adding an empty row to make up the differences in height.

If true, rows are removed from the table to speed up the sort of large tables (v2.0.21).

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_removeRows

The original tablesorter plugin (v2.0.5) removed rows automatically, without providing an option. It really does speed up sorting of very large tables, but also breaks updating and modifying table content dynamically.

If this option is false, the addon only hides the non-visible rows; this is useful if you plan to add/remove rows with the pager enabled.

This option contains the class name that is applied to disabled pager controls.

Note The pager widget equivalent option is within the widgetOptions and accessed via widgetOptions.pager_css.disabled

More explicitly, this class is applied to the pager arrows when they are at either extreme of pages and the updateArrows option is true. When the pager has been disabled, this class is applied to all controls.

Note there is no period "." in front of this class name (it is not a selector).

This widget option replaces the previous widgetUitheme. All theme css names are now contained within the $.tablesorter.themes variable. Extend the default theme as seen above.

The class names from the $.tablesorter.themes.{name} variable are applied to the table as indicated.

As before the jQuery UI theme applies the default class names of "ui-icon-arrowthick-2-n-s" for the unsorted column, "ui-icon-arrowthick-1-s" for the descending sort and "ui-icon-arrowthick-1-n" for the ascending sort. (Modified v2.1; Updated in v2.4). Find more jQuery UI class names by hovering over the Framework icons on this page: http://jqueryui.com/themeroller/

The original tablesorter pager plugin absolutely positioned the pager controls at the bottom of the table. It appears that this option was intended to tweak the position of the pager container. The option exists, but no code was found.

Pager: This option was removed! Use the output option to allow for more control over the formatting.

The original tablesorter pager plugin would combine the current page with the calculated total number of pages within the cssPageDisplay with this separator string inbetween.

Methods

tablesorter has some methods available to allow updating, resorting or applying widgets to a table after it has been initialized.
TIP! Click on the link in the method column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

Using this method will clear out any settings that have changed since the table was initialized (refreshes the entire table); so any sorting or modified widget options will be cleared.
However, it will not clear any values that were saved to storage. This method is basically like reloading the page.

Using this method will maintain the sorting order; so, if the column is already sorted in ascending order, this method will act as if you manually clicked on the header. Whatever sort order is applied is dependent on other option settings such as initialSortOrder, lockedOrder (set within the headers), sortReset option, sortRestart and will be ignored if the column sort is disabled (sorter: false).

Use this method to sort an initialized table in the desired order (v2.17.0)

// Choose a new sort order
var sort = [[0,0],[2,0]],
callback = function(table){
alert('new sort applied to ' + table.id);
};
// Note that the sort value below is inside of another array (inside another set of square brackets)
// without a callback it could look like this:
$("table").trigger("sorton", [ [[0,0],[2,0]] ]);
// when including a callback method the outer square bracket wrap both parameters (added in 2.3.9).
$("table").trigger("sorton", [sort, callback]);

*NOTE* using this method to sort ignores the additions from the sortForce and sortAppend options.

In v2.17.0, the sort direction can be set using "a" (ascending), "d" (descending), "n" (next), "s" (same) & "o" (opposite).

$('table').trigger('sorton', [ [[0,"a"],[2,"n"]] ]);

Please try out the demo (example link) to better understand how these values work.

// Add new content
$("table tbody").append(html);
// let the plugin know that we made a update
// the resort flag set to true will trigger an automatic resort using the current sort
// if set to false, no new sort will be applied; or set it to any sortList value (e.g. [[0,0]]; new v2.19.0)
// A callback method was added in 2.3.9.
var resort = true,
callback = function(table){
alert('new sort applied');
};
$("table").trigger("update", [resort, callback]);
// As of version 2.19.0, if the resort parameter is undefined, the setting from the config.resort will be used
// As of version 2.0.14, the table will automatically resort after the update (if the "resort" flag is true
// & will use the current sort selection), so include the following if you want to specify a different sort
// set sorting column and direction, this will sort on the first and third column
var sorting = [[2,1],[0,0]];
// method to use prior to v2.19.0
// $("table")
// .trigger("update", [ false ])
// .trigger("sorton", [sorting]);
// After v2.19.0; do the following to apply a new sort after updating
// if sorting is an empty array [], then the sort will be reset
$('table').trigger('update', [ sorting ]);

NOTE Don't confuse this method with the sortReset option. updateRows was added to work around the issue of using jQuery with the Prototype library. Triggering an "update" would make Prototype clear the tbody; Please see issue #217 for more details.

This method was originally designed to be used with the pager. It should be used under these conditions:

When the pager removeRows option is true.

When not using the "updateCell" or "addRows" methods.

Before manually adding or removing table rows.

And, before triggering an "update".

Note: The entire table is stored in the cache, but when using the pager with the removeRows option set to true, only the visible portion is actually exists within the table. So, use this option to add all stored rows back into the table before manually changing the contents. Otherwise, if any update method is triggered, only the visible rows will be added back to the cache.

$(function() {
$("table").tablesorter();
$("td.discount").click(function(){
// Do we want to reapply the current sort on the column?
// see updateRow for other resort settings as of v2.19.0
// if resort is undefined, the value from config.resort (added v2.19.0) will be used
var resort = false,
// Do something after the cell update in this callback function
callback = function(table){
/* do something */
},
// randomize a number & add it to the cell
discount = '$' + Math.round(Math.random() * Math.random() * 100) + '.' +
('0' + Math.round(Math.random() * Math.random() * 100)).slice(-2);
// add new table cell text
$(this).text(discount);
// update the table, so the tablesorter plugin can update its value
// set resort flag to false to prevent automatic resort (since we're using a different sort below)
// prior to v2.19.0, leave the resort flag as undefined, or with any other value, to automatically resort the table
// new resort values can be set as of v2.19.0 - please see the "updateRow" documentation for more details
// $("table").trigger("updateCell", [this]); < - resort is undefined so the table WILL resort
$("table").trigger("updateCell", [this, resort, callback]);
// As of version 2.0.14, the table will automatically resort (using the current sort selection)
// after the update, so include the following if you want to specify a different sort
// prior to v2.19.0, set sorting column and direction, this will sort on the first and third column
// after v2.19.0, add any new sort to the "resort" variable above
var sorting = [[3,1]];
$("table").trigger("sorton", [sorting]);
return false;
});
});

This method can be used after a table has been initialized, but it won't work unless you update the configuration settings. See the example, it's easier than describing it.

// Update the list of widgets to apply to the table (add or remove)
// $("table").data("tablesorter").widgets = ["zebra"]; // works the same as
$("table")[0].config.widgets = ["zebra"];
// This method applies the widget - no need to keep updating
$('table').trigger('applyWidgets');

// Remove tablesorter and all classes
$("table").trigger("destroy");
// Remove tablesorter and all classes but the "tablesorter" class on the table
// callback is a function
$("table").trigger("destroy", [false, callback]);

If doAll is true it removes all widgets from the table. If false only non-current widgets (from the widgets option) are removed.

When done removing widgets, the widget re-initializes the currently selected widgets, unless the dontapply parameter is true leaving the table widget-less.

Note that if the widgets option has any named widgets, they will be re-applied to the table when it gets resorted. So if you want to completely remove all widgets from the table, also clear out the widgets option $('table')[0].config.widgets = [];

In v2.15, one additional parameter can be added to the array to perform an "any-match" of the table; Warning! please note that if no external input (with a data-column="all" is attached using bindSearch function) is visible, the user will not know that a filter has been applied.

Events

tablesorter has some methods available to allow updating, resorting or applying widgets to a table after it has been initialized.
TIP! Click on the link in the event column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

Within each row is an array of extracted, then parsed table contents for each column (plus one extra value; see the next comment).

It is important to note that the last value in the column array is the original row index value. This is used when resetting a column sort to its original unsorted order.

In v2.19.1, the raw unparsed data was added to the row data.

In v2.16.0, the last value in the column array is now an object which contains a jquery object of the row, index of the original unsorted order and a child array which contains raw html from any associated child row

Note that all text values will be in lower case if the ignoreCase option is true.

This internal normalized content is what is actually sorted for maximum performance.

row (removed in v2.16.0)

Well not removed, but moved into the row data, within the normalized section of the cache as described above.

This contains an array of jQuery row objects.

These rows are never in sort order, and are used when updating the table after sorting the normalized content. The indexing of these rows is cross-referenced within the normalized values - the extra column value within the row array. Hopefully that makes sense.

The table.config.cache variable is useful when writing widgets that need access to the parsed content.

Internal list of each header element as selected using jQuery selectors in the selectorHeaders option.

This list contains DOM elements (not jQuery objects of each table header cell like the $headers variable) and is how the original version of tablesorter stored these objects.
It is not used in the current version of tablesorter, and is only left in place for backwards compatibility with widgets written for the original tablesorter plugin.

Sort by a shortened date (see dateFormat; these formats can also be followed by a time).

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.

Check out the headers option to see how to use these parsers in your table (example #1).Or add a header class name using "sorter-" plus the parser name (example #2), this includes custom parsers (example #3).

The header cells are targeted using the jQuery selector from the selectorHeaders option.

Please note that the headers cells are simply an array of all header cells and should not be targeted using a column index. For example, given the following table thead markup, the header-index counts the header th cells and does not actually match the data-column index when extra rows and/or colspan or rowspan are included in any of the header cells:

So, in the above example, to target the header cell in the second table column (data-column index of 1), use the following code: table.config.$headers.filter('[data-column="1"]') or table.config.$headers.eq(2).

The table.config.$headers variable is useful within callback functions or when writing widgets that target the table header cells.

Only available when the filter widget is active. This variable contains all external search inputs with data-column="all", bound using the bindSearch function.

The table.config.widgetOptions.filter_$anyMatch variable contains one more more search inputs, and is dynamically updated if the bindSearch function is called; make sure to set the flag to force a new search so that the values of the altered filters is updated appropriately.

Only available when the filter widget is active. This variable contains all table cells within the filter row.

Use the table.config.$filters variable when access to filters is needed. Note! This variable contains the table cell and not the actual input because the filter_formatter function allows adding other types of value selectors (e.g. jQuery UI slider).

Only available when the stickyHeaders widget (not the css3 version) is active.

The table.config.widgetOptions.$sticky variable contains a jQuery object pointing to a cloned table containing the sticky header. The table contained within this variable has a class name of "containsStickyHeaders" versus the original table with a class name of "hasStickyHeaders".

† These methods are the same for both the pager addon and the pager widget.

*NOTE* This pager variable also contains all of the default pager option settings.

*NOTE* When using the pager widget, changing a value within the widgetOptions for the pager may not update the pager as expected. The pager widget uses most of the values within config.pager instead of the pager widgetOptions after initialization.

Initially, this value is set by either the pager page option or from local storage if the savePages option is true. It is then updated by user interaction with the page selector (targeted by the cssGoto option or programmically by the pageSet or pageAndSize method.

Initially, this value is set by either the pager size option or from local storage if the savePages option is true. It is then updated by user interaction with the size selector (targeted by the cssPageSize option or programmically by the pageSize or pageAndSize method.

This variable was removed due to it causing memory leak issues. To find extra tables use config.namespace as follows:

$( config.namespace + '_extra_table' )

Some widgets need to duplicate parts of the original table to provide functionality (e.g. stickyHeaders, scroller). This saved variable will either not exist or contain a jQuery object pointing to the cloned table elements.

This variable was added for the uitheme widget to allow dynamic updating of themes to the original table as well as all cloned parts.

Functions

TIP! Click on the link in the function column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

When calling the function, to get a tbody, set the getIt boolean parameter to true and the removed tbody is returned; setting this option to false or optionally not including it will restore the tbody.
Here is a basic example of how this function is used:

When calling the function, set the toggle option to add (true) or remove (false) process indicators. Include any specific header cells within the $ths variable with which to add the process indicator. When $ths is not defined and a sort is applied, the currently sorted header cells will show process indicators.

All this function does is add or remove a class name of "tablesorter-processing" and the class name contained within the cssProcessing option.

Please note that currently the processing icons do not animate (see issue #158). This is due to javascript being a single-threaded, meaning it only does one task at a time, and maximizing the sorting script. So lots of processing is needed to sort & rebuild the table and thus it has no time for animation. If someone knows of a better solution, please share!

Please note that this function uses jQuery empty(). All data & event handlers are removed. No where within the tablesorter script or included widgets is this function used, it is left intact for backwards compatibility.

This function allows you to bind the same header event listeners to external headers cells (usually clones of the original table). This includes the triggered sort event, left click (only) to sort, ignoring long clicks (> 250ms), pressing enter to trigger a sort (must have focus and a tabindex attribute) and cancelling selection of text (if the option is set).

To ensure the columns match the original table, include data-column attributes pointing to the desired column.

When calling the function, set the removeClasses option to true to include removing of the "tablesorter" class name, tablesorter theme name (e.g. "tablesorter-blue") and the class name applied by the tableClass option. The callback function only provides a table (DOM element only) parameter.

Here is a basic example of how this function is used:

$.tablesorter.destroy( table, true, function(table){
alert('tablesorter has been removed! No sort for you!');
});

Please note that only header cells that still contain a div with a class name of tablesorter-header-inner will have their contents restored; it assumes that the contents have already been restored.

This function returns a zero-based index value of the position of the value within the array, otherwise it returns -1 (Modified v2.15.6).

Use it as follows:

$.tablesorter.isValueInArray(value, array);

value - value to find within the array.

array - array (sortList) to search for the value.

Sadly, this function has limited usefulness outside of tablesorter. It is only meant to search a sortList array and determine if a column (value) is already contained within it. Here is a basic example of how this function is used:

After v2.15.6, this function returns a zero-based index of the position of the value within the array parameter, or -1 if the value is not in the array. Previously, this function returned a boolean value of true if the value was contained within the array, or false if not.

The doAll flag is set to true if all widgets contained with the global $.tablesorter.widgets array are to be removed.
When doAll is false, only widgets not contained within the config.widget option are removed; then if the dontapply flag is false, the widgets named in that option are reapplied (without removing them).

This function returns the column data from an object based on a column index or classname/id (v2.21.1).

Use it as follows:

$.tablesorter.getColumnData( table, object, key );

table - table DOM element (or jQuery object).

object - object containing zero-based column indexes or column class names as a key (e.g. table.config.headers or table.config.widgetOptions.filter_functions; any data found as the value (of the key : value pair) will be returned.

key - key to be Object key; this can be a zero-based column index or header class name/id.

As a full example, say you have a header cell with a class name of "event". And you want to use the textExtraction function for that column, then you would use this function as follows:

The ".event" key can be replaced with a zero-based column index, if the textExtraction option is set up using indexes.

This function is sometimes used in conjunction with the getData function. This function is called first because the getData function uses the result in the configHeaders parameter - the config.headers option result from this function would be an object and not a function.

If string is empty, not a string type, or not a number (after processing), the string itself is returned.
If table is not provided, the format float function will default to U.S. number formatting. The reason a table parameter is needed is to check the value of the usNumberFormat option.

This function uses the usNumberFormat option to determine if either commas or decimals are removed before converting the value within the string parameter into a number type variable. This function does not use the $.tablesorter.isDigit function.

Any numbers wrapped within parentheses are converted into negative numbers; but any other symbols (e.g. currency) are not removed and will cause this function to determine the string as a non-number (e.g. "$1.25" will be returned as a string).

This function determines if a string contains a number after removing commas, periods, quotes and spaces.

Use it as follows:

$.tablesorter.isDigit(string);

string - a string possibly containing a number.

This function will return a boolean value of true if the string parameter contains a number after all commas, decimals, quotes and spaces are removed, and still allow plus or minus signs, or the number wrapped in parenthesis (negative values).

This function allows adding/removing a row to the thead, to display any errors (v2.15).

This function is ONLY included within the widget-pager.js and jquery.tablesorter.pager.js files; in version 3+, I plan to add it as a selectable option in a build.

Use it as follows:

$.tablesorter.showError( table, message );

table - table DOM element (or jQuery object) of table (or tables).

message - a plain string, or string of an HTML row.

This function will add a table row to the thead, with a class name from either the pager plugin cssErrorRow option setting, or the pager widget pager_css.errorRow option (the default class name is "tablesorter-errorRow"; and styled within each theme css file).

The external elements ($els) will allow searching the table using "search" and "keyup" events (enter to start & escape to cancel the search), and uses the filter_liveSearch option, or delayed search.

Include a data-column="#" attribute (where # is the column number) in the search input, to specify to which column the search should apply ~ see this demo for a full example. Warning!, if no data-column attribute is added to the input, the input will be ignored.

In v2.15, use a data-column="all" to bind an external any-match search filter; but note that adding an external any-match filter using this method will not override the filter set by the filter_external option.

The third function parameter, false, is optional. When set to false it forces the inputs to update their values (same as setting the apply flag when using the setFilters function), and reapplies (forces) the current search to be applied again, even if the filter values have not changed; this allows changing the data column attribute dynamically. See the filter external inputs demo for an example.

Warning! If the third parameter is set to true the saved internal filters (config.$filters) will be replaced - not recommended!

options - array of options, jQuery object of option elements, or HTML string of option elements to apply to the targeted select.

replace - a boolean value, which if true all options will be replaced; if false the options will be appended to the current list of options.

onlyAvail - an optional boolean flag, which will be ignored if the options parameter is defined or is an empty string; otherwise it is the value passed to the function which finds all table column values; if true, only the available options will be diplayed.

Please be aware that this function will allow you to modify the select options, but as soon as the user filters any column, all of the select options will refresh and obtain options from the table column, or from the filter_selectSource function.

This filter widget function allows getting an array of the currently applied filters (v2.9; v2.15)

Access it as follows:

$.tablesorter.getFilters(table, flag);

table - table DOM element (or jQuery object) of table.

flag - boolean flag (optional; false by default), added v2.15

Use this function as follows:

// use $('table') or $('table.hasFilters') to make sure the table has a filter row
// only required if the stickyHeaders or scroller widget is being used (they duplicate the table)
$.tablesorter.getFilters( $('table') );

This function returns an array of filter values (e.g. [ '', '', '', '', '', '2?%' ]), or false if the selected table does not have a filter row. It will also return an additional parameter if an external input with data-column="all" containing the value used when matching any table column.

If the second parameter is set to true, it forces the function to get all of the current filter values directly from the inputs. Otherwise, by default, the function returns the last search as found in this stored data $('table').data('lastSearch');.

This function returns true if the filters were sucessfully applied, or false if the table does not have a filter row.

As of v2.15, this function will also set values in any external filters (set either by the filter_external option or using the bindSearch function). An additional search parameter can be included to match any column, but please include an external input with data-column="all" using the bindSearch function so your users will know that a search has been applied.

Also, changed is that when a true value is passed as a third parameter, the search is forced to refresh on the table; otherwise, if the filters set in the search exactly match the previous search, it would be ignored - this was added to prevent numerous ajax calls with exactly the same search or sort parameters (when using the pager).

Added a resize event to the table headers - used by the stickyHeaders widget, but this is a public function available to any widget (v2.10).

There is no built-in resize event for non-window elements, so when this function is active it triggers a resize event when the header cell changes size. So, if you are writing your own widget and need a header resize event, just include the jquery.tablesorter.widgets.js file, or just the extract the function from that file.

Access it as follows:

$.tablesorter.addHeaderResizeEvent(table, disable, { timer : 250 });

table - table DOM element (or jQuery object) of table.

disable - boolean flag, if false events for the targeted table are disabled.

timer - currently only the timer option is available for modification.

$(table).on('resize', function(event, columns){
// columns contains an array of header cells that were resized
// this seemed like a better idea than firing off a resize event for every
// column when the table adjusts itself to fit within its container
event.stopPropagation(); // optional
// do something
console.log( columns );
});

value - value of the variable that is saved (for saving only); set to null if wanting to get a value with options.

options - storage options; see below

This function attempts to give every table a unique identifier using both the page url and table id (or index on the page if no id exists), by default. Here is a usage example and a look at what is stored within the local storage:

To change the default data attributes, use the options to modify them as follows:

$.tablesorter.storage( table, key, value, {
// table id/group id
id : 'group1',
// this group option sets name of the table attribute with the ID;
// but the value within this data attribute is overridden by the above id option
group: 'data-table-group',
// table pages
url : 'page1',
// this page option sets name of the table attribute with the page/url;
// but the value within the data attribute is overridden by the above url option
page: 'data-table-page',
// Option added v2.21.3; if `true` the storage function will use sessionStorage
// if not defined, the `config.widgetOptions.storage_useSessionStorage` setting is checked
// if no settings are found, it will default to `false`, and use localStorage
useSessionStorage : false
});

The storage_fixedUrl widget option allows you to override the current page url (it doesn't need to be a url, just some constant value) and save data for multiple tables across a domain. The value from this option has a lower priority than the options id or group settings (see priority list above).

When using the storage utility to get a value and use custom table options, set the value parameter to null.

Lastly, this storage utility function needs the parseJSON function available in jQuery v1.4.1+.