1
0
mirror of https://github.com/DataTables/DataTables.git synced 2024-12-12 00:08:48 +01:00

Update: Initial work on updating state saving code to use objects rather than constructing a JSON string. Note that this has involved removing fnStateLoadCallback and fnStateSaveCallback which are now replaced with a much more effective setup using fnStateSaveParams, fnStateLoadParams and fnStateLoaded (blog post to come about this). Code documentation and tidy up yet required

This commit is contained in:
Allan Jardine 2012-01-02 09:21:19 +00:00
parent e8c4436132
commit cf12ba5ab3
8 changed files with 246 additions and 250 deletions

View File

@ -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*/ /*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*/
(/** @lends <global> */function($, window, document, undefined) { (/** @lends <global> */function($, window, document, undefined) {
/** /**
@ -4234,60 +4234,27 @@
return; return;
} }
/* xxx - This is horrible! What we really want to do is use a proper object and
* pass that around - but jQuery doesn't have a toJson option. Either need to use
* $.param or JSON.stringify or something else
*/
/* Store the interesting variables */ /* Store the interesting variables */
var i, iLen, sTmp; var i, iLen;
var sValue = "{"; var oState = {
sValue += '"iCreate":'+ new Date().getTime()+','; "iCreate": new Date().getTime(),
sValue += '"iStart":'+ (oSettings.oScroll.bInfinite ? 0 : oSettings._iDisplayStart)+','; "iStart": (oSettings.oScroll.bInfinite ? 0 : oSettings._iDisplayStart),
sValue += '"iEnd":'+ (oSettings.oScroll.bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd)+','; "iEnd": (oSettings.oScroll.bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd),
sValue += '"iLength":'+ oSettings._iDisplayLength+','; "iLength": oSettings._iDisplayLength,
sValue += '"sFilter":"'+ encodeURIComponent(oSettings.oPreviousSearch.sSearch)+'",'; "aaSorting": oSettings.aaSorting.slice(),
sValue += '"sFilterEsc":'+ !oSettings.oPreviousSearch.bRegex+','; "oSearch": oSettings.oPreviousSearch.sSearch,
"aoSearchCols": oSettings.aoPreSearchCols.slice(),
"abVisCols": []
};
sValue += '"aaSorting":[ '; for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
for ( i=0 ; i<oSettings.aaSorting.length ; i++ )
{ {
sValue += '['+oSettings.aaSorting[i][0]+',"'+oSettings.aaSorting[i][1]+'"],'; oState.abVisCols.push( oSettings.aoColumns[i].bVisible );
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "],";
sValue += '"aaSearchCols":[ ';
for ( i=0 ; i<oSettings.aoPreSearchCols.length ; i++ )
{
sValue += '["'+encodeURIComponent(oSettings.aoPreSearchCols[i].sSearch)+
'",'+!oSettings.aoPreSearchCols[i].bRegex+'],';
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "],";
sValue += '"abVisCols":[ ';
for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
{
sValue += oSettings.aoColumns[i].bVisible+",";
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "]";
/* Save state from any plug-ins */
for ( i=0, iLen=oSettings.aoStateSave.length ; i<iLen ; i++ )
{
sTmp = oSettings.aoStateSave[i].fn( oSettings, sValue );
if ( sTmp !== "" )
{
sValue = sTmp;
}
} }
sValue += "}"; _fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
_fnCreateCookie( oSettings.sCookiePrefix+oSettings.sInstance, sValue, oSettings.fnStateSave.call( oSettings.oInstance, oSettings, oState );
oSettings.iCookieDuration, oSettings.sCookiePrefix, oSettings.fnCookieCallback );
} }
@ -4304,34 +4271,16 @@
return; return;
} }
var oData, i, iLen; var oData = oSettings.fnStateLoad.call( oSettings.oInstance, oSettings );
var sData = _fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance ); if ( !oData )
/* Try/catch the JSON eval - if it is bad then we ignore it - note that 1.7.0 and before
* incorrectly used single quotes for some strings - hence the replace below
*/
try
{
oData = (typeof $.parseJSON === 'function') ?
$.parseJSON( sData.replace(/'/g, '"') ) : eval( '('+sData+')' );
}
catch( e )
{
oData = null;
}
/* Allow custom and plug-in manipulation functions to alter the data set which was
* saved, and also reject any saved state by returning false
*/
var aCallbacks = _fnCallbackFire( oSettings, 'aoStateLoad', 'stateLoad', [oSettings, oData] );
if ( $.inArray( false, aCallbacks ) !== -1 )
{ {
return; return;
} }
if ( oData !== null ) /* Allow custom and plug-in manipulation functions to alter the saved data set */
{ _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
/* Store the saved state so it might be accessed at any time (particualrly a plug-in */
/* Store the saved state so it might be accessed at any time */
oSettings.oLoadedState = $.extend( true, {}, oData ); oSettings.oLoadedState = $.extend( true, {}, oData );
/* Restore key features */ /* Restore key features */
@ -4339,46 +4288,25 @@
oSettings.iInitDisplayStart = oData.iStart; oSettings.iInitDisplayStart = oData.iStart;
oSettings._iDisplayEnd = oData.iEnd; oSettings._iDisplayEnd = oData.iEnd;
oSettings._iDisplayLength = oData.iLength; oSettings._iDisplayLength = oData.iLength;
oSettings.oPreviousSearch.sSearch = decodeURIComponent(oData.sFilter);
oSettings.aaSorting = oData.aaSorting.slice(); oSettings.aaSorting = oData.aaSorting.slice();
oSettings.saved_aaSorting = oData.aaSorting.slice(); oSettings.saved_aaSorting = oData.aaSorting.slice();
/* /* Search filtering */
* Search filtering - global reference added in 1.4.1 $.extend( oSettings.oPreviousSearch, oData.oSearch );
* Note that we use a 'not' for the value of the regular expression indicator to maintain $.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
* compatibility with pre 1.7 versions, where this was basically inverted. Added in 1.7.0
*/
if ( oData.sFilterEsc )
{
oSettings.oPreviousSearch.bRegex = !oData.sFilterEsc;
}
/* Column filtering - added in 1.5.0 beta 6 */ /* Column visibility state
if ( oData.aaSearchCols ) * Pass back visibiliy settings to the init handler, but to do not here override
{
for ( i=0 ; i<oData.aaSearchCols.length ; i++ )
{
oSettings.aoPreSearchCols[i] = {
"sSearch": decodeURIComponent(oData.aaSearchCols[i][0]),
"bRegex": !oData.aaSearchCols[i][1]
};
}
}
/* Column visibility state - added in 1.5.0 beta 10 */
if ( oData.abVisCols )
{
/* Pass back visibiliy settings to the init handler, but to do not here override
* the init object that the user might have passed in * the init object that the user might have passed in
*/ */
oInit.saved_aoColumns = []; oInit.saved_aoColumns = [];
for ( i=0 ; i<oData.abVisCols.length ; i++ ) for ( var i=0 ; i<oData.abVisCols.length ; i++ )
{ {
oInit.saved_aoColumns[i] = {}; oInit.saved_aoColumns[i] = {};
oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i]; oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i];
} }
}
} _fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
} }
@ -4751,6 +4679,39 @@
} }
function _fnJsonString( obj )
{
if ( JSON.stringify )
{
return JSON.stringify( obj );
}
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") {
obj = '"'+obj+'"';
}
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") {
v = '"'+v+'"';
}
else if (t == "object" && v !== null) {
v = _fnJsonString(v);
}
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
}
/** /**
@ -6009,7 +5970,8 @@
"_fnBindAction": _fnBindAction, "_fnBindAction": _fnBindAction,
"_fnExtend": _fnExtend, "_fnExtend": _fnExtend,
"_fnCallbackReg": _fnCallbackReg, "_fnCallbackReg": _fnCallbackReg,
"_fnCallbackFire": _fnCallbackFire "_fnCallbackFire": _fnCallbackFire,
"_fnJsonString": _fnJsonString
}; };
$.extend( DataTable.ext.oApi, this.oApi ); $.extend( DataTable.ext.oApi, this.oApi );
@ -6148,13 +6110,16 @@
_fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" ); _fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" );
_fnMap( oSettings, oInit, "bJQueryUI", "bJUI" ); _fnMap( oSettings, oInit, "bJQueryUI", "bJUI" );
_fnMap( oSettings, oInit, "fnCookieCallback" ); _fnMap( oSettings, oInit, "fnCookieCallback" );
_fnMap( oSettings, oInit, "fnStateLoad" );
_fnMap( oSettings, oInit, "fnStateSave" );
_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
/* Callback functions which are array driven */ /* Callback functions which are array driven */
_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' ); _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateSave', oInit.fnStateSaveCallback, 'user' ); _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateLoad', oInit.fnStateLoadCallback, 'user' ); _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' ); _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' ); _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' ); _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
@ -9137,7 +9102,36 @@
* } ); * } );
* } ); * } );
*/ */
"sServerMethod": "GET" "sServerMethod": "GET",
"fnStateSave": function ( oSettings, oData ) {
this.oApi._fnCreateCookie(
oSettings.sCookiePrefix+oSettings.sInstance,
this.oApi._fnJsonString(oData),
oSettings.iCookieDuration,
oSettings.sCookiePrefix,
oSettings.fnCookieCallback
);
},
"fnStateLoad": function ( oSettings ) {
var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance );
var oData;
try {
oData = (typeof $.parseJSON === 'function') ?
$.parseJSON(sData) : eval( '('+sData+')' );
} catch (e) {
oData = null;
}
return oData;
},
"fnStateSaveParams": null,
"fnStateLoadParams": null,
"fnStateLoaded": null
}; };
@ -10195,6 +10189,10 @@
*/ */
"aoInitComplete": [], "aoInitComplete": [],
"aoStateSaveParams": [],
"aoStateLoadParams": [],
"aoStateLoaded": [],
/** /**
* Cache the table ID for quick access * Cache the table ID for quick access
* @type string * @type string

View File

@ -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*/ /*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*/
(/** @lends <global> */function($, window, document, undefined) { (/** @lends <global> */function($, window, document, undefined) {
/** /**

View File

@ -109,7 +109,8 @@ this.oApi = {
"_fnBindAction": _fnBindAction, "_fnBindAction": _fnBindAction,
"_fnExtend": _fnExtend, "_fnExtend": _fnExtend,
"_fnCallbackReg": _fnCallbackReg, "_fnCallbackReg": _fnCallbackReg,
"_fnCallbackFire": _fnCallbackFire "_fnCallbackFire": _fnCallbackFire,
"_fnJsonString": _fnJsonString
}; };
$.extend( DataTable.ext.oApi, this.oApi ); $.extend( DataTable.ext.oApi, this.oApi );

View File

@ -121,13 +121,16 @@ _fnMap( oSettings, oInit, "aoSearchCols", "aoPreSearchCols" );
_fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" ); _fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" );
_fnMap( oSettings, oInit, "bJQueryUI", "bJUI" ); _fnMap( oSettings, oInit, "bJQueryUI", "bJUI" );
_fnMap( oSettings, oInit, "fnCookieCallback" ); _fnMap( oSettings, oInit, "fnCookieCallback" );
_fnMap( oSettings, oInit, "fnStateLoad" );
_fnMap( oSettings, oInit, "fnStateSave" );
_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
/* Callback functions which are array driven */ /* Callback functions which are array driven */
_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' ); _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateSave', oInit.fnStateSaveCallback, 'user' ); _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateLoad', oInit.fnStateLoadCallback, 'user' ); _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' ); _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' ); _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' ); _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );

