admin/public/js/plugins/dataTables/jquery.dataTables.js
function _fnSortListener ( settings, colIdx, append, callback )
	{
		var col = settings.aoColumns[ colIdx ];
		var sorting = settings.aaSorting;
		var asSorting = col.asSorting;
		var nextSortIdx;
		var next = function ( a ) {
			var idx = a._idx;
			if ( idx === undefined ) {
				idx = $.inArray( a[1], asSorting );
			}
	
			return idx+1 >= asSorting.length ? 0 : idx+1;
		};
	
		// If appending the sort then we are multi-column sorting
		if ( append && settings.oFeatures.bSortMulti ) {
			// Are we already doing some kind of sort on this column?
			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
	
			if ( sortIdx !== -1 ) {
				// Yes, modify the sort
				nextSortIdx = next( sorting[sortIdx] );
	
				sorting[sortIdx][1] = asSorting[ nextSortIdx ];
				sorting[sortIdx]._idx = nextSortIdx;
			}
			else {
				// No sort on this column yet
				sorting.push( [ colIdx, asSorting[0], 0 ] );
				sorting[sorting.length-1]._idx = 0;
			}
		}
		else if ( sorting.length && sorting[0][0] == colIdx ) {
			// Single column - already sorting on this column, modify the sort
			nextSortIdx = next( sorting[0] );
	
			sorting.length = 1;
			sorting[0][1] = asSorting[ nextSortIdx ];
			sorting[0]._idx = nextSortIdx;
		}
		else {
			// Single column - sort only on this column
			sorting.length = 0;
			sorting.push( [ colIdx, asSorting[0] ] );
			sorting[0]._idx = 0;
		}
	
		// Run the sort by calling a full redraw
		_fnReDraw( settings );
	
		// callback used for async user interaction
		if ( typeof callback == 'function' ) {
			callback( settings );
		}
	}
function _fnSortListener ( settings, colIdx, append, callback )
	{
		var col = settings.aoColumns[ colIdx ];
		var sorting = settings.aaSorting;
		var asSorting = col.asSorting;
		var nextSortIdx;
		var next = function ( a ) {
			var idx = a._idx;
			if ( idx === undefined ) {
				idx = $.inArray( a[1], asSorting );
			}
	
			return idx+1 >= asSorting.length ? 0 : idx+1;
		};
	
		// If appending the sort then we are multi-column sorting
		if ( append && settings.oFeatures.bSortMulti ) {
			// Are we already doing some kind of sort on this column?
			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
	
			if ( sortIdx !== -1 ) {
				// Yes, modify the sort
				nextSortIdx = next( sorting[sortIdx] );
	
				sorting[sortIdx][1] = asSorting[ nextSortIdx ];
				sorting[sortIdx]._idx = nextSortIdx;
			}
			else {
				// No sort on this column yet
				sorting.push( [ colIdx, asSorting[0], 0 ] );
				sorting[sorting.length-1]._idx = 0;
			}
		}
		else if ( sorting.length && sorting[0][0] == colIdx ) {
			// Single column - already sorting on this column, modify the sort
			nextSortIdx = next( sorting[0] );
	
			sorting.length = 1;
			sorting[0][1] = asSorting[ nextSortIdx ];
			sorting[0]._idx = nextSortIdx;
		}
		else {
			// Single column - sort only on this column
			sorting.length = 0;
			sorting.push( [ colIdx, asSorting[0] ] );
			sorting[0]._idx = 0;
		}
	
		// Run the sort by calling a full redraw
		_fnReDraw( settings );
	
		// callback used for async user interaction
		if ( typeof callback == 'function' ) {
			callback( settings );
		}
	}
function _fnSortListener ( settings , colIdx , append , callback ) { var col = settings . aoColumns [ colIdx ] ; var sorting = settings . aaSorting ; var asSorting = col . asSorting ; var nextSortIdx ; var next = function ( a ) { var idx = a . _idx ; if ( idx === undefined ) { idx = $ . inArray ( a [ 1 ] , asSorting ) ; } return idx + 1 >= asSorting . length ? 0 : idx + 1 ; } ; // If appending the sort then we are multi-column sorting
 if ( append && settings . oFeatures . bSortMulti ) { // Are we already doing some kind of sort on this column?
 var sortIdx = $ . inArray ( colIdx , _pluck ( sorting , '0' ) ) ; if ( sortIdx !== - 1 ) { // Yes, modify the sort
 nextSortIdx = next ( sorting [ sortIdx ] ) ; sorting [ sortIdx ] [ 1 ] = asSorting [ nextSortIdx ] ; sorting [ sortIdx ] . _idx = nextSortIdx ; } else { // No sort on this column yet
 sorting . push ( [ colIdx , asSorting [ 0 ] , 0 ] ) ; sorting [ sorting . length - 1 ] . _idx = 0 ; } } else if ( sorting . length && sorting [ 0 ] [ 0 ] == colIdx ) { // Single column - already sorting on this column, modify the sort
 nextSortIdx = next ( sorting [ 0 ] ) ; sorting . length = 1 ; sorting [ 0 ] [ 1 ] = asSorting [ nextSortIdx ] ; sorting [ 0 ] . _idx = nextSortIdx ; } else { // Single column - sort only on this column
 sorting . length = 0 ; sorting . push ( [ colIdx , asSorting [ 0 ] ] ) ; sorting [ 0 ] . _idx = 0 ; } // Run the sort by calling a full redraw
 _fnReDraw ( settings ) ; // callback used for async user interaction
 if ( typeof callback == 'function' ) { callback ( settings ) ; } }
Function to run on user sort request
@param {object} settings dataTables settings object
@param {node} attachTo node to attach the handler to
@param {int} colIdx column sorting index
@param {boolean} [append=false] Append the requested sort to the existing
sort if true (i.e. multi-column sort)
@param {function} [callback] callback function
@memberof DataTable#oApi
Function to run on user sort request