1/** 2 * Data can often be a complicated mix of numbers and letters (file names 3 * are a common example) and sorting them in a natural manner is quite a 4 * difficult problem. 5 * 6 * Fortunately a deal of work has already been done in this area by other 7 * authors - the following plug-in uses the [naturalSort() function by Jim 8 * Palmer](http://www.overset.com/2008/09/01/javascript-natural-sort-algorithm-with-unicode-support) to provide natural sorting in DataTables. 9 * 10 * @name Natural sorting 11 * @summary Sort data with a mix of numbers and letters _naturally_. 12 * @author [Jim Palmer](http://www.overset.com/2008/09/01/javascript-natural-sort-algorithm-with-unicode-support) 13 * @author [Michael Buehler] (https://github.com/AnimusMachina) 14 * 15 * @example 16 * $('#example').dataTable( { 17 * columnDefs: [ 18 * { type: 'natural', targets: 0 } 19 * ] 20 * } ); 21 * 22 * Html can be stripped from sorting by using 'natural-nohtml' such as 23 * 24 * $('#example').dataTable( { 25 * columnDefs: [ 26 * { type: 'natural-nohtml', targets: 0 } 27 * ] 28 * } ); 29 */ 30 31(function () { 32 33 /* 34 * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license 35 * Author: Jim Palmer (based on chunking idea from Dave Koelle) 36 * Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo 37 * See: http://js-naturalsort.googlecode.com/svn/trunk/naturalSort.js 38 */ 39 function naturalSort(a, b, html) { 40 var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?%?$|^0x[0-9a-f]+$|[0-9]+)/gi, 41 sre = /(^[ ]*|[ ]*$)/g, 42 dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, 43 hre = /^0x[0-9a-f]+$/i, 44 ore = /^0/, 45 htmre = /(<([^>]+)>)/ig, 46 // convert all to strings and trim() 47 x = a.toString().replace( sre, '' ) || '', 48 y = b.toString().replace( sre, '' ) || ''; 49 // remove html from strings if desired 50 if ( ! html) { 51 x = x.replace( htmre, '' ); 52 y = y.replace( htmre, '' ); 53 } 54 // chunk/tokenize 55 var xN = x.replace( re, '\0$1\0' ).replace( /\0$/,'' ).replace( /^\0/,'' ).split( '\0' ), 56 yN = y.replace( re, '\0$1\0' ).replace( /\0$/,'' ).replace( /^\0/,'' ).split( '\0' ), 57 // numeric, hex or date detection 58 xD = parseInt( x.match( hre ), 10 ) || (xN.length !== 1 && x.match( dre ) && Date.parse( x )), 59 yD = parseInt( y.match( hre ), 10 ) || xD && y.match( dre ) && Date.parse( y ) || null; 60 61 // first try and sort Hex codes or Dates 62 if (yD) { 63 if ( xD < yD ) { 64 return -1; 65 } else if ( xD > yD ) { 66 return 1; 67 } 68 } 69 70 // natural sorting through split numeric strings and default strings 71 for (var cLoc = 0, numS = Math.max( xN.length, yN.length ); cLoc < numS; cLoc++) { 72 // find floats not starting with '0', string or 0 if not defined (Clint Priest) 73 var oFxNcL = ! (xN[cLoc] || '').match( ore ) && parseFloat( xN[cLoc], 10 ) || xN[cLoc] || 0; 74 var oFyNcL = ! (yN[cLoc] || '').match( ore ) && parseFloat( yN[cLoc], 10 ) || yN[cLoc] || 0; 75 // handle numeric vs string comparison - number < string - (Kyle Adams) 76 if (isNaN( oFxNcL ) !== isNaN( oFyNcL )) { 77 return (isNaN( oFxNcL )) ? 1 : -1; 78 } 79 // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' 80 else if (typeof oFxNcL !== typeof oFyNcL) { 81 oFxNcL += ''; 82 oFyNcL += ''; 83 } 84 if (oFxNcL < oFyNcL) { 85 return -1; 86 } 87 if (oFxNcL > oFyNcL) { 88 return 1; 89 } 90 } 91 return 0; 92 } 93 94 jQuery.extend( 95 jQuery.fn.dataTableExt.oSort, 96 { 97 "natural-asc": function ( a, b ) { 98 return naturalSort( a,b,true ); 99 }, 100 101 "natural-desc": function ( a, b ) { 102 return naturalSort( a,b,true ) * -1; 103 }, 104 105 "natural-nohtml-asc": function ( a, b ) { 106 return naturalSort( a,b,false ); 107 }, 108 109 "natural-nohtml-desc": function ( a, b ) { 110 return naturalSort( a,b,false ) * -1; 111 }, 112 113 "natural-ci-asc": function ( a, b ) { 114 a = a.toString().toLowerCase(); 115 b = b.toString().toLowerCase(); 116 117 return naturalSort( a,b,true ); 118 }, 119 120 "natural-ci-desc": function ( a, b ) { 121 a = a.toString().toLowerCase(); 122 b = b.toString().toLowerCase(); 123 124 return naturalSort( a,b,true ) * -1; 125 } 126 } 127 ); 128 129}());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.