View File

@ -12,60 +12,27 @@ function _fnSaveState ( oSettings )
return; return;
} }
/* xxx - This is horrible! What we really want to do is use a proper object and
* pass that around - but jQuery doesn't have a toJson option. Either need to use
* $.param or JSON.stringify or something else
*/
/* Store the interesting variables */ /* Store the interesting variables */
var i, iLen, sTmp; var i, iLen;
var sValue = "{"; var oState = {
sValue += '"iCreate":'+ new Date().getTime()+','; "iCreate": new Date().getTime(),
sValue += '"iStart":'+ (oSettings.oScroll.bInfinite ? 0 : oSettings._iDisplayStart)+','; "iStart": (oSettings.oScroll.bInfinite ? 0 : oSettings._iDisplayStart),
sValue += '"iEnd":'+ (oSettings.oScroll.bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd)+','; "iEnd": (oSettings.oScroll.bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd),
sValue += '"iLength":'+ oSettings._iDisplayLength+','; "iLength": oSettings._iDisplayLength,
sValue += '"sFilter":"'+ encodeURIComponent(oSettings.oPreviousSearch.sSearch)+'",'; "aaSorting": oSettings.aaSorting.slice(),
sValue += '"sFilterEsc":'+ !oSettings.oPreviousSearch.bRegex+','; "oSearch": oSettings.oPreviousSearch.sSearch,
"aoSearchCols": oSettings.aoPreSearchCols.slice(),
"abVisCols": []
};
sValue += '"aaSorting":[ '; for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
for ( i=0 ; i<oSettings.aaSorting.length ; i++ )
{ {
sValue += '['+oSettings.aaSorting[i][0]+',"'+oSettings.aaSorting[i][1]+'"],'; oState.abVisCols.push( oSettings.aoColumns[i].bVisible );
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "],";
sValue += '"aaSearchCols":[ ';
for ( i=0 ; i<oSettings.aoPreSearchCols.length ; i++ )
{
sValue += '["'+encodeURIComponent(oSettings.aoPreSearchCols[i].sSearch)+
'",'+!oSettings.aoPreSearchCols[i].bRegex+'],';
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "],";
sValue += '"abVisCols":[ ';
for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
{
sValue += oSettings.aoColumns[i].bVisible+",";
}
sValue = sValue.substring(0, sValue.length-1);
sValue += "]";
/* Save state from any plug-ins */
for ( i=0, iLen=oSettings.aoStateSave.length ; i<iLen ; i++ )
{
sTmp = oSettings.aoStateSave[i].fn( oSettings, sValue );
if ( sTmp !== "" )
{
sValue = sTmp;
}
} }
sValue += "}"; _fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
_fnCreateCookie( oSettings.sCookiePrefix+oSettings.sInstance, sValue, oSettings.fnStateSave.call( oSettings.oInstance, oSettings, oState );
oSettings.iCookieDuration, oSettings.sCookiePrefix, oSettings.fnCookieCallback );
} }
@ -82,34 +49,16 @@ function _fnLoadState ( oSettings, oInit )
return; return;
} }
var oData, i, iLen; var oData = oSettings.fnStateLoad.call( oSettings.oInstance, oSettings );
var sData = _fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance ); if ( !oData )
/* Try/catch the JSON eval - if it is bad then we ignore it - note that 1.7.0 and before
* incorrectly used single quotes for some strings - hence the replace below
*/
try
{
oData = (typeof $.parseJSON === 'function') ?
$.parseJSON( sData.replace(/'/g, '"') ) : eval( '('+sData+')' );
}
catch( e )
{
oData = null;
}
/* Allow custom and plug-in manipulation functions to alter the data set which was
* saved, and also reject any saved state by returning false
*/
var aCallbacks = _fnCallbackFire( oSettings, 'aoStateLoad', 'stateLoad', [oSettings, oData] );
if ( $.inArray( false, aCallbacks ) !== -1 )
{ {
return; return;
} }
if ( oData !== null ) /* Allow custom and plug-in manipulation functions to alter the saved data set */
{ _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
/* Store the saved state so it might be accessed at any time (particualrly a plug-in */
/* Store the saved state so it might be accessed at any time */
oSettings.oLoadedState = $.extend( true, {}, oData ); oSettings.oLoadedState = $.extend( true, {}, oData );
/* Restore key features */ /* Restore key features */
@ -117,46 +66,25 @@ function _fnLoadState ( oSettings, oInit )
oSettings.iInitDisplayStart = oData.iStart; oSettings.iInitDisplayStart = oData.iStart;
oSettings._iDisplayEnd = oData.iEnd; oSettings._iDisplayEnd = oData.iEnd;
oSettings._iDisplayLength = oData.iLength; oSettings._iDisplayLength = oData.iLength;
oSettings.oPreviousSearch.sSearch = decodeURIComponent(oData.sFilter);
oSettings.aaSorting = oData.aaSorting.slice(); oSettings.aaSorting = oData.aaSorting.slice();
oSettings.saved_aaSorting = oData.aaSorting.slice(); oSettings.saved_aaSorting = oData.aaSorting.slice();
/* /* Search filtering */
* Search filtering - global reference added in 1.4.1 $.extend( oSettings.oPreviousSearch, oData.oSearch );
* Note that we use a 'not' for the value of the regular expression indicator to maintain $.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
* compatibility with pre 1.7 versions, where this was basically inverted. Added in 1.7.0
*/
if ( oData.sFilterEsc )
{
oSettings.oPreviousSearch.bRegex = !oData.sFilterEsc;
}
/* Column filtering - added in 1.5.0 beta 6 */ /* Column visibility state
if ( oData.aaSearchCols ) * Pass back visibiliy settings to the init handler, but to do not here override
{
for ( i=0 ; i<oData.aaSearchCols.length ; i++ )
{
oSettings.aoPreSearchCols[i] = {
"sSearch": decodeURIComponent(oData.aaSearchCols[i][0]),
"bRegex": !oData.aaSearchCols[i][1]
};
}
}
/* Column visibility state - added in 1.5.0 beta 10 */
if ( oData.abVisCols )
{
/* Pass back visibiliy settings to the init handler, but to do not here override
* the init object that the user might have passed in * the init object that the user might have passed in
*/ */
oInit.saved_aoColumns = []; oInit.saved_aoColumns = [];
for ( i=0 ; i<oData.abVisCols.length ; i++ ) for ( var i=0 ; i<oData.abVisCols.length ; i++ )
{ {
oInit.saved_aoColumns[i] = {}; oInit.saved_aoColumns[i] = {};
oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i]; oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i];
} }
}
} _fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
} }

