Project

General

Profile

Download (6.34 KB) Statistics
| Branch: | Tag: | Revision:
1

    
2

    
3
/**
4
 * Save the state of a table in a cookie such that the page can be reloaded
5
 *  @param {object} oSettings dataTables settings object
6
 *  @memberof DataTable#oApi
7
 */
8
function _fnSaveState ( oSettings )
9
{
10
	if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying )
11
	{
12
		return;
13
	}
14

    
15
	/* Store the interesting variables */
16
	var i, iLen, bInfinite=oSettings.oScroll.bInfinite;
17
	var oState = {
18
		"iCreate":      new Date().getTime(),
19
		"iStart":       (bInfinite ? 0 : oSettings._iDisplayStart),
20
		"iEnd":         (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd),
21
		"iLength":      oSettings._iDisplayLength,
22
		"aaSorting":    $.extend( true, [], oSettings.aaSorting ),
23
		"oSearch":      $.extend( true, {}, oSettings.oPreviousSearch ),
24
		"aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ),
25
		"abVisCols":    []
26
	};
27

    
28
	for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
29
	{
30
		oState.abVisCols.push( oSettings.aoColumns[i].bVisible );
31
	}
32

    
33
	_fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
34
	
35
	oSettings.fnStateSave.call( oSettings.oInstance, oSettings, oState );
36
}
37

    
38

    
39
/**
40
 * Attempt to load a saved table state from a cookie
41
 *  @param {object} oSettings dataTables settings object
42
 *  @param {object} oInit DataTables init object so we can override settings
43
 *  @memberof DataTable#oApi
44
 */
45
function _fnLoadState ( oSettings, oInit )
46
{
47
	if ( !oSettings.oFeatures.bStateSave )
48
	{
49
		return;
50
	}
51

    
52
	var oData = oSettings.fnStateLoad.call( oSettings.oInstance, oSettings );
53
	if ( !oData )
54
	{
55
		return;
56
	}
57
	
58
	/* Allow custom and plug-in manipulation functions to alter the saved data set and
59
	 * cancelling of loading by returning false
60
	 */
61
	var abStateLoad = _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
62
	if ( $.inArray( false, abStateLoad ) !== -1 )
63
	{
64
		return;
65
	}
66
	
67
	/* Store the saved state so it might be accessed at any time */
68
	oSettings.oLoadedState = $.extend( true, {}, oData );
69
	
70
	/* Restore key features */
71
	oSettings._iDisplayStart    = oData.iStart;
72
	oSettings.iInitDisplayStart = oData.iStart;
73
	oSettings._iDisplayEnd      = oData.iEnd;
74
	oSettings._iDisplayLength   = oData.iLength;
75
	oSettings.aaSorting         = oData.aaSorting.slice();
76
	oSettings.saved_aaSorting   = oData.aaSorting.slice();
77
	
78
	/* Search filtering  */
79
	$.extend( oSettings.oPreviousSearch, oData.oSearch );
80
	$.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
81
	
82
	/* Column visibility state
83
	 * Pass back visibility settings to the init handler, but to do not here override
84
	 * the init object that the user might have passed in
85
	 */
86
	oInit.saved_aoColumns = [];
87
	for ( var i=0 ; i<oData.abVisCols.length ; i++ )
88
	{
89
		oInit.saved_aoColumns[i] = {};
90
		oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i];
91
	}
92

    
93
	_fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
94
}
95

    
96

    
97
/**
98
 * Create a new cookie with a value to store the state of a table
99
 *  @param {string} sName name of the cookie to create
100
 *  @param {string} sValue the value the cookie should take
101
 *  @param {int} iSecs duration of the cookie
102
 *  @param {string} sBaseName sName is made up of the base + file name - this is the base
103
 *  @param {function} fnCallback User definable function to modify the cookie
104
 *  @memberof DataTable#oApi
105
 */
