1
0
mirror of https://github.com/DataTables/DataTables.git synced 2025-02-20 18:54:15 +01:00

Internal: Refactor sorting classes for size and efficiency

- Refactoring _fnSortingClasses to be more efficient in how it operates
  and to compress better. This is done by looping first over the
  elements to have their classes removed, and then looping over only
  those to have them added. Previous all columns were operated upon.
  Also using _pluck and that fact that all cells fromt he tbody are
  stored makes the code much smaller, more readable and compressable.
  Only 0.5KiB saved in the refactor, but every little helps...

- Restored column sorting classes functionality that had been disabled
  earlier in the 1.10 development sequence.
This commit is contained in:
Allan Jardine 2013-05-17 09:48:21 +01:00
parent 9f1cae4528
commit 6a6eed2db3
4 changed files with 85 additions and 148 deletions

View File

@ -59,6 +59,7 @@ function _fnAddColumn( oSettings, nTh )
function _fnColumnOptions( oSettings, iCol, oOptions )
{
var oCol = oSettings.aoColumns[ iCol ];
var oClasses = oSettings.oClasses;
/* User specified column options */
if ( oOptions !== undefined && oOptions !== null )
@ -112,30 +113,30 @@ function _fnColumnOptions( oSettings, iCol, oOptions )
return innerData;
};
oCol.fnSetData = _fnSetObjectDataFn( oCol.mData );
/* Feature sorting overrides column specific when off */
if ( !oSettings.oFeatures.bSort )
{
oCol.bSortable = false;
}
/* Check that the class assignment is correct for sorting */
var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
if ( !oCol.bSortable || (!bAsc && !bDesc) )
{
oCol.sSortingClass = oSettings.oClasses.sSortableNone;
oCol.sSortingClass = oClasses.sSortableNone;
oCol.sSortingClassJUI = "";
}
else if ( bAsc && !bDesc )
{
oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
oCol.sSortingClass = oClasses.sSortableAsc;
oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
}
else if ( !bAsc && bDesc )
{
oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
oCol.sSortingClass = oClasses.sSortableDesc;
oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
}
}
@ -153,7 +154,7 @@ function _fnAdjustColumnSizing ( oSettings )
{
return false;
}
_fnCalculateColumnWidths( oSettings );
for ( var i=0 , iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
{

View File

@ -145,7 +145,7 @@ function _fnBuildHead( oSettings )
/* ARIA role for the rows */
$(oSettings.nTHead).children('tr').attr('role', 'row');
/* Add the extra markup needed by jQuery UI's themes */
if ( oSettings.bJUI )
{
@ -158,7 +158,7 @@ function _fnBuildHead( oSettings )
$(nTh).contents().appendTo(nDiv);
var nSpan = document.createElement('span');
nSpan.className = oSettings.oClasses.sSortIcon;
nSpan.className = oSettings.oClasses.sSortIcon+' '+oSettings.aoColumns[i].sSortingClassJUI;
nDiv.appendChild( nSpan );
nTh.appendChild( nDiv );
}
@ -168,14 +168,12 @@ function _fnBuildHead( oSettings )
{
for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
{
$(oSettings.aoColumns[i].nTh).addClass( oSettings.aoColumns[i].sSortingClass );
if ( oSettings.aoColumns[i].bSortable !== false )
{
_fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
}
else
{
$(oSettings.aoColumns[i].nTh).addClass( oSettings.oClasses.sSortableNone );
}
}
}

View File

@ -306,145 +306,76 @@ function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
* @param {object} oSettings dataTables settings object
* @memberof DataTable#oApi
*/
function _fnSortingClasses( oSettings )
function _fnSortingClasses( settings )
{
var i, iLen, j, jLen, iFound;
var aaSort, sClass;
var iColumns = oSettings.aoColumns.length;
var oClasses = oSettings.oClasses;
for ( i=0 ; i<iColumns ; i++ )
{
if ( oSettings.aoColumns[i].bSortable )
{
$(oSettings.aoColumns[i].nTh).removeClass( oClasses.sSortAsc +" "+ oClasses.sSortDesc +
" "+ oSettings.aoColumns[i].sSortingClass );
}
}
aaSort = _fnSortFlatten( oSettings );
/* Apply the required classes to the header */
for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
{
if ( oSettings.aoColumns[i].bSortable )
{
sClass = oSettings.aoColumns[i].sSortingClass;
iFound = -1;
for ( j=0 ; j<aaSort.length ; j++ )
{
if ( aaSort[j].col == i )
{
sClass = ( aaSort[j].dir == "asc" ) ?
oClasses.sSortAsc : oClasses.sSortDesc;
iFound = j;
break;
}
}
$(oSettings.aoColumns[i].nTh).addClass( sClass );
if ( oSettings.bJUI )
{
/* jQuery UI uses extra markup */
var jqSpan = $("span."+oClasses.sSortIcon, oSettings.aoColumns[i].nTh);
jqSpan.removeClass(oClasses.sSortJUIAsc +" "+ oClasses.sSortJUIDesc +" "+
oClasses.sSortJUI +" "+ oClasses.sSortJUIAscAllowed +" "+ oClasses.sSortJUIDescAllowed );
var sSpanClass;
if ( iFound == -1 )
{
sSpanClass = oSettings.aoColumns[i].sSortingClassJUI;
}
else if ( aaSort[iFound].dir == "asc" )
{
sSpanClass = oClasses.sSortJUIAsc;
}
else
{
sSpanClass = oClasses.sSortJUIDesc;
}
jqSpan.addClass( sSpanClass );
}
}
else
{
/* No sorting on this column, so add the base class. This will have been assigned by
* _fnAddColumn
*/
$(oSettings.aoColumns[i].nTh).addClass( oSettings.aoColumns[i].sSortingClass );
var oldSort = settings.aLastSort;
var columns = settings.aoColumns;
var classes = settings.oClasses;
var sortIcon = classes.sSortIcon;
var sort = _fnSortFlatten( settings );
var i, ien, col, colIdx, jqTh;
// Remove old sorting classes
for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
colIdx = oldSort[i].col;
col = columns[ colIdx ];
jqTh = $(col.nTh);
// Remove base TH sorting
jqTh
.removeClass(
classes.sSortAsc +" "+
classes.sSortDesc +" "
)
.addClass( col.sSortingClass );
// Remove icon sorting
if ( sortIcon ) {
jqTh
.find( 'span.'+sortIcon )
.removeClass(
classes.sSortJUIAsc +" "+
classes.sSortJUIDesc +" "+
classes.sSortJUI +" "+
classes.sSortJUIAscAllowed +" "+
classes.sSortJUIDescAllowed
)
.addClass( col.sSortingClassJUI );
}
// Remove column sorting
$( _pluck( settings.aoData, 'anCells', colIdx ) )
.removeClass( classes.sSortColumn + (i<2 ? i+1 : 3) );
}
// @todo This is totally inefficient. It is accessing the class name of every
// cell when it really doesn't need to. It should determine which cells
// have classes to be removed (by saving the previous state or doing a check
// on the first row), and then add to the required cells. Use _pluck.
// DISABLED until this can be done, since _fnGetTdNodes has been removed.
return;
/*
* Apply the required classes to the table body
* Note that this is given as a feature switch since it can significantly slow down a sort
* on large data sets (adding and removing of classes is always slow at the best of times..)
* Further to this, note that this code is admittedly fairly ugly. It could be made a lot
* simpler using jQuery selectors and add/removeClass, but that is significantly slower
* (on the order of 5 times slower) - hence the direct DOM manipulation here.
* Note that for deferred drawing we do use jQuery - the reason being that taking the first
* row found to see if the whole column needs processed can miss classes since the first
* column might be new.
*/
sClass = oClasses.sSortColumn;
if ( oSettings.oFeatures.bSort && oSettings.oFeatures.bSortClasses )
{
var nTds = _fnGetTdNodes( oSettings );
/* Determine what the sorting class for each column should be */
var iClass, iTargetCol;
var asClasses = [];
for (i = 0; i < iColumns; i++)
{
asClasses.push("");
}
for (i = 0, iClass = 1; i < aaSort.length; i++)
{
iTargetCol = parseInt( aaSort[i][0], 10 );
asClasses[iTargetCol] = sClass + iClass;
if ( iClass < 3 )
{
iClass++;
}
}
/* Make changes to the classes for each cell as needed */
var reClass = new RegExp(sClass + "[123]");
var sTmpClass, sCurrentClass, sNewClass;
for ( i=0, iLen=nTds.length; i<iLen; i++ )
{
/* Determine which column we're looking at */
iTargetCol = i % iColumns;
/* What is the full list of classes now */
sCurrentClass = nTds[i].className;
/* What sorting class should be applied? */
sNewClass = asClasses[iTargetCol];
/* What would the new full list be if we did a replacement? */
sTmpClass = sCurrentClass.replace(reClass, sNewClass);
if ( sTmpClass != sCurrentClass )
{
/* We changed something */
nTds[i].className = $.trim( sTmpClass );
}
else if ( sNewClass.length > 0 && sCurrentClass.indexOf(sNewClass) == -1 )
{
/* We need to add a class */
nTds[i].className = sCurrentClass + " " + sNewClass;
}
// Add new ones
for ( i=0, ien=sort.length ; i<ien ; i++ ) {
colIdx = sort[i].col;
col = columns[ colIdx ];
jqTh = $(col.nTh);
// Add base TH sorting
jqTh
.removeClass( col.sSortingClass )
.addClass( sort[i].dir == "asc" ?
classes.sSortAsc : classes.sSortDesc
);
// Add icon sorting
if ( sortIcon ) {
jqTh
.find( 'span.'+sortIcon )
.addClass( sort[i].dir == "asc" ?
classes.sSortJUIAsc : classes.sSortJUIDesc
);
}
// Add column sorting
$( _pluck( settings.aoData, 'anCells', colIdx ) )
.addClass( classes.sSortColumn + (i<2 ? i+1 : 3) );
}
settings.aLastSort = sort;
}

View File

@ -867,5 +867,12 @@ DataTable.models.oSettings = {
/**
* DIV container for the footer scrolling table if scrolling
*/
"nScrollFoot": null
"nScrollFoot": null,
/**
* Last applied sort
* @type array
* @default []
*/
"aLastSort": []
};