View File

@ -261,3 +261,36 @@ function _fnCallbackFire( oSettings, sStore, sTrigger, aArgs )
return aRet; return aRet;
} }
function _fnJsonString( obj )
{
if ( JSON.stringify )
{
return JSON.stringify( obj );
}
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") {
obj = '"'+obj+'"';
}
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") {
v = '"'+v+'"';
}
else if (t == "object" && v !== null) {
v = _fnJsonString(v);
}
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
}

View File

@ -1766,6 +1766,35 @@ DataTable.defaults = {
* } ); * } );
* } ); * } );
*/ */
"sServerMethod": "GET" "sServerMethod": "GET",
"fnStateSave": function ( oSettings, oData ) {
this.oApi._fnCreateCookie(
oSettings.sCookiePrefix+oSettings.sInstance,
this.oApi._fnJsonString(oData),
oSettings.iCookieDuration,
oSettings.sCookiePrefix,
oSettings.fnCookieCallback
);
},
"fnStateLoad": function ( oSettings ) {
var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance );
var oData;
try {
oData = (typeof $.parseJSON === 'function') ?
$.parseJSON(sData) : eval( '('+sData+')' );
} catch (e) {
oData = null;
}
return oData;
},
"fnStateSaveParams": null,
"fnStateLoadParams": null,
"fnStateLoaded": null
}; };

View File

@ -411,6 +411,10 @@ DataTable.models.oSettings = {
*/ */
"aoInitComplete": [], "aoInitComplete": [],
"aoStateSaveParams": [],
"aoStateLoadParams": [],
"aoStateLoaded": [],
/** /**
* Cache the table ID for quick access * Cache the table ID for quick access
* @type string * @type string