function _fnSort ( oSettings )
		{
			var i, ien, iLen, aiOrig = [],
				oExtSort = DataTable.ext.type.order,
				aoData = oSettings.aoData;
				oSettings.aoColumns;
				var formatters = 0,
				sortCol,
				displayMaster = oSettings.aiDisplayMaster,
				aSort;
		
			// Resolve any column types that are unknown due to addition or invalidation
			// @todo Can this be moved into a 'data-ready' handler which is called when
			//   data is going to be used in the table?
			_fnColumnTypes( oSettings );
		
			aSort = _fnSortFlatten( oSettings );
		
			for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
				sortCol = aSort[i];
		
				// Track if we can use the fast sort algorithm
				if ( sortCol.formatter ) {
					formatters++;
				}
		
				// Load the data needed for the sort, for each cell
				_fnSortData( oSettings, sortCol.col );
			}
		
			/* No sorting required if server-side or no sorting array */
			if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
			{
				// Create a value - key array of the current row positions such that we can use their
				// current position during the sort, if values match, in order to perform stable sorting
				for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
					aiOrig[ displayMaster[i] ] = i;
				}
		
				/* Do the sort - here we want multi-column sorting based on a given data source (column)
				 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
				 * follow on it's own, but this is what we want (example two column sorting):
				 *  fnLocalSorting = function(a,b){
				 *    var iTest;
				 *    iTest = oSort['string-asc']('data11', 'data12');
				 *      if (iTest !== 0)
				 *        return iTest;
				 *    iTest = oSort['numeric-desc']('data21', 'data22');
				 *    if (iTest !== 0)
				 *      return iTest;
				 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
				 *  }
				 * Basically we have a test for each sorting column, if the data in that column is equal,
				 * test the next column. If all columns match, then we use a numeric sort on the row
				 * positions in the original data array to provide a stable sort.
				 *
				 * Note - I know it seems excessive to have two sorting methods, but the first is around
				 * 15% faster, so the second is only maintained for backwards compatibility with sorting
				 * methods which do not have a pre-sort formatting function.
				 */
				if ( formatters === aSort.length ) {
					// All sort types have formatting functions
					displayMaster.sort( function ( a, b ) {
						var
							x, y, k, test, sort,
							len=aSort.length,
							dataA = aoData[a]._aSortData,
							dataB = aoData[b]._aSortData;
		
						for ( k=0 ; k<len ; k++ ) {
							sort = aSort[k];
		
							x = dataA[ sort.col ];
							y = dataB[ sort.col ];
		
							test = x<y ? -1 : x>y ? 1 : 0;
							if ( test !== 0 ) {
								return sort.dir === 'asc' ? test : -test;
							}
						}
		
						x = aiOrig[a];
						y = aiOrig[b];
						return x<y ? -1 : x>y ? 1 : 0;
					} );
				}
				else {
					// Depreciated - remove in 1.11 (providing a plug-in option)
					// Not all sort types have formatting methods, so we have to call their sorting
					// methods.
					displayMaster.sort( function ( a, b ) {
						var x, y, k, test, sort, fn,
							len=aSort.length,
							dataA = aoData[a]._aSortData,
							dataB = aoData[b]._aSortData;
		
						for ( k=0 ; k<len ; k++ ) {
							sort = aSort[k];
		
							x = dataA[ sort.col ];
							y = dataB[ sort.col ];
		
							fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
							test = fn( x, y );
							if ( test !== 0 ) {
								return test;
							}
						}
		
						x = aiOrig[a];
						y = aiOrig[b];
						return x<y ? -1 : x>y ? 1 : 0;
					} );
				}
			}
		
			/* Tell the draw function that we have sorted the data */
			oSettings.bSorted = true;
		}
/**
		 * Change the order of the table
		 *  @param {object} oSettings dataTables settings object
		 *  @memberof DataTable#oApi
		 *  @todo This really needs split up!
		 */
Change the order of the table
@param {object} oSettings dataTables settings object
@memberof DataTable#oApi
@todo This really needs split up!
Change the order of the table @param { object } oSettings dataTables settings object @memberof DataTable#oApi @todo This really needs split up!
function _fnSort ( oSettings )
		{
			var i, ien, iLen, aiOrig = [],
				oExtSort = DataTable.ext.type.order,
				aoData = oSettings.aoData;
				oSettings.aoColumns;
				var formatters = 0,
				sortCol,
				displayMaster = oSettings.aiDisplayMaster,
				aSort;
			_fnColumnTypes( oSettings );
			aSort = _fnSortFlatten( oSettings );
			for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
				sortCol = aSort[i];
				if ( sortCol.formatter ) {
					formatters++;
				}
				_fnSortData( oSettings, sortCol.col );
			}
			if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
			{
				for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
					aiOrig[ displayMaster[i] ] = i;
				}
				if ( formatters === aSort.length ) {
					displayMaster.sort( function ( a, b ) {
						var
							x, y, k, test, sort,
							len=aSort.length,
							dataA = aoData[a]._aSortData,
							dataB = aoData[b]._aSortData;
						for ( k=0 ; k<len ; k++ ) {
							sort = aSort[k];
							x = dataA[ sort.col ];
							y = dataB[ sort.col ];
							test = x<y ? -1 : x>y ? 1 : 0;
							if ( test !== 0 ) {
								return sort.dir === 'asc' ? test : -test;
							}
						}
						x = aiOrig[a];
						y = aiOrig[b];
						return x<y ? -1 : x>y ? 1 : 0;
					} );
				}
				else {
					displayMaster.sort( function ( a, b ) {
						var x, y, k, test, sort, fn,
							len=aSort.length,
							dataA = aoData[a]._aSortData,
							dataB = aoData[b]._aSortData;
						for ( k=0 ; k<len ; k++ ) {
							sort = aSort[k];
							x = dataA[ sort.col ];
							y = dataB[ sort.col ];
							fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
							test = fn( x, y );
							if ( test !== 0 ) {
								return test;
							}
						}
						x = aiOrig[a];
						y = aiOrig[b];
						return x<y ? -1 : x>y ? 1 : 0;
					} );
				}
			}
			oSettings.bSorted = true;
		}
