CC-3735 : Now Playing: Browser(Firefox) Mem usage goes high when play a show with hundreds of songs more than 3 hours

updating datatables to stable 1.9.1 release.

optimizing javascript, using jquery to add/remove nodes to avoid JQuery.cache issues.
This commit is contained in:
Naomi Aro 2012-05-03 15:04:23 +02:00
parent 08d939d736
commit c2c6e1b114
2 changed files with 399 additions and 184 deletions

View file

@ -144,34 +144,33 @@ var AIRTIME = (function(AIRTIME){
mod.checkToolBarIcons(); mod.checkToolBarIcons();
}; };
mod.fnItemCallback = function(json) {
checkError(json);
oSchedTable.fnDraw();
};
mod.fnAdd = function(aMediaIds, aSchedIds) { mod.fnAdd = function(aMediaIds, aSchedIds) {
$.post("/showbuilder/schedule-add", $.post("/showbuilder/schedule-add",
{"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds}, {"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds},
function(json){ mod.fnItemCallback
checkError(json); );
oSchedTable.fnDraw();
});
}; };
mod.fnMove = function(aSelect, aAfter) { mod.fnMove = function(aSelect, aAfter) {
$.post("/showbuilder/schedule-move", $.post("/showbuilder/schedule-move",
{"format": "json", "selectedItem": aSelect, "afterItem": aAfter}, {"format": "json", "selectedItem": aSelect, "afterItem": aAfter},
function(json){ mod.fnItemCallback
checkError(json); );
oSchedTable.fnDraw();
});
}; };
mod.fnRemove = function(aItems) { mod.fnRemove = function(aItems) {
$.post( "/showbuilder/schedule-remove", $.post( "/showbuilder/schedule-remove",
{"items": aItems, "format": "json"}, {"items": aItems, "format": "json"},
function(json) { mod.fnItemCallback
checkError(json); );
oSchedTable.fnDraw();
});
}; };
mod.fnRemoveSelectedItems = function() { mod.fnRemoveSelectedItems = function() {
@ -189,10 +188,10 @@ var AIRTIME = (function(AIRTIME){
mod.fnRemove(aItems); mod.fnRemove(aItems);
}; };
mod.fnServerData = function ( sSource, aoData, fnCallback ) { mod.fnServerData = function fnBuilderServerData( sSource, aoData, fnCallback ) {
aoData.push( { name: "timestamp", value: AIRTIME.showbuilder.getTimestamp()} ); aoData.push( { name: "timestamp", value: mod.getTimestamp()} );
aoData.push( { name: "instances", value: AIRTIME.showbuilder.getShowInstances()} ); aoData.push( { name: "instances", value: mod.getShowInstances()} );
aoData.push( { name: "format", value: "json"} ); aoData.push( { name: "format", value: "json"} );
if (mod.fnServerData.hasOwnProperty("start")) { if (mod.fnServerData.hasOwnProperty("start")) {
@ -212,8 +211,8 @@ var AIRTIME = (function(AIRTIME){
"url": sSource, "url": sSource,
"data": aoData, "data": aoData,
"success": function(json) { "success": function(json) {
AIRTIME.showbuilder.setTimestamp(json.timestamp); mod.setTimestamp(json.timestamp);
AIRTIME.showbuilder.setShowInstances(json.instances); mod.setShowInstances(json.instances);
fnCallback(json); fnCallback(json);
} }
}); });
@ -295,12 +294,12 @@ var AIRTIME = (function(AIRTIME){
oData.iCreate = parseInt(oData.iCreate, 10); oData.iCreate = parseInt(oData.iCreate, 10);
}, },
"fnServerData": AIRTIME.showbuilder.fnServerData, "fnServerData": mod.fnServerData,
"fnRowCallback": function fnRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { "fnRowCallback": function fnRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var i, var i, length,
sSeparatorHTML, sSeparatorHTML,
fnPrepareSeparatorRow, fnPrepareSeparatorRow,
node, $node,
cl="", cl="",
//background-color to imitate calendar color. //background-color to imitate calendar color.
r,g,b,a, r,g,b,a,
@ -310,37 +309,37 @@ var AIRTIME = (function(AIRTIME){
fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) { fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) {
node = nRow.children[iNodeIndex]; $node = $(nRow.children[iNodeIndex]);
node.innerHTML = sRowContent; $node.html(sRowContent);
node.setAttribute('colspan',100); $node.attr('colspan',100);
for (i = iNodeIndex + 1; i < nRow.children.length; i = i+1) { for (i = iNodeIndex + 1, length = nRow.children.length; i < length; i = i+1) {
node = nRow.children[i]; $node = $(nRow.children[i]);
node.innerHTML = ""; $node.html("");
node.setAttribute("style", "display : none"); $node.attr("style", "display : none");
} }
$(nRow).addClass(sClass); $nRow.addClass(sClass);
}; };
if (aData.header === true) { if (aData.header === true) {
//remove the column classes from all tds. //remove the column classes from all tds.
$(nRow).find('td').removeClass(); $nRow.find('td').removeClass();
node = nRow.children[0]; $node = $(nRow.children[0]);
node.innerHTML = ''; $node.html("");
cl = 'sb-header'; cl = 'sb-header';
if (aData.record === true) { if (aData.record === true) {
$div = $("<div/>", { $div = $("<div/>", {
"class": "small-icon recording" "class": "small-icon recording"
}); });
$(node).append($div); $node.append($div);
} }
else if (aData.rebroadcast === true) { else if (aData.rebroadcast === true) {
$div = $("<div/>", { $div = $("<div/>", {
"class": "small-icon rebroadcast" "class": "small-icon rebroadcast"
}); });
$(node).append($div); $node.append($div);
} }
sSeparatorHTML = '<span class="show-title">'+aData.title+'</span>'; sSeparatorHTML = '<span class="show-title">'+aData.title+'</span>';
@ -366,18 +365,18 @@ var AIRTIME = (function(AIRTIME){
} }
else if (aData.footer === true) { else if (aData.footer === true) {
//remove the column classes from all tds. //remove the column classes from all tds.
$(nRow).find('td').removeClass(); $nRow.find('td').removeClass();
node = nRow.children[0]; $node = $(nRow.children[0]);
cl = 'sb-footer'; cl = 'sb-footer';
//check the show's content status. //check the show's content status.
if (aData.runtime > 0) { if (aData.runtime > 0) {
node.innerHTML = '<span class="ui-icon ui-icon-check"></span>'; $node.html('<span class="ui-icon ui-icon-check"></span>');
cl = cl + ' ui-state-highlight'; cl = cl + ' ui-state-highlight';
} }
else { else {
node.innerHTML = '<span class="ui-icon ui-icon-notice"></span>'; $node.html('<span class="ui-icon ui-icon-notice"></span>');
cl = cl + ' ui-state-error'; cl = cl + ' ui-state-error';
} }
@ -386,10 +385,10 @@ var AIRTIME = (function(AIRTIME){
} }
else if (aData.empty === true) { else if (aData.empty === true) {
//remove the column classes from all tds. //remove the column classes from all tds.
$(nRow).find('td').removeClass(); $nRow.find('td').removeClass();
node = nRow.children[0]; $node = $(nRow.children[0]);
node.innerHTML = ''; $node.html('');
sSeparatorHTML = '<span>Show Empty</span>'; sSeparatorHTML = '<span>Show Empty</span>';
cl = cl + " sb-empty odd"; cl = cl + " sb-empty odd";
@ -398,10 +397,10 @@ var AIRTIME = (function(AIRTIME){
} }
else if (aData.record === true) { else if (aData.record === true) {
//remove the column classes from all tds. //remove the column classes from all tds.
$(nRow).find('td').removeClass(); $nRow.find('td').removeClass();
node = nRow.children[0]; $node = $(nRow.children[0]);
node.innerHTML = ''; $node.html('');
sSeparatorHTML = '<span>Recording From Line In</span>'; sSeparatorHTML = '<span>Recording From Line In</span>';
cl = cl + " sb-record odd"; cl = cl + " sb-record odd";
@ -411,7 +410,7 @@ var AIRTIME = (function(AIRTIME){
else { else {
//add the play function if the file exists on disk. //add the play function if the file exists on disk.
$image = $(nRow).find('td.sb-image'); $image = $nRow.find('td.sb-image');
//check if the file exists. //check if the file exists.
if (aData.image === true) { if (aData.image === true) {
$image.html('<img title="Track preview" src="/css/images/icon_audioclip.png"></img>') $image.html('<img title="Track preview" src="/css/images/icon_audioclip.png"></img>')
@ -424,12 +423,12 @@ var AIRTIME = (function(AIRTIME){
$image.html('<span class="ui-icon ui-icon-alert"></span>'); $image.html('<span class="ui-icon ui-icon-alert"></span>');
} }
node = nRow.children[0]; $node = $(nRow.children[0]);
if (aData.allowed === true && aData.scheduled >= 1) { if (aData.allowed === true && aData.scheduled >= 1) {
node.innerHTML = '<input type="checkbox" name="'+aData.id+'"></input>'; $node.html('<input type="checkbox" name="'+aData.id+'"></input>');
} }
else { else {
node.innerHTML = ''; $node.html('');
} }
} }
@ -455,39 +454,39 @@ var AIRTIME = (function(AIRTIME){
} }
//save some info for reordering purposes. //save some info for reordering purposes.
$(nRow).data({"aData": aData}); $nRow.data({"aData": aData});
if (aData.scheduled === 1) { if (aData.scheduled === 1) {
$(nRow).addClass("sb-now-playing"); $nRow.addClass("sb-now-playing");
} }
else if (aData.scheduled === 0) { else if (aData.scheduled === 0) {
$(nRow).addClass("sb-past"); $nRow.addClass("sb-past");
} }
else { else {
$(nRow).addClass("sb-future"); $nRow.addClass("sb-future");
} }
if (aData.allowed !== true) { if (aData.allowed !== true) {
$(nRow).addClass("sb-not-allowed"); $nRow.addClass("sb-not-allowed");
} }
else { else {
$(nRow).addClass("sb-allowed"); $nRow.addClass("sb-allowed");
} }
//status used to colour tracks. //status used to colour tracks.
if (aData.status === 2) { if (aData.status === 2) {
$(nRow).addClass("sb-boundry"); $nRow.addClass("sb-boundry");
} }
else if (aData.status === 0) { else if (aData.status === 0) {
$(nRow).addClass("sb-over"); $nRow.addClass("sb-over");
} }
if (aData.currentShow === true) { if (aData.currentShow === true) {
$(nRow).addClass("sb-current-show"); $nRow.addClass("sb-current-show");
} }
//call the context menu so we can prevent the event from propagating. //call the context menu so we can prevent the event from propagating.
$(nRow).find('td:gt(1)').click(function(e){ $nRow.find('td:gt(1)').click(function(e){
$(this).contextMenu({x: e.pageX, y: e.pageY}); $(this).contextMenu({x: e.pageX, y: e.pageY});
@ -513,7 +512,7 @@ var AIRTIME = (function(AIRTIME){
//use this array to cache DOM heights then we can detach the table to manipulate it to increase speed. //use this array to cache DOM heights then we can detach the table to manipulate it to increase speed.
heights = []; heights = [];
clearTimeout(AIRTIME.showbuilder.timeout); clearTimeout(mod.timeout);
//only create the cursor arrows if the library is on the page. //only create the cursor arrows if the library is on the page.
if ($lib.length > 0 && $lib.filter(":visible").length > 0) { if ($lib.length > 0 && $lib.filter(":visible").length > 0) {
@ -574,7 +573,7 @@ var AIRTIME = (function(AIRTIME){
if (temp.length > 0) { if (temp.length > 0) {
aData = temp.data("aData"); aData = temp.data("aData");
setTimeout(mod.refresh, aData.refresh * 1000); //need refresh in milliseconds mod.timeout = setTimeout(mod.refresh, aData.refresh * 1000); //need refresh in milliseconds
break; break;
} }
} }
@ -646,7 +645,7 @@ var AIRTIME = (function(AIRTIME){
} }
aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp}); aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp});
AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds); mod.fnAdd(aMediaIds, aSchedIds);
}; };
fnMove = function() { fnMove = function() {
@ -659,7 +658,7 @@ var AIRTIME = (function(AIRTIME){
aAfter.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp}); aAfter.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp});
AIRTIME.showbuilder.fnMove(aSelect, aAfter); mod.fnMove(aSelect, aAfter);
}; };
fnReceive = function(event, ui) { fnReceive = function(event, ui) {

View file

@ -1,7 +1,7 @@
/** /**
* @summary DataTables * @summary DataTables
* @description Paginate, search and sort HTML tables * @description Paginate, search and sort HTML tables
* @version 1.9.1.dev * @version 1.9.1
* @file jquery.dataTables.js * @file jquery.dataTables.js
* @author Allan Jardine (www.sprymedia.co.uk) * @author Allan Jardine (www.sprymedia.co.uk)
* @contact www.sprymedia.co.uk/contact * @contact www.sprymedia.co.uk/contact
@ -21,7 +21,7 @@
*/ */
/*jslint evil: true, undef: true, browser: true */ /*jslint evil: true, undef: true, browser: true */
/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_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,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex*/ /*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_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,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/
(/** @lends <global> */function($, window, document, undefined) { (/** @lends <global> */function($, window, document, undefined) {
/** /**
@ -445,9 +445,8 @@
/* Create the object for storing information about this new row */ /* Create the object for storing information about this new row */
var iRow = oSettings.aoData.length; var iRow = oSettings.aoData.length;
var oData = $.extend( true, {}, DataTable.models.oRow, { var oData = $.extend( true, {}, DataTable.models.oRow );
"_aData": aDataIn oData._aData = aDataIn;
} );
oSettings.aoData.push( oData ); oSettings.aoData.push( oData );
/* Create the cells */ /* Create the cells */
@ -461,6 +460,10 @@
{ {
_fnSetCellData( oSettings, iRow, i, _fnRender(oSettings, iRow, i) ); _fnSetCellData( oSettings, iRow, i, _fnRender(oSettings, iRow, i) );
} }
else
{
_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
}
/* See if we should auto-detect the column type */ /* See if we should auto-detect the column type */
if ( oCol._bAutoType && oCol.sType != 'string' ) if ( oCol._bAutoType && oCol.sType != 'string' )
@ -738,8 +741,9 @@
{ {
if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null ) if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null )
{ {
_fnLog( oSettings, 0, "Requested unknown parameter '"+oCol.mDataProp+ _fnLog( oSettings, 0, "Requested unknown parameter "+
"' from the data source for row "+iRow ); (typeof oCol.mDataProp=='function' ? '{mDataprop function}' : "'"+oCol.mDataProp+"'")+
" from the data source for row "+iRow );
oSettings.iDrawError = oSettings.iDraw; oSettings.iDrawError = oSettings.iDraw;
} }
return oCol.sDefaultContent; return oCol.sDefaultContent;
@ -862,6 +866,10 @@
for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
{ {
data = data[ a[i] ]; data = data[ a[i] ];
if ( data === undefined )
{
return;
}
} }
data[ a[a.length-1] ] = val; data[ a[a.length-1] ] = val;
}; };
@ -996,7 +1004,7 @@
for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
{ {
var oCol = oSettings.aoColumns[i]; var oCol = oSettings.aoColumns[i];
nTd = document.createElement('td'); nTd = document.createElement( oCol.sCellType );
/* Render if needed - if bUseRendered is true then we already have the rendered /* Render if needed - if bUseRendered is true then we already have the rendered
* value in the data source - so can just use that * value in the data source - so can just use that
@ -1372,22 +1380,22 @@
anRows[ 0 ].className = oSettings.asStripeClasses[0]; anRows[ 0 ].className = oSettings.asStripeClasses[0];
} }
var sZero = oSettings.oLanguage.sZeroRecords.replace( var oLang = oSettings.oLanguage;
'_MAX_', oSettings.fnFormatNumber(oSettings.fnRecordsTotal()) ); var sZero = oLang.sZeroRecords;
if ( oSettings.iDraw == 1 && oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide ) if ( oSettings.iDraw == 1 && oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
{ {
sZero = oSettings.oLanguage.sLoadingRecords; sZero = oLang.sLoadingRecords;
} }
else if ( oSettings.oLanguage.sEmptyTable && oSettings.fnRecordsTotal() === 0 ) else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
{ {
sZero = oSettings.oLanguage.sEmptyTable; sZero = oLang.sEmptyTable;
} }
var nTd = document.createElement( 'td' ); var nTd = document.createElement( 'td' );
nTd.setAttribute( 'valign', "top" ); nTd.setAttribute( 'valign', "top" );
nTd.colSpan = _fnVisbleColumns( oSettings ); nTd.colSpan = _fnVisbleColumns( oSettings );
nTd.className = oSettings.oClasses.sRowEmpty; nTd.className = oSettings.oClasses.sRowEmpty;
nTd.innerHTML = sZero; nTd.innerHTML = _fnInfoMacros( oSettings, sZero );
anRows[ iRowCount ].appendChild( nTd ); anRows[ iRowCount ].appendChild( nTd );
} }
@ -1968,19 +1976,21 @@
jqFilter.bind( 'keyup.DT', function(e) { jqFilter.bind( 'keyup.DT', function(e) {
/* Update all other filter input elements for the new display */ /* Update all other filter input elements for the new display */
var n = oSettings.aanFeatures.f; var n = oSettings.aanFeatures.f;
var val = this.value==="" ? "" : this.value; // mental IE8 fix :-(
for ( var i=0, iLen=n.length ; i<iLen ; i++ ) for ( var i=0, iLen=n.length ; i<iLen ; i++ )
{ {
if ( n[i] != $(this).parents('div.dataTables_filter')[0] ) if ( n[i] != $(this).parents('div.dataTables_filter')[0] )
{ {
$(n[i]._DT_Input).val( this.value ); $(n[i]._DT_Input).val( val );
} }
} }
/* Now do the filter */ /* Now do the filter */
if ( this.value != oPreviousSearch.sSearch ) if ( val != oPreviousSearch.sSearch )
{ {
_fnFilterComplete( oSettings, { _fnFilterComplete( oSettings, {
"sSearch": this.value, "sSearch": val,
"bRegex": oPreviousSearch.bRegex, "bRegex": oPreviousSearch.bRegex,
"bSmart": oPreviousSearch.bSmart , "bSmart": oPreviousSearch.bSmart ,
"bCaseInsensitive": oPreviousSearch.bCaseInsensitive "bCaseInsensitive": oPreviousSearch.bCaseInsensitive
@ -2307,6 +2317,10 @@
{ {
return DataTable.ext.ofnSearch[sType]( sData ); return DataTable.ext.ofnSearch[sType]( sData );
} }
else if ( sData === null )
{
return '';
}
else if ( sType == "html" ) else if ( sType == "html" )
{ {
return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" );
@ -2315,10 +2329,6 @@
{ {
return sData.replace(/[\r\n]/g," "); return sData.replace(/[\r\n]/g," ");
} }
else if ( sData === null )
{
return '';
}
return sData; return sData;
} }
@ -2381,57 +2391,41 @@
} }
var var
iStart = oSettings._iDisplayStart+1, iEnd = oSettings.fnDisplayEnd(), oLang = oSettings.oLanguage,
iMax = oSettings.fnRecordsTotal(), iTotal = oSettings.fnRecordsDisplay(), iStart = oSettings._iDisplayStart+1,
sStart = oSettings.fnFormatNumber( iStart ), sEnd = oSettings.fnFormatNumber( iEnd ), iEnd = oSettings.fnDisplayEnd(),
sMax = oSettings.fnFormatNumber( iMax ), sTotal = oSettings.fnFormatNumber( iTotal ), iMax = oSettings.fnRecordsTotal(),
iTotal = oSettings.fnRecordsDisplay(),
sOut; sOut;
/* When infinite scrolling, we are always starting at 1. _iDisplayStart is used only if ( iTotal === 0 && iTotal == iMax )
* internally
*/
if ( oSettings.oScroll.bInfinite )
{
sStart = oSettings.fnFormatNumber( 1 );
}
if ( oSettings.fnRecordsDisplay() === 0 &&
oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
{ {
/* Empty record set */ /* Empty record set */
sOut = oSettings.oLanguage.sInfoEmpty+ oSettings.oLanguage.sInfoPostFix; sOut = oLang.sInfoEmpty;
} }
else if ( oSettings.fnRecordsDisplay() === 0 ) else if ( iTotal === 0 )
{ {
/* Rmpty record set after filtering */ /* Empty record set after filtering */
sOut = oSettings.oLanguage.sInfoEmpty +' '+ sOut = oLang.sInfoEmpty +' '+ oLang.sInfoFiltered;
oSettings.oLanguage.sInfoFiltered.replace('_MAX_', sMax)+
oSettings.oLanguage.sInfoPostFix;
} }
else if ( oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() ) else if ( iTotal == iMax )
{ {
/* Normal record set */ /* Normal record set */
sOut = oSettings.oLanguage.sInfo. sOut = oLang.sInfo;
replace('_START_', sStart).
replace('_END_', sEnd).
replace('_TOTAL_', sTotal)+
oSettings.oLanguage.sInfoPostFix;
} }
else else
{ {
/* Record set after filtering */ /* Record set after filtering */
sOut = oSettings.oLanguage.sInfo. sOut = oLang.sInfo +' '+ oLang.sInfoFiltered;
replace('_START_', sStart).
replace('_END_', sEnd).
replace('_TOTAL_', sTotal) +' '+
oSettings.oLanguage.sInfoFiltered.replace('_MAX_',
oSettings.fnFormatNumber(oSettings.fnRecordsTotal()))+
oSettings.oLanguage.sInfoPostFix;
} }
if ( oSettings.oLanguage.fnInfoCallback !== null ) // Convert the macros
sOut += oLang.sInfoPostFix;
sOut = _fnInfoMacros( oSettings, sOut );
if ( oLang.fnInfoCallback !== null )
{ {
sOut = oSettings.oLanguage.fnInfoCallback.call( oSettings.oInstance, sOut = oLang.fnInfoCallback.call( oSettings.oInstance,
oSettings, iStart, iEnd, iMax, iTotal, sOut ); oSettings, iStart, iEnd, iMax, iTotal, sOut );
} }
@ -2443,6 +2437,33 @@
} }
function _fnInfoMacros ( oSettings, str )
{
var
iStart = oSettings._iDisplayStart+1,
sStart = oSettings.fnFormatNumber( iStart ),
iEnd = oSettings.fnDisplayEnd(),
sEnd = oSettings.fnFormatNumber( iEnd ),
iTotal = oSettings.fnRecordsDisplay(),
sTotal = oSettings.fnFormatNumber( iTotal ),
iMax = oSettings.fnRecordsTotal(),
sMax = oSettings.fnFormatNumber( iMax );
// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
// internally
if ( oSettings.oScroll.bInfinite )
{
sStart = oSettings.fnFormatNumber( 1 );
}
return str.
replace('_START_', sStart).
replace('_END_', sEnd).
replace('_TOTAL_', sTotal).
replace('_MAX_', sMax);
}
/** /**
* Draw the table for the first time, adding all required features * Draw the table for the first time, adding all required features
@ -2576,16 +2597,20 @@
*/ */
function _fnLanguageCompat( oLanguage ) function _fnLanguageCompat( oLanguage )
{ {
var oDefaults = DataTable.defaults.oLanguage;
/* Backwards compatibility - if there is no sEmptyTable given, then use the same as /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
* sZeroRecords - assuming that is given. * sZeroRecords - assuming that is given.
*/ */
if ( !oLanguage.sEmptyTable && oLanguage.sZeroRecords ) if ( !oLanguage.sEmptyTable && oLanguage.sZeroRecords &&
oDefaults.sEmptyTable === "No data available in table" )
{ {
_fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sEmptyTable' ); _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sEmptyTable' );
} }
/* Likewise with loading records */ /* Likewise with loading records */
if ( !oLanguage.sLoadingRecords && oLanguage.sZeroRecords ) if ( !oLanguage.sLoadingRecords && oLanguage.sZeroRecords &&
oDefaults.sLoadingRecords === "Loading..." )
{ {
_fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sLoadingRecords' ); _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sLoadingRecords' );
} }
@ -2954,7 +2979,8 @@
nScrollHead.style.border = "0"; nScrollHead.style.border = "0";
nScrollHead.style.width = "100%"; nScrollHead.style.width = "100%";
nScrollFoot.style.border = "0"; nScrollFoot.style.border = "0";
nScrollHeadInner.style.width = "150%"; /* will be overwritten */ nScrollHeadInner.style.width = oSettings.oScroll.sXInner !== "" ?
oSettings.oScroll.sXInner : "100%"; /* will be overwritten */
/* Modify attributes to respect the clones */ /* Modify attributes to respect the clones */
nScrollHeadTable.removeAttribute('id'); nScrollHeadTable.removeAttribute('id');
@ -2966,11 +2992,20 @@
nScrollFootTable.style.marginLeft = "0"; nScrollFootTable.style.marginLeft = "0";
} }
/* Move any caption elements from the body to the header */ /* Move caption elements from the body to the header, footer or leave where it is
var nCaptions = $(oSettings.nTable).children('caption'); * depending on the configuration. Note that the DTD says there can be only one caption */
for ( var i=0, iLen=nCaptions.length ; i<iLen ; i++ ) var nCaption = $(oSettings.nTable).children('caption');
if ( nCaption.length > 0 )
{ {
nScrollHeadTable.appendChild( nCaptions[i] ); nCaption = nCaption[0];
if ( nCaption._captionSide === "top" )
{
nScrollHeadTable.appendChild( nCaption );
}
else if ( nCaption._captionSide === "bottom" && nTfoot )
{
nScrollFootTable.appendChild( nCaption );
}
} }
/* /*
@ -3072,12 +3107,12 @@
$(o.nTable).children('thead, tfoot').remove(); $(o.nTable).children('thead, tfoot').remove();
/* Clone the current header and footer elements and then place it into the inner table */ /* Clone the current header and footer elements and then place it into the inner table */
nTheadSize = o.nTHead.cloneNode(true); nTheadSize = $(o.nTHead).clone()[0];
o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] );
if ( o.nTFoot !== null ) if ( o.nTFoot !== null )
{ {
nTfootSize = o.nTFoot.cloneNode(true); nTfootSize = $(o.nTFoot).clone()[0];
o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] );
} }
@ -3109,6 +3144,14 @@
}, nTfootSize.getElementsByTagName('tr') ); }, nTfootSize.getElementsByTagName('tr') );
} }
// If scroll collapse is enabled, when we put the headers back into the body for sizing, we
// will end up forcing the scrollbar to appear, making our measurements wrong for when we
// then hide it (end of this function), so add the header height to the body scroller.
if ( o.oScroll.bCollapse && o.oScroll.sY !== "" )
{
nScrollBody.style.height = (nScrollBody.offsetHeight + o.nTHead.offsetHeight)+"px";
}
/* Size the table as a whole */ /* Size the table as a whole */
iSanityWidth = $(o.nTable).outerWidth(); iSanityWidth = $(o.nTable).outerWidth();
if ( o.oScroll.sX === "" ) if ( o.oScroll.sX === "" )
@ -3292,7 +3335,7 @@
o.oScroll.iBarWidth : 0; o.oScroll.iBarWidth : 0;
if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) if ( o.nTable.offsetHeight < nScrollBody.offsetHeight )
{ {
nScrollBody.style.height = _fnStringToCss( $(o.nTable).height()+iExtra ); nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra );
} }
} }
@ -3796,7 +3839,9 @@
sDataType = oSettings.aoColumns[ iColumn ].sSortDataType; sDataType = oSettings.aoColumns[ iColumn ].sSortDataType;
if ( DataTable.ext.afnSortData[sDataType] ) if ( DataTable.ext.afnSortData[sDataType] )
{ {
var aData = DataTable.ext.afnSortData[sDataType]( oSettings, iColumn, iVisColumn ); var aData = DataTable.ext.afnSortData[sDataType].call(
oSettings.oInstance, oSettings, iColumn, iVisColumn
);
if ( aData.length === aoData.length ) if ( aData.length === aoData.length )
{ {
for ( j=0, jLen=aoData.length ; j<jLen ; j++ ) for ( j=0, jLen=aoData.length ; j<jLen ; j++ )
@ -3894,6 +3939,7 @@
for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
{ {
var sTitle = aoColumns[i].sTitle.replace( /<.*?>/g, "" );
nTh = aoColumns[i].nTh; nTh = aoColumns[i].nTh;
nTh.removeAttribute('aria-sort'); nTh.removeAttribute('aria-sort');
nTh.removeAttribute('aria-label'); nTh.removeAttribute('aria-label');
@ -3907,18 +3953,18 @@
var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ?
aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0];
nTh.setAttribute('aria-label', aoColumns[i].sTitle+ nTh.setAttribute('aria-label', sTitle+
(nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
} }
else else
{ {
nTh.setAttribute('aria-label', aoColumns[i].sTitle+ nTh.setAttribute('aria-label', sTitle+
(aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
} }
} }
else else
{ {
nTh.setAttribute('aria-label', aoColumns[i].sTitle); nTh.setAttribute('aria-label', sTitle);
} }
} }
@ -5194,10 +5240,8 @@
/* Flag to note that the table is currently being destroyed - no action should be taken */ /* Flag to note that the table is currently being destroyed - no action should be taken */
oSettings.bDestroying = true; oSettings.bDestroying = true;
/* Restore hidden columns */ /* Fire off the destroy callbacks for plug-ins etc */
for ( i=0, iLen=oSettings.aoDestroyCallback.length ; i<iLen ; i++ ) { _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] );
oSettings.aoDestroyCallback[i].fn();
}
/* Restore hidden columns */ /* Restore hidden columns */
for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
@ -5317,7 +5361,7 @@
this.fnDraw = function( bComplete ) this.fnDraw = function( bComplete )
{ {
var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
if ( bComplete ) if ( bComplete === false )
{ {
_fnCalculateEnd( oSettings ); _fnCalculateEnd( oSettings );
_fnDraw( oSettings ); _fnDraw( oSettings );
@ -5713,7 +5757,7 @@
var i, iLen; var i, iLen;
var aoColumns = oSettings.aoColumns; var aoColumns = oSettings.aoColumns;
var aoData = oSettings.aoData; var aoData = oSettings.aoData;
var nTd, nCell, anTrs, jqChildren, bAppend, iBefore; var nTd, bAppend, iBefore;
/* No point in doing anything if we are requesting what is already true */ /* No point in doing anything if we are requesting what is already true */
if ( aoColumns[iCol].bVisible == bShow ) if ( aoColumns[iCol].bVisible == bShow )
@ -5833,7 +5877,7 @@
/** /**
* Sort the table by a particular row * Sort the table by a particular column
* @param {int} iCol the data index to sort on. Note that this will not match the * @param {int} iCol the data index to sort on. Note that this will not match the
* 'display index' if you have hidden data entries * 'display index' if you have hidden data entries
* @dtopt API * @dtopt API
@ -5899,7 +5943,7 @@
this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
{ {
var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
var iVisibleColumn, i, iLen, sDisplay; var i, iLen, sDisplay;
var iRow = (typeof mRow === 'object') ? var iRow = (typeof mRow === 'object') ?
_fnNodeToDataIndex(oSettings, mRow) : mRow; _fnNodeToDataIndex(oSettings, mRow) : mRow;
@ -6105,7 +6149,8 @@
"_fnCallbackFire": _fnCallbackFire, "_fnCallbackFire": _fnCallbackFire,
"_fnJsonString": _fnJsonString, "_fnJsonString": _fnJsonString,
"_fnRender": _fnRender, "_fnRender": _fnRender,
"_fnNodeToColumnIndex": _fnNodeToColumnIndex "_fnNodeToColumnIndex": _fnNodeToColumnIndex,
"_fnInfoMacros": _fnInfoMacros
}; };
$.extend( DataTable.ext.oApi, this.oApi ); $.extend( DataTable.ext.oApi, this.oApi );
@ -6173,7 +6218,7 @@
} }
/* Ensure the table has an ID - required for accessibility */ /* Ensure the table has an ID - required for accessibility */
if ( sId === null ) if ( sId === null || sId === "" )
{ {
sId = "DataTables_Table_"+(DataTable.ext._oExternConfig.iNextUnique++); sId = "DataTables_Table_"+(DataTable.ext._oExternConfig.iNextUnique++);
this.id = sId; this.id = sId;
@ -6320,8 +6365,9 @@
if ( oInit.iDeferLoading !== null ) if ( oInit.iDeferLoading !== null )
{ {
oSettings.bDeferLoading = true; oSettings.bDeferLoading = true;
oSettings._iRecordsTotal = oInit.iDeferLoading; var tmp = $.isArray( oInit.iDeferLoading );
oSettings._iRecordsDisplay = oInit.iDeferLoading; oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
} }
if ( oInit.aaData !== null ) if ( oInit.aaData !== null )
@ -6353,6 +6399,13 @@
/* /*
* Stripes * Stripes
*/ */
if ( oInit.asStripeClasses === null )
{
oSettings.asStripeClasses =[
oSettings.oClasses.sStripeOdd,
oSettings.oClasses.sStripeEven
];
}
/* Remove row stripe classes if they are already on the table row */ /* Remove row stripe classes if they are already on the table row */
var bStripeRemove = false; var bStripeRemove = false;
@ -6485,6 +6538,12 @@
* Final init * Final init
* Cache the header, body and footer as required, creating them if needed * Cache the header, body and footer as required, creating them if needed
*/ */
// Work around for Webkit bug 83867 - store the caption-side before removing from doc
var captions = $(this).children('caption').each( function () {
this._captionSide = $(this).css('caption-side');
} );
var thead = $(this).children('thead'); var thead = $(this).children('thead');
if ( thead.length === 0 ) if ( thead.length === 0 )
{ {
@ -6505,6 +6564,14 @@
oSettings.nTBody.setAttribute( "aria-relevant", "all" ); oSettings.nTBody.setAttribute( "aria-relevant", "all" );
var tfoot = $(this).children('tfoot'); var tfoot = $(this).children('tfoot');
if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
{
// If we are a scrolling table, and no footer has been given, then we need to create
// a tfoot element for the caption element to be appended to
tfoot = [ document.createElement( 'tfoot' ) ];
this.appendChild( tfoot[0] );
}
if ( tfoot.length > 0 ) if ( tfoot.length > 0 )
{ {
oSettings.nTFoot = tfoot[0]; oSettings.nTFoot = tfoot[0];
@ -6541,6 +6608,105 @@
} ); } );
}; };
/**
* Provide a common method for plug-ins to check the version of DataTables being used, in order
* to ensure compatibility.
* @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
* formats "X" and "X.Y" are also acceptable.
* @returns {boolean} true if this version of DataTables is greater or equal to the required
* version, or false if this version of DataTales is not suitable
* @static
* @dtopt API-Static
*
* @example
* alert( $.fn.dataTable.fnVersionCheck( '1.9.0' ) );
*/
DataTable.fnVersionCheck = function( sVersion )
{
/* This is cheap, but effective */
var fnZPad = function (Zpad, count)
{
while(Zpad.length < count) {
Zpad += '0';
}
return Zpad;
};
var aThis = DataTable.ext.sVersion.split('.');
var aThat = sVersion.split('.');
var sThis = '', sThat = '';
for ( var i=0, iLen=aThat.length ; i<iLen ; i++ )
{
sThis += fnZPad( aThis[i], 3 );
sThat += fnZPad( aThat[i], 3 );
}
return parseInt(sThis, 10) >= parseInt(sThat, 10);
};
/**
* Check if a TABLE node is a DataTable table already or not.
* @param {node} nTable The TABLE node to check if it is a DataTable or not (note that other
* node types can be passed in, but will always return false).
* @returns {boolean} true the table given is a DataTable, or false otherwise
* @static
* @dtopt API-Static
*
* @example
* var ex = document.getElementById('example');
* if ( ! $.fn.DataTable.fnIsDataTable( ex ) ) {
* $(ex).dataTable();
* }
*/
DataTable.fnIsDataTable = function ( nTable )
{
var o = DataTable.settings;
for ( var i=0 ; i<o.length ; i++ )
{
if ( o[i].nTable === nTable || o[i].nScrollHead === nTable || o[i].nScrollFoot === nTable )
{
return true;
}
}
return false;
};
/**
* Get all DataTable tables that have been initialised - optionally you can select to
* get only currently visible tables.
* @param {boolean} [bVisible=false] Flag to indicate if you want all (default) or
* visible tables only.
* @returns {array} Array of TABLE nodes (not DataTable instances) which are DataTables
* @static
* @dtopt API-Static
*
* @example
* var table = $.fn.dataTable.fnTables(true);
* if ( table.length > 0 ) {
* $(table).dataTable().fnAdjustColumnSizing();
* }
*/
DataTable.fnTables = function ( bVisible )
{
var out = [];
jQuery.each( DataTable.settings, function (i, o) {
if ( !bVisible || (bVisible === true && $(o.nTable).is(':visible')) )
{
out.push( o.nTable );
}
} );
return out;
};
/** /**
* Version string for plug-ins to check compatibility. Allowed format is * Version string for plug-ins to check compatibility. Allowed format is
* a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
@ -6549,7 +6715,7 @@
* @type string * @type string
* @default Version number * @default Version number
*/ */
DataTable.version = "1.9.1.dev"; DataTable.version = "1.9.1";
/** /**
* Private data store, containing all of the settings objects that are created for the * Private data store, containing all of the settings objects that are created for the
@ -6797,28 +6963,7 @@
* alert( oTable.fnVersionCheck( '1.9.0' ) ); * alert( oTable.fnVersionCheck( '1.9.0' ) );
* } ); * } );
*/ */
"fnVersionCheck": function( sVersion ) "fnVersionCheck": DataTable.fnVersionCheck,
{
/* This is cheap, but very effective */
var fnZPad = function (Zpad, count)
{
while(Zpad.length < count) {
Zpad += '0';
}
return Zpad;
};
var aThis = DataTable.ext.sVersion.split('.');
var aThat = sVersion.split('.');
var sThis = '', sThat = '';
for ( var i=0, iLen=aThat.length ; i<iLen ; i++ )
{
sThis += fnZPad( aThis[i], 3 );
sThat += fnZPad( aThat[i], 3 );
}
return parseInt(sThis, 10) >= parseInt(sThat, 10);
},
/** /**
@ -7683,7 +7828,8 @@
* array may be of any length, and DataTables will apply each class * array may be of any length, and DataTables will apply each class
* sequentially, looping when required. * sequentially, looping when required.
* @type array * @type array
* @default [ 'odd', 'even' ] * @default null <i>Will take the values determinted by the oClasses.sStripe*
* options</i>
* @dtopt Option * @dtopt Option
* *
* @example * @example
@ -7693,7 +7839,7 @@
* } ); * } );
* } ) * } )
*/ */
"asStripeClasses": [ 'odd', 'even' ], "asStripeClasses": null,
/** /**
@ -7768,7 +7914,7 @@
* specified (this allow matching across multiple columns). Note that if you * specified (this allow matching across multiple columns). Note that if you
* wish to use filtering in DataTables this must remain 'true' - to remove the * wish to use filtering in DataTables this must remain 'true' - to remove the
* default filtering input box and retain filtering abilities, please use * default filtering input box and retain filtering abilities, please use
* @ref{sDom}. * {@link DataTable.defaults.sDom}.
* @type boolean * @type boolean
* @default true * @default true
* @dtopt Features * @dtopt Features
@ -8129,7 +8275,7 @@
* @example * @example
* $(document).ready( function() { * $(document).ready( function() {
* $('#example').dataTable( { * $('#example').dataTable( {
* "fnDrawCallback": function() { * "fnDrawCallback": function( oSettings ) {
* alert( 'DataTables has redrawn the table' ); * alert( 'DataTables has redrawn the table' );
* } * }
* } ); * } );
@ -8399,8 +8545,8 @@
"type": oSettings.sServerMethod, "type": oSettings.sServerMethod,
"error": function (xhr, error, thrown) { "error": function (xhr, error, thrown) {
if ( error == "parsererror" ) { if ( error == "parsererror" ) {
alert( "DataTables warning: JSON data from server could not be parsed. "+ oSettings.oApi._fnLog( oSettings, 0, "DataTables warning: JSON data from "+
"This is caused by a JSON formatting error." ); "server could not be parsed. This is caused by a JSON formatting error." );
} }
} }
} ); } );
@ -8627,12 +8773,18 @@
* will be applied to it), thus saving on an XHR at load time. iDeferLoading * will be applied to it), thus saving on an XHR at load time. iDeferLoading
* is used to indicate that deferred loading is required, but it is also used * is used to indicate that deferred loading is required, but it is also used
* to tell DataTables how many records there are in the full table (allowing * to tell DataTables how many records there are in the full table (allowing
* the information element and pagination to be displayed correctly). * the information element and pagination to be displayed correctly). In the case
* @type int * where a filtering is applied to the table on initial load, this can be
* indicated by giving the parameter as an array, where the first element is
* the number of records available after filtering and the second element is the
* number of records without filtering (allowing the table information element
* to be shown correctly).
* @type int | array
* @default null * @default null
* @dtopt Options * @dtopt Options
* *
* @example * @example
* // 57 records available in the table, no filtering applied
* $(document).ready(function() { * $(document).ready(function() {
* $('#example').dataTable( { * $('#example').dataTable( {
* "bServerSide": true, * "bServerSide": true,
@ -8640,6 +8792,19 @@
* "iDeferLoading": 57 * "iDeferLoading": 57
* } ); * } );
* } ); * } );
*
* @example
* // 57 records after filtering, 100 without filtering (an initial filter applied)
* $(document).ready(function() {
* $('#example').dataTable( {
* "bServerSide": true,
* "sAjaxSource": "scripts/server_processing.php",
* "iDeferLoading": [ 57, 100 ],
* "oSearch": {
* "sSearch": "my_filter"
* }
* } );
* } );
*/ */
"iDeferLoading": null, "iDeferLoading": null,
@ -9315,7 +9480,7 @@
* Enable horizontal scrolling. When a table is too wide to fit into a certain * Enable horizontal scrolling. When a table is too wide to fit into a certain
* layout, or you have a large number of columns in the table, you can enable * layout, or you have a large number of columns in the table, you can enable
* x-scrolling to show the table in a viewport, which can be scrolled. This * x-scrolling to show the table in a viewport, which can be scrolled. This
* property can by any CSS unit, or a number (in which case it will be treated * property can be any CSS unit, or a number (in which case it will be treated
* as a pixel measurement). * as a pixel measurement).
* @type string * @type string
* @default <i>blank string - i.e. disabled</i> * @default <i>blank string - i.e. disabled</i>
@ -9356,10 +9521,10 @@
/** /**
* Enable vertical scrolling. Vertical scrolling will constrain the DataTable * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
* to the given height, an enable scrolling for any data which overflows the * to the given height, and enable scrolling for any data which overflows the
* current viewport. This can be used as an alternative to paging to display * current viewport. This can be used as an alternative to paging to display
* a lot of data in a small area (although paging and scrolling can both be * a lot of data in a small area (although paging and scrolling can both be
* enabled at the same time). This property can by any CSS unit, or a number * enabled at the same time). This property can be any CSS unit, or a number
* (in which case it will be treated as a pixel measurement). * (in which case it will be treated as a pixel measurement).
* @type string * @type string
* @default <i>blank string - i.e. disabled</i> * @default <i>blank string - i.e. disabled</i>
@ -9753,8 +9918,9 @@
* <ul> * <ul>
* <li>{array|object} The data source for the row</li> * <li>{array|object} The data source for the row</li>
* <li>{string} The type call data requested - this will be 'set' when * <li>{string} The type call data requested - this will be 'set' when
* setting data or 'filter', 'display', 'type' or 'sort' when gathering * setting data or 'filter', 'display', 'type', 'sort' or undefined when
* data.</li> * gathering data. Note that when <i>undefined</i> is given for the type
* DataTables expects to get the raw data for the object back</li>
* <li>{*} Data to set when the second parameter is 'set'.</li> * <li>{*} Data to set when the second parameter is 'set'.</li>
* </ul> * </ul>
* The return value from the function is not required when 'set' is the type * The return value from the function is not required when 'set' is the type
@ -9802,7 +9968,7 @@
* else if (type === 'filter') { * else if (type === 'filter') {
* return source.price_filter; * return source.price_filter;
* } * }
* // 'sort' and 'type' both just use the integer * // 'sort', 'type' and undefined all just use the integer
* return source.price; * return source.price;
* } * }
* ] * ]
@ -9812,6 +9978,29 @@
"mDataProp": null, "mDataProp": null,
/**
* Change the cell type created for the column - either TD cells or TH cells. This
* can be useful as TH cells have semantic meaning in the table body, allowing them
* to act as a header for a row (you may wish to add scope='row' to the TH elements).
* @type string
* @default td
* @dtopt Columns
*
* @example
* // Make the first column use TH cells
* $(document).ready(function() {
* var oTable = $('#example').dataTable( {
* "aoColumnDefs": [
* {
* "aTargets": [ 0 ],
* "sCellType": "th"
* ]
* } );
* } );
*/
"sCellType": "td",
/** /**
* Class to give to each cell in this column. * Class to give to each cell in this column.
* @type string * @type string
@ -10965,7 +11154,17 @@
* tabindex attribute value that is added to DataTables control elements, allowing * tabindex attribute value that is added to DataTables control elements, allowing
* keyboard navigation of the table and its controls. * keyboard navigation of the table and its controls.
*/ */
"iTabIndex": 0 "iTabIndex": 0,
/**
* DIV container for the footer scrolling table if scrolling
*/
"nScrollHead": null,
/**
* DIV container for the footer scrolling table if scrolling
*/
"nScrollFoot": null
}; };
/** /**
@ -11272,7 +11471,13 @@
}; };
/* Pages calculation */ /* Pages calculation */
if (iPages < iPageCount) if ( oSettings._iDisplayLength === -1 )
{
iStartButton = 1;
iEndButton = 1;
iCurrentPage = 1;
}
else if (iPages < iPageCount)
{ {
iStartButton = 1; iStartButton = 1;
iEndButton = iPages; iEndButton = iPages;
@ -11293,6 +11498,7 @@
iEndButton = iStartButton + iPageCount - 1; iEndButton = iStartButton + iPageCount - 1;
} }
/* Build the dynamic list */ /* Build the dynamic list */
for ( i=iStartButton ; i<=iEndButton ; i++ ) for ( i=iStartButton ; i<=iEndButton ; i++ )
{ {
@ -11619,4 +11825,14 @@
* @param {event} e jQuery event object * @param {event} e jQuery event object
* @param {object} o DataTables settings object {@link DataTable.models.oSettings} * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
*/ */
/**
* Destroy event, fired when the DataTable is destroyed by calling fnDestroy or passing
* the bDestroy:true parameter in the initialisation object. This can be used to remove
* bound events, added DOM nodes, etc.
* @name DataTable#destroy
* @event
* @param {event} e jQuery event object
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
*/
}(jQuery, window, document, undefined)); }(jQuery, window, document, undefined));