DataTables provides two APIs for sorting information in a table: type based sorting and custom data source sorting. They can be used together or independently, and are fully described on the sorting development page. By far the most commonly used of these two types is "type based sorting" and is the one you are most likely to want to use if just starting out with DataTables.
To add the ability to sort specific data types, using the plug-in functions below, you simply need to include the plug-in's code in the Javascript available for your page, after you load the DataTables library, but before you initialise the DataTable. Then using the sType parameter for that column, set it to the value needed for the plug-in. If sType is not given for a column, DataTables will attempt to detect the type automatically. The following example shows how the numeric comma sorting plug-in (saved to a file) can be used with a DataTable, sorting on the fourth column (live example):
<script type="text/javascript" src="jquery.dataTables.js"></script> <script type="text/javascript" src="dataTables.numericComma.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#example').dataTable( { "aoColumns": [ null, null, null, { "sType": "numeric-comma" }, null ] } ); } ); </script>
The main DataTables package includes sorting functions for string, date and numeric data, but you may very well wish to order data in some other manner (for example currency, formatting numbers, multi-part data etc). The sorting function pairs below provide a wealth of different sorting methods.
It is also worth noting that sorting function go hand-in-hand with type detection functions, and many of the function pairs below has a corresponding type detection function to make installation very easy.
Anti-"the"
Show details |
Often a list of data which has titles in it (books, albums etc) will have the word "the" at the start of some individual titles, which you don't want to include in your sorting order. This plug-in will strip the word "the" from the start of a string and sort on what is left. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "anti-the-pre": function ( a ) { return a.replace(/^the /i, ""); }, "anti-the-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "anti-the-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Chinese (string)
Show details |
Sorting in Javascript for Chinese Character. The Chinese Characters are sorted on the radical and number of strokes. This plug-in performs sorting for Chinese characters. localeCompare MDC documentation. Please also see note about localeCompare and IE9. |
Author: | Patrik Lindstr�m |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "chinese-string-asc" : function (s1, s2) { return s1.localeCompare(s2); }, "chinese-string-desc" : function (s1, s2) { return s2.localeCompare(s1); } } ); |
Currency
Show details |
This plug-in will provide numeric sorting for currency columns (either detected automatically with the currency type detection plug-in or set manually) while taking account of the currency symbol ($ or £ by default). |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "currency-pre": function ( a ) { a = (a==="-") ? 0 : a.replace( /[^\d\-\.]/g, "" ); return parseFloat( a ); }, "currency-asc": function ( a, b ) { return a - b; }, "currency-desc": function ( a, b ) { return b - a; } } ); |
Date dd-mmm-yyyy
Show details |
Adds a new sorting option to dataTables called date-dd-mmm-yyyy . Also
includes a type detection plug-in. Matches and sorts date strings in
the format: (dd/mmm/yyyy . For example:
|
Author: | Jeromy French |
Code: |
var customDateDDMMMYYYYToOrd = function (date) { "use strict"; //let's avoid tom-foolery in this function // Convert to a number YYYYMMDD which we can use to order var dateParts = date.split(/-/); return (dateParts[2] * 10000) + ($.inArray(dateParts[1].toUpperCase(), ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]) * 100) + dateParts[0]; }; // This will help DataTables magic detect the "dd-MMM-yyyy" format; Unshift so that it's the first data type (so it takes priority over existing) jQuery.fn.dataTableExt.aTypes.unshift( function (sData) { "use strict"; //let's avoid tom-foolery in this function if (/^([0-2]?\d|3[0-1])-(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)-\d{4}/i.test(sData)) { return 'date-dd-mmm-yyyy'; } return null; } ); // define the sorts jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-asc'] = function (a, b) { "use strict"; //let's avoid tom-foolery in this function var ordA = customDateDDMMMYYYYToOrd(a), ordB = customDateDDMMMYYYYToOrd(b); return (ordA < ordB) ? -1 : ((ordA > ordB) ? 1 : 0); }; jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-desc'] = function (a, b) { "use strict"; //let's avoid tom-foolery in this function var ordA = customDateDDMMMYYYYToOrd(a), ordB = customDateDDMMMYYYYToOrd(b); return (ordA < ordB) ? 1 : ((ordA > ordB) ? -1 : 0); }; |
Date (dd . mm[ . YYYY])
Show details |
Similar to the Date (dd/mm/YY) data sorting plug-in, this plug-in offers additional flexibility with support for spaces between the values and either . or / notation for the separators. |
Author: | Robert Sedovšek |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "date-eu-pre": function ( date ) { var date = date.replace(" ", ""); if (date.indexOf('.') > 0) { /*date a, format dd.mn.(yyyy) ; (year is optional)*/ var eu_date = date.split('.'); } else { /*date a, format dd/mn/(yyyy) ; (year is optional)*/ var eu_date = date.split('/'); } /*year (optional)*/ if (eu_date[2]) { var year = eu_date[2]; } else { var year = 0; } /*month*/ var month = eu_date[1]; if (month.length == 1) { month = 0+month; } /*day*/ var day = eu_date[0]; if (day.length == 1) { day = 0+day; } return (year + month + day) * 1; }, "date-eu-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "date-eu-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Date (dd/mm/YYY hh:ii:ss)
Show details |
This plug-in will provide date sorting for the "dd/mm/YYY hh:ii:ss" formatting, which is common in France and other European countries. It can also be quickly adapted for other formatting as required. Furthermore, this date sorting plug-in allows for empty values in the column. |
Author: | Ronan Guilloux |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "date-euro-pre": function ( a ) { if ($.trim(a) != '') { var frDatea = $.trim(a).split(' '); var frTimea = frDatea[1].split(':'); var frDatea2 = frDatea[0].split('/'); var x = (frDatea2[2] + frDatea2[1] + frDatea2[0] + frTimea[0] + frTimea[1] + frTimea[2]) * 1; } else { var x = 10000000000000; // = l'an 1000 ... } return x; }, "date-euro-asc": function ( a, b ) { return a - b; }, "date-euro-desc": function ( a, b ) { return b - a; } } ); |
Date / time - US
Show details |
Adds a new sorting option to dataTables called datetime-us . Also
includes a type detection plug-in. Matches and sorts date / time strings in
the format: (m)m/(d)d/(yy)yy (h)h/m(m) (am|pm) . For example:
|
Author: | Kevin Gravier |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "datetime-us-pre": function ( a ) { var b = a.match(/(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2}) (am|pm|AM|PM|Am|Pm)/), month = b[1], day = b[2], year = b[3], hour = b[4], min = b[5], ap = b[6]; if(hour == '12') hour = '0'; if(ap == 'pm') hour = parseInt(hour, 10)+12; if(year.length == 2){ if(parseInt(year, 10)<70) year = '20'+year; else year = '19'+year; } if(month.length == 1) month = '0'+month; if(day.length == 1) day = '0'+day; if(hour.length == 1) hour = '0'+hour; if(min.length == 1) min = '0'+min; var tt = year+month+day+hour+min; return tt; }, "datetime-us-asc": function ( a, b ) { return a - b; }, "datetime-us-desc": function ( a, b ) { return b - a; } }); jQuery.fn.dataTableExt.aTypes.unshift( function ( sData ) { if (sData !== null && sData.match(/\d{1,2}\/\d{1,2}\/\d{2,4} \d{1,2}:\d{1,2} (am|pm|AM|PM|Am|Pm)/)) { return 'datetime-us'; } return null; } ); |
enum
Show details |
Sort by priority through an enumerated list. In this case the words 'High', 'Medium' and 'Low' are used and thus sorted in priority order. This works by converting the works to a numerical value and then sorting based on that value. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "enum-pre": function ( a ) { // Add / alter the switch statement below to match your enum list switch( a ) { case "High": return 1; case "Medium": return 2; case "Low": return 3; default: return 4; } }, "enum-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "enum-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Formatted numbers
Show details |
This plug-in will provide numeric sorting for numeric columns which have extra formatting, such as thousands seperators, currency symobols or any other non-numeric data. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "formatted-num-pre": function ( a ) { a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); return parseFloat( a ); }, "formatted-num-asc": function ( a, b ) { return a - b; }, "formatted-num-desc": function ( a, b ) { return b - a; } } ); |
Natural sorting
Show details |
Data can often be a complicated mix of numbers and letters (file names are a common example) and sorting them in a natural manner is quite a difficult problem. Fortunately a deal of work has already been done in this area by other authors - the following plug-in uses the naturalSort() function by Jim Palmer (download it here) to provide natural sorting in DataTables. |
Author: | Jim Palmer |
Code: |
(function() { /* * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license * Author: Jim Palmer (based on chunking idea from Dave Koelle) * Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo * See: http://js-naturalsort.googlecode.com/svn/trunk/naturalSort.js */ function naturalSort (a, b) { var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, sre = /(^[ ]*|[ ]*$)/g, dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, hre = /^0x[0-9a-f]+$/i, ore = /^0/, // convert all to strings and trim() x = a.toString().replace(sre, '') || '', y = b.toString().replace(sre, '') || '', // chunk/tokenize xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), // numeric, hex or date detection xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)), yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null; // first try and sort Hex codes or Dates if (yD) if ( xD < yD ) return -1; else if ( xD > yD ) return 1; // natural sorting through split numeric strings and default strings for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { // find floats not starting with '0', string or 0 if not defined (Clint Priest) var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; // handle numeric vs string comparison - number < string - (Kyle Adams) if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1; // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' else if (typeof oFxNcL !== typeof oFyNcL) { oFxNcL += ''; oFyNcL += ''; } if (oFxNcL < oFyNcL) return -1; if (oFxNcL > oFyNcL) return 1; } return 0; } jQuery.extend( jQuery.fn.dataTableExt.oSort, { "natural-asc": function ( a, b ) { return naturalSort(a,b); }, "natural-desc": function ( a, b ) { return naturalSort(a,b) * -1; } } ); }()); |
Commas for decimal place
Show details |
It is not uncommon for non-English speaking countries to use a comma for a decimal place. This sorting plug-in shows how that can be taken account of in sorting by adding the type 'numeric-comma' to DataTables. A type detection plug-in for this sorting method is provided below. Please note that the 'Formatted numbers' type detection and sorting plug-ins offer greater flexibility that this plug-in and should be used in preference to this method. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "numeric-comma-pre": function ( a ) { var x = (a == "-") ? 0 : a.replace( /,/, "." ); return parseFloat( x ); }, "numeric-comma-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "numeric-comma-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Numbers with HTML
Show details |
This sorting plug-in allows for HTML tags with numeric data. With the 'html' type it will strip the HTML and then sorts by strings, with this type it strips the HTML and then sorts by numbers. Note also that this sorting plug-in has an equivalent type detection plug-in which can make integration easier. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "num-html-pre": function ( a ) { var x = String(a).replace( /<[\s\S]*?>/g, "" ); return parseFloat( x ); }, "num-html-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "num-html-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Percentage
Show details |
Sort numeric data which has a percent sign with it. |
Author: | Jonathan Romley |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "percent-pre": function ( a ) { var x = (a == "-") ? 0 : a.replace( /%/, "" ); return parseFloat( x ); }, "percent-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "percent-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Persian
Show details |
Sorting in Javascript can be difficult to get right with non-Roman characters - for which special consideration must be made. This plug-in performs correct sorting on Persian characters. |
Author: | Afshin Mehrabani |
Code: |
(function(){ var persianSort = [ 'آ', 'ا', 'ب', 'پ', 'ت', 'ث', 'ج', 'چ', 'ح', 'خ', 'د', 'ذ', 'ر', 'ز', 'ژ', 'س', 'ش', 'ص', 'ط', 'ظ', 'ع', 'غ', 'ف', 'ق', 'ک', 'گ', 'ل', 'م', 'ن', 'و', 'ه', 'ی', 'ي' ]; function GetUniCode(source) { source = $.trim(source); result = ''; for (i = 0; i < source.length; i++) { //Check and fix IE indexOf bug if (!Array.indexOf) { var index = jQuery.inArray(source.charAt(i), persianSort); }else{ var index = persianSort.indexOf(source.charAt(i)); } if (index < 0) { index = source.charCodeAt(i); } if (index < 10) index = '0' + index; result += '00' + index; } return 'a' + result; }; jQuery.extend( jQuery.fn.dataTableExt.oSort, { "pstring-pre": function ( a ) { return GetUniCode(a.toLowerCase()); }, "pstring-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "pstring-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); }()); |
Scientific notation sorting
Show details |
This plug-in will treat numbers which are in scientific notation (for example 1E-10, 1.2E6 etc) and sort them numerically. |
Author: | Nick Schurch |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "scientific-pre": function ( a ) { return parseFloat(a); }, "scientific-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "scientific-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Fully signed numbers sorting
Show details |
Although DataTables' internal numeric sorting works no problem on negative numbers, it does not accept positively signed numbers. This plug-in will sort just such data numerically. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "signed-num-pre": function ( a ) { return (a=="-" || a==="") ? 0 : a.replace('+','')*1; }, "signed-num-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "signed-num-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Hidden title numeric sorting
Show details |
An alternative to the formatted number sorting function above (particularly useful when considering localisation which uses dots/periods for 10^3 separation rather than decimal places). Another method of overcoming it difficulties of sorting formatted numbers is to have the data to be sorted upon separate from the visual data. This sorting function pair will use the 'title' attribute of en empty span element (or anything else) to sort numerically (for example 1'000'000). |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "title-numeric-pre": function ( a ) { var x = a.match(/title="*(-?[0-9\.]+)/)[1]; return parseFloat( x ); }, "title-numeric-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "title-numeric-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Hidden title string sorting
Show details |
Just like the "hidden title numeric sorting" plug-in, this sorting plug-in will take the information to be sorted on from the title attribute of a span element. The only difference is that it is string based sorting rather than numeric. |
Author: | Allan Jardine |
Code: |
jQuery.extend( jQuery.fn.dataTableExt.oSort, { "title-string-pre": function ( a ) { return a.match(/title="(.*?)"/)[1].toLowerCase(); }, "title-string-asc": function ( a, b ) { return ((a < b) ? -1 : ((a > b) ? 1 : 0)); }, "title-string-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } } ); |
Custom data source sorting plug-ins complement type based sorting by adding a method to DataTables to retrieve data live from the DOM just prior to the table being sorted. As such, you can use type based sorting, in-combination with custom data source sorting. This is particularly useful if dealing with DOM information in a table which can change dynamically, such as form inputs, but it can add a little extra overhead to the sorting.
To make use of the plug-ins below, you simply need to include the plug-in's code in the Javascript available for your page, after you load the DataTables library, but before you initialise the DataTable. You also need to specify the sSortDataType parameter for the column, to tell it which plug-in function to use.
The example below shows the use of multiple custom data source plug-ins, and also it's use in-combination with sType (live example):
<script type="text/javascript" src="jquery.dataTables.js"></script> <script type="text/javascript" src="dataTables.dataSourcePlugins.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#example').dataTable( { "aoColumns": [ null, null, { "sSortDataType": "dom-text" }, { "sSortDataType": "dom-text", "sType": "numeric" }, { "sSortDataType": "dom-select" }, { "sSortDataType": "dom-checkbox" } ] } ); } ); </script>
The custom data source functions are used to update the cached data in DataTables, so sorting can occur on columns with user input information.
Checkbox data source
Show details |
Read information from a column of checkboxes (input elements with type checkbox) and return an array to use as a basis for sorting. |
Author: | Allan Jardine |
Code: |
$.fn.dataTableExt.afnSortData['dom-checkbox'] = function ( oSettings, iColumn ) { var aData = []; $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () { aData.push( this.checked==true ? "1" : "0" ); } ); return aData; }; |
Select menu data source
Show details |
Read information from a column of select (drop down) menus and return an array to use as a basis for sorting. |
Author: | Allan Jardine |
Code: |
$.fn.dataTableExt.afnSortData['dom-select'] = function ( oSettings, iColumn ) { var aData = []; $( 'td:eq('+iColumn+') select', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () { aData.push( $(this).val() ); } ); return aData; }; |
Input element data source
Show details |
Read information from a column of input (type text) elements and return an array to use as a basis for sorting. |
Author: | Allan Jardine |
Code: |
$.fn.dataTableExt.afnSortData['dom-text'] = function ( oSettings, iColumn ) { var aData = []; $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () { aData.push( this.value ); } ); return aData; }; |