function _fnSort ( oSettings ) { var i , ien , iLen , aiOrig = [ ] , oExtSort = DataTable . ext . type . order , aoData = oSettings . aoData ; oSettings . aoColumns ; var formatters = 0 , sortCol , displayMaster = oSettings . aiDisplayMaster , aSort ; _fnColumnTypes ( oSettings ) ; aSort = _fnSortFlatten ( oSettings ) ; for ( i = 0 , ien = aSort . length ; i < ien ; i ++ ) { sortCol = aSort [ i ] ; if ( sortCol . formatter ) { formatters ++ ; } _fnSortData ( oSettings , sortCol . col ) ; } if ( _fnDataSource ( oSettings ) != 'ssp' && aSort . length !== 0 ) { for ( i = 0 , iLen = displayMaster . length ; i < iLen ; i ++ ) { aiOrig [ displayMaster [ i ] ] = i ; } if ( formatters === aSort . length ) { displayMaster . sort ( function ( a , b ) { var x , y , k , test , sort , len = aSort . length , dataA = aoData [ a ] . _aSortData , dataB = aoData [ b ] . _aSortData ; for ( k = 0 ; k < len ; k ++ ) { sort = aSort [ k ] ; x = dataA [ sort . col ] ; y = dataB [ sort . col ] ; test = x < y ? - 1 : x > y ? 1 : 0 ; if ( test !== 0 ) { return sort . dir === 'asc' ? test : - test ; } } x = aiOrig [ a ] ; y = aiOrig [ b ] ; return x < y ? - 1 : x > y ? 1 : 0 ; } ) ; } else { displayMaster . sort ( function ( a , b ) { var x , y , k , test , sort , fn , len = aSort . length , dataA = aoData [ a ] . _aSortData , dataB = aoData [ b ] . _aSortData ; for ( k = 0 ; k < len ; k ++ ) { sort = aSort [ k ] ; x = dataA [ sort . col ] ; y = dataB [ sort . col ] ; fn = oExtSort [ sort . type + "-" + sort . dir ] || oExtSort [ "string-" + sort . dir ] ; test = fn ( x , y ) ; if ( test !== 0 ) { return test ; } } x = aiOrig [ a ] ; y = aiOrig [ b ] ; return x < y ? - 1 : x > y ? 1 : 0 ; } ) ; } } oSettings . bSorted = true ; }
Change the order of the table
  @param {object} oSettings dataTables settings object
  @memberof DataTable#oApi
  @todo This really needs split up!
Change the order of the table @param { object } oSettings dataTables settings object @memberof DataTable#oApi @todo This really needs split up!
// Resolve any column types that are unknown due to addition or invalidation // @todo Can this be moved into a 'data-ready' handler which is called when //   data is going to be used in the table? // Track if we can use the fast sort algorithm // Load the data needed for the sort, for each cell /* No sorting required if server-side or no sorting array */ // Create a value - key array of the current row positions such that we can use their // current position during the sort, if values match, in order to perform stable sorting /* Do the sort - here we want multi-column sorting based on a given data source (column)
				 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
				 * follow on it's own, but this is what we want (example two column sorting):
				 *  fnLocalSorting = function(a,b){
				 *    var iTest;
				 *    iTest = oSort['string-asc']('data11', 'data12');
				 *      if (iTest !== 0)
				 *        return iTest;
				 *    iTest = oSort['numeric-desc']('data21', 'data22');
				 *    if (iTest !== 0)
				 *      return iTest;
				 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
				 *  }
				 * Basically we have a test for each sorting column, if the data in that column is equal,
				 * test the next column. If all columns match, then we use a numeric sort on the row
				 * positions in the original data array to provide a stable sort.
				 *
				 * Note - I know it seems excessive to have two sorting methods, but the first is around
				 * 15% faster, so the second is only maintained for backwards compatibility with sorting
				 * methods which do not have a pre-sort formatting function.
				 */ // All sort types have formatting functions // Depreciated - remove in 1.11 (providing a plug-in option) // Not all sort types have formatting methods, so we have to call their sorting // methods. /* Tell the draw function that we have sorted the data */