From 34f86db7826c83eb7c10909071b0dee596a513ec Mon Sep 17 00:00:00 2001 From: Allan Jardine Date: Sat, 25 May 2013 08:21:55 +0100 Subject: [PATCH] Build update - all the latest changes, compiled into the source file. --- media/js/jquery.dataTables.js | 4039 +++++++++++++++++++-------------- 1 file changed, 2327 insertions(+), 1712 deletions(-) diff --git a/media/js/jquery.dataTables.js b/media/js/jquery.dataTables.js index 89179c85..90509098 100644 --- a/media/js/jquery.dataTables.js +++ b/media/js/jquery.dataTables.js @@ -21,7 +21,7 @@ */ /*jslint evil: true, undef: true, browser: true */ -/*globals $,require,jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns,_fnHungarianMap,_fnCamelToHungarian,_fnBuildAjax,_fnAjaxDataSrc*/ +/*globals $,require,jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnEscapeRegex,_fnDeleteIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns,_fnHungarianMap,_fnCamelToHungarian,_fnBuildAjax,_fnAjaxDataSrc*/ (/** @lends */function( window, document, undefined ) { @@ -206,7 +206,6 @@ document.body.removeChild( n ); } - /** * Add a column to the list used for the table with default values * @param {object} oSettings dataTables settings object @@ -268,6 +267,7 @@ function _fnColumnOptions( oSettings, iCol, oOptions ) { var oCol = oSettings.aoColumns[ iCol ]; + var oClasses = oSettings.oClasses; /* User specified column options */ if ( oOptions !== undefined && oOptions !== null ) @@ -286,7 +286,14 @@ oCol.sType = oOptions.sType; oCol._bAutoType = false; } - + + // `class` is a reserved word in Javascript, so we need to provide + // the ability to use a valid name for the camel case input + if ( oOptions.className && ! oOptions.sClass ) + { + oOptions.sClass = oOptions.className; + } + $.extend( oCol, oOptions ); _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); @@ -314,34 +321,30 @@ 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 */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + 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 ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) + else if ( bAsc && !bDesc ) { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; + oCol.sSortingClass = oClasses.sSortableAsc; + oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) + else if ( !bAsc && bDesc ) { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; + oCol.sSortingClass = oClasses.sSortableDesc; + oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; } } @@ -359,7 +362,7 @@ { return false; } - + _fnCalculateColumnWidths( oSettings ); for ( var i=0 , iLen=oSettings.aoColumns.length ; i= oSettings.fnRecordsDisplay()) ? - 0 : oSettings.iInitDisplayStart; - } + iDisplayStart = bServerSide ? + iInitDisplayStart : + iInitDisplayStart >= oSettings.fnRecordsDisplay() ? + 0 : + iInitDisplayStart; + oSettings.iInitDisplayStart = -1; - _fnCalculateEnd( oSettings ); } /* Server-side processing draw intercept */ @@ -1432,7 +1487,7 @@ oSettings.bDeferLoading = false; oSettings.iDraw++; } - else if ( !oSettings.oFeatures.bServerSide ) + else if ( !bServerSide ) { oSettings.iDraw++; } @@ -1441,23 +1496,18 @@ return; } - if ( oSettings.aiDisplay.length !== 0 ) + if ( aiDisplay.length !== 0 ) { - var iStart = oSettings._iDisplayStart; - var iEnd = oSettings._iDisplayEnd; - - if ( oSettings.oFeatures.bServerSide ) - { - iStart = 0; - iEnd = oSettings.aoData.length; - } + var iStart = bServerSide ? 0 : iDisplayStart; + var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd; for ( var j=iStart ; j', { 'class': iStripes ? asStripeClasses[0] : '' } ) + .append( $('', { + 'valign': 'top', + 'colSpan': _fnVisbleColumns( oSettings ), + 'class': oSettings.oClasses.sRowEmpty + } ).html( sZero ) )[0]; } /* Header and footer callbacks */ _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0], - _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] ); + _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0], - _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] ); - - /* - * Need to remove any old row from the display - note we can't just empty the tbody using - * $().html('') since this will unbind the jQuery event handlers (even although the node - * still exists!) - equally we can't use innerHTML, since IE throws an exception. + _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); + + var body = $(oSettings.nTBody); + + /* When doing infinite scrolling, only remove child rows when sorting, filtering or start + * up. When not infinite scroll, always do it. */ - var - nAddFrag = document.createDocumentFragment(), - nRemoveFrag = document.createDocumentFragment(), - nBodyPar; - - if ( oSettings.nTBody ) + if ( !oSettings.oScroll.bInfinite || !oSettings._bInitComplete || + oSettings.bSorted || oSettings.bFiltered ) { - nBodyPar = oSettings.nTBody.parentNode; - nRemoveFrag.appendChild( oSettings.nTBody ); - - /* When doing infinite scrolling, only remove child rows when sorting, filtering or start - * up. When not infinite scroll, always do it. - */ - if ( !oSettings.oScroll.bInfinite || !oSettings._bInitComplete || - oSettings.bSorted || oSettings.bFiltered ) - { - while( (n = oSettings.nTBody.firstChild) ) - { - oSettings.nTBody.removeChild( n ); - } - } - - /* Put the draw table into the dom */ - for ( i=0, iLen=anRows.length ; i') : sSearchStr==="" ? '' : sSearchStr+' '; - + var nFilter = document.createElement( 'div' ); nFilter.className = oSettings.oClasses.sFilter; nFilter.innerHTML = ''; @@ -2175,7 +2179,7 @@ { nFilter.id = oSettings.sTableId+'_filter'; } - + var jqFilter = $('input[type="search"]', nFilter); // Store a reference to the input element, so other input elements could be @@ -2188,14 +2192,6 @@ var n = oSettings.aanFeatures.f; var val = this.value==="" ? "" : this.value; // mental IE8 fix :-( - for ( var i=0, iLen=n.length ; i=0 ; i-- ) - { - var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), - oSettings.aoColumns[iColumn].sType ); - if ( ! rpSearch.test( sData ) ) - { - oSettings.aiDisplay.splice( i, 1 ); - iIndexCorrector++; + + var data; + var display = settings.aiDisplay; + var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive ); + + for ( var i=display.length-1 ; i>=0 ; i-- ) { + data = settings.aoData[ display[i] ]._aFilterData[ colIdx ]; + + if ( ! rpSearch.test( data ) ) { + display.splice( i, 1 ); } } } @@ -2358,19 +2364,19 @@ var i; var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); var oPrevSearch = oSettings.oPreviousSearch; - + /* Check if we are forcing or not - optional parameter */ if ( !iForce ) { iForce = 0; } - + /* Need to take account of custom filtering functions - always filter */ if ( DataTable.ext.afnFiltering.length !== 0 ) { iForce = 1; } - + /* * If the input is blank - we want the full data set */ @@ -2390,11 +2396,11 @@ sInput.indexOf(oPrevSearch.sSearch) !== 0 ) { /* Nuke the old display array - we are going to rebuild it */ - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - + oSettings.aiDisplay.length = 0; + /* Force a rebuild of the search array */ _fnBuildSearchArray( oSettings, 1 ); - + /* Search through all records to populate the search array * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 * mapping @@ -2413,7 +2419,7 @@ * Don't have to search the whole master array again */ var iIndexCorrector = 0; - + /* Search the current results */ for ( i=0 ; i').html(sSearch).text(); - } - - // Strip newline characters - return sSearch.replace( /[\n\r]/g, " " ); - } - /** * Build a regular expression object suitable for searching a table * @param {string} sSearch string to search for @@ -2504,7 +2476,7 @@ { var asSearch, sRegExpString = bRegex ? sSearch : _fnEscapeRegex( sSearch ); - + if ( bSmart ) { /* Generate the regular expression to use. Something along the lines of: @@ -2513,40 +2485,11 @@ asSearch = sRegExpString.split( ' ' ); sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; } - + return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); } - /** - * Convert raw data into something that the user can search on - * @param {string} sData data to be modified - * @param {string} sType data type - * @returns {string} search string - * @memberof DataTable#oApi - */ - function _fnDataToSearch ( sData, sType ) - { - if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) - { - return DataTable.ext.ofnSearch[sType]( sData ); - } - else if ( sData === null ) - { - return ''; - } - else if ( sType == "html" ) - { - return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); - } - else if ( typeof sData === "string" ) - { - return sData.replace(/[\r\n]/g," "); - } - return sData; - } - - /** * scape a string such that it can be used in a regular expression * @param {string} sVal string to escape @@ -2560,109 +2503,140 @@ return sVal.replace(reReplace, '\\$1'); } + + + var __filter_div = $('
'); + + // Update the filtering data for each row if needed (by invalidation or first run) + function _fnFilterData ( settings ) + { + var columns = settings.aoColumns; + var column; + var i, j, ien, jen, filterData, cellData, row; + var fomatters = DataTable.ext.ofnSearch; + + for ( i=0, ien=settings.aoData.length ; i', { + 'class': settings.oClasses.sInfo, + 'id': ! nodes ? tid+'_info' : null + } )[0]; } /** * Update the information elements in the display - * @param {object} oSettings dataTables settings object + * @param {object} settings dataTables settings object * @memberof DataTable#oApi */ - function _fnUpdateInfo ( oSettings ) + function _fnUpdateInfo ( settings ) { /* Show information about the table */ - if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) - { + var nodes = settings.aanFeatures.i; + if ( nodes.length === 0 ) { return; } var - oLang = oSettings.oLanguage, - iStart = oSettings._iDisplayStart+1, - iEnd = oSettings.fnDisplayEnd(), - iMax = oSettings.fnRecordsTotal(), - iTotal = oSettings.fnRecordsDisplay(), - sOut; - - if ( iTotal === 0 ) - { - /* Empty record set */ - sOut = oLang.sInfoEmpty; - } - else { - /* Normal record set */ - sOut = oLang.sInfo; - } + lang = settings.oLanguage, + start = settings._iDisplayStart+1, + end = settings.fnDisplayEnd(), + max = settings.fnRecordsTotal(), + total = settings.fnRecordsDisplay(), + out = total ? + lang.sInfo : + lang.sInfoEmpty; - if ( iTotal != iMax ) - { + if ( total !== max ) { /* Record set after filtering */ - sOut += ' ' + oLang.sInfoFiltered; + out += ' ' + lang.sInfoFiltered; } // Convert the macros - sOut += oLang.sInfoPostFix; - sOut = _fnInfoMacros( oSettings, sOut ); + out += lang.sInfoPostFix; + out = _fnInfoMacros( settings, out ); - if ( oLang.fnInfoCallback !== null ) - { - sOut = oLang.fnInfoCallback.call( oSettings.oInstance, - oSettings, iStart, iEnd, iMax, iTotal, sOut ); + var callback = lang.fnInfoCallback; + if ( callback !== null ) { + out = callback.call( settings.oInstance, + settings, start, end, max, total, out + ); } - var n = oSettings.aanFeatures.i; - for ( var i=0, iLen=n.length ; irecords || len===-1 ? - records : - calc; - } - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Note that most of the paging logic is done in @@ -2895,7 +2828,6 @@ type = settings.sPaginationType, plugin = DataTable.ext.oPagination[ type ], redraw = function( settings ) { - _fnCalculateEnd( settings ); _fnDraw( settings ); }, node = $('
').addClass( settings.oClasses.sPaging + type )[0]; @@ -2980,7 +2912,7 @@ settings._iDisplayStart = start; $(settings.oInstance).trigger('page', settings); - + return changed; } @@ -2988,44 +2920,34 @@ /** * Generate the node required for the processing node - * @param {object} oSettings dataTables settings object + * @param {object} settings dataTables settings object * @returns {node} Processing element * @memberof DataTable#oApi */ - function _fnFeatureHtmlProcessing ( oSettings ) + function _fnFeatureHtmlProcessing ( settings ) { - var nProcessing = document.createElement( 'div' ); - - if ( !oSettings.aanFeatures.r ) - { - nProcessing.id = oSettings.sTableId+'_processing'; - } - nProcessing.innerHTML = oSettings.oLanguage.sProcessing; - nProcessing.className = oSettings.oClasses.sProcessing; - oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); - - return nProcessing; + return $('
', { + 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null, + 'class': settings.oClasses.sProcessing + } ) + .html( settings.oLanguage.sProcessing ) + .insertBefore( settings.nTable )[0]; } /** * Display or hide the processing indicator - * @param {object} oSettings dataTables settings object - * @param {bool} bShow Show the processing indicator (true) or not (false) + * @param {object} settings dataTables settings object + * @param {bool} show Show the processing indicator (true) or not (false) * @memberof DataTable#oApi */ - function _fnProcessingDisplay ( oSettings, bShow ) + function _fnProcessingDisplay ( settings, show ) { - if ( oSettings.oFeatures.bProcessing ) - { - var an = oSettings.aanFeatures.r; - for ( var i=0, iLen=an.length ; i').html( _fnGetCellData( oSettings, iMaxIndex, iCol, 'display' ) )[0] : + data.anCells[ iCol ]; } + var __re_html_remove = /<.*?>/g; + /** * Get the maximum strlen for each data column * @param {object} oSettings dataTables settings object @@ -3863,13 +3783,13 @@ */ function _fnGetMaxLenString( oSettings, iCol ) { - var iMax = -1; - var iMaxIndex = -1; + var s, iMax=-1, iMaxIndex = -1; for ( var i=0 ; i/g, "" ); + s = _fnGetCellData( oSettings, i, iCol, 'display' )+''; + s = s.replace( __re_html_remove, '' ); + if ( s.length > iMax ) { iMax = s.length; @@ -3959,6 +3879,40 @@ return DataTable.__scrollbarWidth; } + + + function _fnSortFlatten ( settings ) + { + var + i, iLen, k, kLen, + aSort = [], + aiOrig = [], + aoColumns = settings.aoColumns, + aDataSort, iCol, sType, + nestedSort = settings.aaSortingFixed.concat( settings.aaSorting ); + + for ( i=0 ; iy ? 1 : 0; - if ( test !== 0 ) - { + if ( test !== 0 ) { return sort.dir === 'asc' ? test : -test; } } - + x = aiOrig[a]; y = aiOrig[b]; return xy ? 1 : 0; @@ -4123,191 +4010,172 @@ // 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. - oSettings.aiDisplayMaster.sort( function ( a, b ) { + displayMaster.sort( function ( a, b ) { var x, y, k, l, test, sort, len=aSort.length, dataA = aoData[a]._aSortData, dataB = aoData[b]._aSortData; - for ( k=0 ; ky ? 1 : 0; } ); } } - + /* Alter the sorting classes to take account of the changes */ if ( (bApplyClasses === undefined || bApplyClasses) && !oSettings.oFeatures.bDeferRender ) { _fnSortingClasses( oSettings ); } - for ( i=0, iLen=oSettings.aoColumns.length ; i/g, "" ); - nTh = aoColumns[i].nTh; - nTh.removeAttribute('aria-sort'); - nTh.removeAttribute('aria-label'); - - /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ - if ( aoColumns[i].bSortable ) - { - if ( aSort.length > 0 && aSort[0].col == i ) - { - nTh.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" ); - - var nextSort = (aoColumns[i].asSorting[ aSort[0].index+1 ]) ? - aoColumns[i].asSorting[ aSort[0].index+1 ] : aoColumns[i].asSorting[0]; - nTh.setAttribute('aria-label', sTitle+ - (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - else - { - nTh.setAttribute('aria-label', sTitle+ - (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - } - else - { - nTh.setAttribute('aria-label', sTitle); - } - } - + _fnSortAria( oSettings ); + /* Tell the draw function that we have sorted the data */ oSettings.bSorted = true; $(oSettings.oInstance).trigger('sort', oSettings); } + function _fnSortAria ( settings ) + { + var label; + var nextSort; + var columns = settings.aoColumns; + var aSort = _fnSortFlatten( settings ); + var oAria = settings.oLanguage.oAria; + + // ARIA attributes - need to loop all columns, to update all (removing old + // attributes as needed) + for ( var i=0, iLen=columns.length ; i/g, "" ); + var jqTh = $(col.nTh).removeAttr('aria-sort'); + + /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ + if ( col.bSortable ) { + if ( aSort.length > 0 && aSort[0].col == i ) { + jqTh.attr('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" ); + nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0]; + } + else { + nextSort = asSorting[0]; + } + + label = sTitle + ( nextSort === "asc" ? + oAria.sSortAscending : + oAria.sSortDescending + ); + } + else { + label = sTitle; + } + + jqTh.attr('aria-label', label); + } + } + + /** * Attach a sort handler (click) to a node - * @param {object} oSettings dataTables settings object - * @param {node} nNode node to attach the handler to - * @param {int} iDataIndex column sorting index - * @param {function} [fnCallback] callback function + * @param {object} settings dataTables settings object + * @param {node} attachTo node to attach the handler to + * @param {int} colIdx column sorting index + * @param {function} [callback] callback function * @memberof DataTable#oApi */ - function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) + function _fnSortAttachListener ( settings, attachTo, colIdx, callback ) { - _fnBindAction( nNode, {}, function (e) { + var col = settings.aoColumns[ colIdx ]; + var sorting = settings.aaSorting; + var asSorting = col.asSorting; + + _fnBindAction( attachTo, {}, function (e) { /* If the column is not sortable - don't to anything */ - if ( oSettings.aoColumns[iDataIndex].bSortable === false ) - { + if ( col.bSortable === false ) { return; } - - /* - * This is a little bit odd I admit... I declare a temporary function inside the scope of - * _fnBuildHead and the click handler in order that the code presented here can be used - * twice - once for when bProcessing is enabled, and another time for when it is - * disabled, as we need to perform slightly different actions. - * Basically the issue here is that the Javascript engine in modern browsers don't - * appear to allow the rendering engine to update the display while it is still executing - * it's thread (well - it does but only after long intervals). This means that the - * 'processing' display doesn't appear for a table sort. To break the js thread up a bit - * I force an execution break by using setTimeout - but this breaks the expected - * thread continuation for the end-developer's point of view (their code would execute - * too early), so we only do it when we absolutely have to. - */ - var fnInnerSorting = function () { - var iColumn, iNextSort; - - /* If the shift key is pressed then we are multiple column sorting */ - if ( e.shiftKey ) - { - /* Are we already doing some kind of sort on this column? */ - var bFound = false; - for ( var i=0 ; i 0 && sCurrentClass.indexOf(sNewClass) == -1 ) - { - /* We need to add a class */ - nTds[i].className = sCurrentClass + " " + sNewClass; - } + + if ( ! row._aSortData[idx] || customSort ) { + cellData = customSort ? + customData : // If there was a custom sort function, use data from there + _fnGetCellData( settings, i, idx, 'sort' ); + + row._aSortData[ idx ] = formatter ? + formatter( cellData ) : + cellData; } } } @@ -4478,8 +4316,7 @@ var i, iLen, bInfinite=oSettings.oScroll.bInfinite; var oState = { "iCreate": new Date().getTime(), - "iStart": (bInfinite ? 0 : oSettings._iDisplayStart), - "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd), + "iStart": bInfinite ? 0 : oSettings._iDisplayStart, "iLength": oSettings._iDisplayLength, "aaSorting": $.extend( true, [], oSettings.aaSorting ), "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ), @@ -4537,7 +4374,6 @@ /* Restore key features */ oSettings._iDisplayStart = oData.iStart; oSettings.iInitDisplayStart = oData.iStart; - oSettings._iDisplayEnd = oData.iEnd; oSettings._iDisplayLength = oData.iLength; oSettings.aaSorting = oData.aaSorting.slice(); oSettings.saved_aaSorting = oData.aaSorting.slice(); @@ -4582,88 +4418,6 @@ } - /** - * Return an array with the TR nodes for the table - * @param {object} oSettings dataTables settings object - * @returns {array} TR array - * @memberof DataTable#oApi - */ - function _fnGetTrNodes ( oSettings ) - { - var aNodes = []; - var aoData = oSettings.aoData; - for ( var i=0, iLen=aoData.length ; i=0 ; i-- ) - { - aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); + if ( callbackArr ) { + ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) { + return val.fn.apply( settings.oInstance, args ); + } ); } - if ( sTrigger !== null ) - { - $(oSettings.oInstance).trigger(sTrigger, aArgs); + if ( event !== null ) { + $(settings.oInstance).trigger(event, args); } - return aRet; + return ret; } + + function _fnLengthOverflow ( settings ) + { + var + start = settings._iDisplayStart, + end = settings.fnDisplayEnd(), + len = settings._iDisplayLength; + + /* If we have space to show extra rows (backing up from the end point - then do so */ + if ( end === settings.fnRecordsDisplay() ) + { + start = end - len; + } + + if ( len === -1 || start < 0 ) + { + start = 0; + } + + settings._iDisplayStart = start; + } DataTable = function( oInit ) { @@ -4874,94 +4648,7 @@ */ this.$ = function ( sSelector, oOpts ) { - var i, iLen, a = [], tr; - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var aoData = oSettings.aoData; - var aiDisplay = oSettings.aiDisplay; - var aiDisplayMaster = oSettings.aiDisplayMaster; - - if ( !oOpts ) - { - oOpts = {}; - } - - oOpts = $.extend( {}, { - "filter": "none", // applied - "order": "current", // "original" - "page": "all" // current - }, oOpts ); - - // Current page implies that order=current and fitler=applied, since it is fairly - // senseless otherwise - if ( oOpts.page == 'current' ) - { - for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i *
  • 1D array of data - add a single row with the data provided
  • *
  • 2D array of arrays - add multiple rows in a single call
  • *
  • object - data object when using mData
  • *
  • array of objects - multiple data objects when using mData
  • * - * @param {bool} [bRedraw=true] redraw the table or not + * @param {bool} [redraw=true] redraw the table or not * @returns {array} An array of integers, representing the list of indexes in * aoData ({@link DataTable.models.oSettings}) that have been added to * the table. * @dtopt API + * @deprecated Since v1.10 * * @example * // Global var for counter @@ -5074,49 +4763,20 @@ * giCount++; * } */ - this.fnAddData = function( mData, bRedraw ) + this.fnAddData = function( data, redraw ) { - if ( mData.length === 0 ) - { - return []; - } - - var aiReturn = []; - var iTest; - - /* Find settings from table node */ - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - + var api = this.api( true ); + /* Check if we want to add multiple rows or not */ - if ( typeof mData[0] === "object" && mData[0] !== null ) - { - for ( var i=0 ; i= oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart -= oSettings._iDisplayLength; - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - - if ( bRedraw === undefined || bRedraw ) - { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - - return oData; + + return data; }; /** * Restore the table to it's original state in the DOM by removing all of DataTables * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [bRemove=false] Completely remove the table from the DOM + * @param {boolean} [remove=false] Completely remove the table from the DOM * @dtopt API + * @deprecated Since v1.10 * * @example * $(document).ready(function() { @@ -5314,138 +4923,17 @@ * oTable.fnDestroy(); * } ); */ - this.fnDestroy = function ( bRemove ) + this.fnDestroy = function ( remove ) { - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var nOrig = oSettings.nTableWrapper.parentNode; - var nBody = oSettings.nTBody; - var i, iLen; - - bRemove = (bRemove===undefined) ? false : bRemove; - - /* Flag to note that the table is currently being destroyed - no action should be taken */ - oSettings.bDestroying = true; - - /* Fire off the destroy callbacks for plug-ins etc */ - _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); - - /* If the table is not being removed, restore the hidden columns */ - if ( !bRemove ) - { - for ( i=0, iLen=oSettings.aoColumns.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove(); - - /* When scrolling we had to break the table up - restore it */ - if ( oSettings.nTable != oSettings.nTHead.parentNode ) - { - $(oSettings.nTable).children('thead').remove(); - oSettings.nTable.appendChild( oSettings.nTHead ); - } - - if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode ) - { - $(oSettings.nTable).children('tfoot').remove(); - oSettings.nTable.appendChild( oSettings.nTFoot ); - } - - /* Remove the DataTables generated nodes, events and classes */ - oSettings.nTable.parentNode.removeChild( oSettings.nTable ); - $(oSettings.nTableWrapper).remove(); - - oSettings.aaSorting = []; - oSettings.aaSortingFixed = []; - _fnSortingClasses( oSettings ); - - $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') ); - - $('th, td', oSettings.nTHead).removeClass( [ - oSettings.oClasses.sSortable, - oSettings.oClasses.sSortableAsc, - oSettings.oClasses.sSortableDesc, - oSettings.oClasses.sSortableNone ].join(' ') - ); - if ( oSettings.bJUI ) - { - $('th span.'+oSettings.oClasses.sSortIcon - + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove(); - - $('th, td', oSettings.nTHead).each( function () { - var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this); - var kids = jqWrapper.contents(); - $(this).append( kids ); - jqWrapper.remove(); - } ); - } - - /* Add the TR elements back into the table in their original order */ - if ( !bRemove && oSettings.nTableReinsertBefore ) - { - nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore ); - } - else if ( !bRemove ) - { - nOrig.appendChild( oSettings.nTable ); - } - - for ( i=0, iLen=oSettings.aoData.length ; i