106
function _fnCreateCookie ( sName, sValue, iSecs, sBaseName, fnCallback )
107
{
108
	var date = new Date();
109
	date.setTime( date.getTime()+(iSecs*1000) );
110
	
111
	/* 
112
	 * Shocking but true - it would appear IE has major issues with having the path not having
113
	 * a trailing slash on it. We need the cookie to be available based on the path, so we
114
	 * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the
115
	 * patch to use at least some of the path
116
	 */
117
	var aParts = window.location.pathname.split('/');
118
	var sNameFile = sName + '_' + aParts.pop().replace(/[\/:]/g,"").toLowerCase();
119
	var sFullCookie, oData;
120
	
121
	if ( fnCallback !== null )
122
	{
123
		oData = (typeof $.parseJSON === 'function') ? 
124
			$.parseJSON( sValue ) : eval( '('+sValue+')' );
125
		sFullCookie = fnCallback( sNameFile, oData, date.toGMTString(),
126
			aParts.join('/')+"/" );
127
	}
128
	else
129
	{
130
		sFullCookie = sNameFile + "=" + encodeURIComponent(sValue) +
131
			"; expires=" + date.toGMTString() +"; path=" + aParts.join('/')+"/";
132
	}
133
	
134
	/* Are we going to go over the cookie limit of 4KiB? If so, try to delete a cookies
135
	 * belonging to DataTables.
136
	 */
137
	var
138
		aCookies =document.cookie.split(';'),
139
		iNewCookieLen = sFullCookie.split(';')[0].length,
140
		aOldCookies = [];
141
	
142
	if ( iNewCookieLen+document.cookie.length+10 > 4096 ) /* Magic 10 for padding */
143
	{
144
		for ( var i=0, iLen=aCookies.length ; i<iLen ; i++ )
145
		{
146
			if ( aCookies[i].indexOf( sBaseName ) != -1 )
147
			{
148
				/* It's a DataTables cookie, so eval it and check the time stamp */
149
				var aSplitCookie = aCookies[i].split('=');
150
				try {
151
					oData = eval( '('+decodeURIComponent(aSplitCookie[1])+')' );
152

    
153
					if ( oData && oData.iCreate )
154
					{
155
						aOldCookies.push( {
156
							"name": aSplitCookie[0],
157
							"time": oData.iCreate
158
						} );
159
					}
160
				}
161
				catch( e ) {}
162
			}
163
		}
164

    
165
		// Make sure we delete the oldest ones first
166
		aOldCookies.sort( function (a, b) {
167
			return b.time - a.time;
168
		} );
169

    
170
		// Eliminate as many old DataTables cookies as we need to
171
		while ( iNewCookieLen + document.cookie.length + 10 > 4096 ) {
172
			if ( aOldCookies.length === 0 ) {
173
				// Deleted all DT cookies and still not enough space. Can't state save
174
				return;
175
			}
176
			
177
			var old = aOldCookies.pop();
178
			document.cookie = old.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
179
				aParts.join('/') + "/";
180
		}
181
	}
182
	
183
	document.cookie = sFullCookie;
184
}
185

    
186

    
187
/**
188
 * Read an old cookie to get a cookie with an old table state
189
 *  @param {string} sName name of the cookie to read
190
 *  @returns {string} contents of the cookie - or null if no cookie with that name found
191
 *  @memberof DataTable#oApi
192
 */
193
function _fnReadCookie ( sName )
194
{
195
	var
196
		aParts = window.location.pathname.split('/'),
197
		sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=',
198
	 	sCookieContents = document.cookie.split(';');
199
	
200
	for( var i=0 ; i<sCookieContents.length ; i++ )
201
	{
202
		var c = sCookieContents[i];
203
		
204
		while (c.charAt(0)==' ')
205
		{
206
			c = c.substring(1,c.length);
207
		}
208
		
209
		if (c.indexOf(sNameEQ) === 0)
210
		{
211
			return decodeURIComponent( c.substring(sNameEQ.length,c.length) );
212
		}
213
	}
214
	return null;
215
}
216

    
(15-15/16)