datatables.net 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/dataTables.js +766 -398
- package/js/dataTables.min.js +2 -2
- package/js/dataTables.min.mjs +2 -2
- package/js/dataTables.mjs +765 -397
- package/package.json +1 -1
- package/types/types.d.ts +146 -13
package/js/dataTables.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! DataTables 2.0
|
|
1
|
+
/*! DataTables 2.1.0
|
|
2
2
|
* © SpryMedia Ltd - datatables.net/license
|
|
3
3
|
*/
|
|
4
4
|
|
|
@@ -51,7 +51,6 @@ var DataTable = function ( selector, options )
|
|
|
51
51
|
|
|
52
52
|
var i=0, iLen;
|
|
53
53
|
var sId = this.getAttribute( 'id' );
|
|
54
|
-
var bInitHandedOff = false;
|
|
55
54
|
var defaults = DataTable.defaults;
|
|
56
55
|
var $this = $(this);
|
|
57
56
|
|
|
@@ -201,6 +200,7 @@ var DataTable = function ( selector, options )
|
|
|
201
200
|
"rowId",
|
|
202
201
|
"caption",
|
|
203
202
|
"layout",
|
|
203
|
+
"orderDescReverse",
|
|
204
204
|
[ "iCookieDuration", "iStateDuration" ], // backwards compat
|
|
205
205
|
[ "oSearch", "oPreviousSearch" ],
|
|
206
206
|
[ "aoSearchCols", "aoPreSearchCols" ],
|
|
@@ -247,38 +247,14 @@ var DataTable = function ( selector, options )
|
|
|
247
247
|
oSettings._iDisplayStart = oInit.iDisplayStart;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
$.extend( true, oLanguage, oInit.oLanguage );
|
|
253
|
-
|
|
254
|
-
if ( oLanguage.sUrl )
|
|
250
|
+
var defer = oInit.iDeferLoading;
|
|
251
|
+
if ( defer !== null )
|
|
255
252
|
{
|
|
256
|
-
|
|
257
|
-
* get async to the remainder of this function we use bInitHandedOff to indicate that
|
|
258
|
-
* _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
|
|
259
|
-
*/
|
|
260
|
-
$.ajax( {
|
|
261
|
-
dataType: 'json',
|
|
262
|
-
url: oLanguage.sUrl,
|
|
263
|
-
success: function ( json ) {
|
|
264
|
-
_fnCamelToHungarian( defaults.oLanguage, json );
|
|
265
|
-
$.extend( true, oLanguage, json, oSettings.oInit.oLanguage );
|
|
253
|
+
oSettings.deferLoading = true;
|
|
266
254
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
error: function () {
|
|
271
|
-
// Error occurred loading language file
|
|
272
|
-
_fnLog( oSettings, 0, 'i18n file loading error', 21 );
|
|
273
|
-
|
|
274
|
-
// continue on as best we can
|
|
275
|
-
_fnInitialise( oSettings );
|
|
276
|
-
}
|
|
277
|
-
} );
|
|
278
|
-
bInitHandedOff = true;
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
_fnCallbackFire( oSettings, null, 'i18n', [oSettings]);
|
|
255
|
+
var tmp = Array.isArray(defer);
|
|
256
|
+
oSettings._iRecordsDisplay = tmp ? defer[0] : defer;
|
|
257
|
+
oSettings._iRecordsTotal = tmp ? defer[1] : defer;
|
|
282
258
|
}
|
|
283
259
|
|
|
284
260
|
/*
|
|
@@ -345,113 +321,112 @@ var DataTable = function ( selector, options )
|
|
|
345
321
|
} );
|
|
346
322
|
}
|
|
347
323
|
|
|
324
|
+
// Must be done after everything which can be overridden by the state saving!
|
|
325
|
+
_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState );
|
|
326
|
+
|
|
348
327
|
var features = oSettings.oFeatures;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
*/
|
|
328
|
+
if ( oInit.bStateSave )
|
|
329
|
+
{
|
|
330
|
+
features.bStateSave = true;
|
|
331
|
+
}
|
|
354
332
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
333
|
+
// If aaSorting is not defined, then we use the first indicator in asSorting
|
|
334
|
+
// in case that has been altered, so the default sort reflects that option
|
|
335
|
+
if ( oInit.aaSorting === undefined ) {
|
|
336
|
+
var sorting = oSettings.aaSorting;
|
|
337
|
+
for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
|
|
338
|
+
sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
|
|
362
339
|
}
|
|
340
|
+
}
|
|
363
341
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
_fnSortingClasses( oSettings );
|
|
368
|
-
|
|
369
|
-
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
|
370
|
-
if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
|
|
371
|
-
_fnSortingClasses( oSettings );
|
|
372
|
-
}
|
|
373
|
-
} );
|
|
342
|
+
// Do a first pass on the sorting classes (allows any size changes to be taken into
|
|
343
|
+
// account, and also will apply sorting disabled classes if disabled
|
|
344
|
+
_fnSortingClasses( oSettings );
|
|
374
345
|
|
|
346
|
+
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
|
347
|
+
if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
|
|
348
|
+
_fnSortingClasses( oSettings );
|
|
349
|
+
}
|
|
350
|
+
} );
|
|
375
351
|
|
|
376
|
-
/*
|
|
377
|
-
* Final init
|
|
378
|
-
* Cache the header, body and footer as required, creating them if needed
|
|
379
|
-
*/
|
|
380
|
-
var caption = $this.children('caption');
|
|
381
352
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
353
|
+
/*
|
|
354
|
+
* Table HTML init
|
|
355
|
+
* Cache the header, body and footer as required, creating them if needed
|
|
356
|
+
*/
|
|
357
|
+
var caption = $this.children('caption');
|
|
386
358
|
|
|
387
|
-
|
|
359
|
+
if ( oSettings.caption ) {
|
|
360
|
+
if ( caption.length === 0 ) {
|
|
361
|
+
caption = $('<caption/>').appendTo( $this );
|
|
388
362
|
}
|
|
389
363
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (caption.length) {
|
|
393
|
-
caption[0]._captionSide = caption.css('caption-side');
|
|
394
|
-
oSettings.captionNode = caption[0];
|
|
395
|
-
}
|
|
364
|
+
caption.html( oSettings.caption );
|
|
365
|
+
}
|
|
396
366
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
367
|
+
// Store the caption side, so we can remove the element from the document
|
|
368
|
+
// when creating the element
|
|
369
|
+
if (caption.length) {
|
|
370
|
+
caption[0]._captionSide = caption.css('caption-side');
|
|
371
|
+
oSettings.captionNode = caption[0];
|
|
372
|
+
}
|
|
402
373
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
374
|
+
if ( thead.length === 0 ) {
|
|
375
|
+
thead = $('<thead/>').appendTo($this);
|
|
376
|
+
}
|
|
377
|
+
oSettings.nTHead = thead[0];
|
|
378
|
+
$('tr', thead).addClass(oClasses.thead.row);
|
|
408
379
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
oSettings.nTFoot = tfoot[0];
|
|
416
|
-
$('tr', tfoot).addClass(oClasses.tfoot.row);
|
|
380
|
+
var tbody = $this.children('tbody');
|
|
381
|
+
if ( tbody.length === 0 ) {
|
|
382
|
+
tbody = $('<tbody/>').insertAfter(thead);
|
|
383
|
+
}
|
|
384
|
+
oSettings.nTBody = tbody[0];
|
|
417
385
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
|
|
427
|
-
}
|
|
386
|
+
var tfoot = $this.children('tfoot');
|
|
387
|
+
if ( tfoot.length === 0 ) {
|
|
388
|
+
// If we are a scrolling table, and no footer has been given, then we need to create
|
|
389
|
+
// a tfoot element for the caption element to be appended to
|
|
390
|
+
tfoot = $('<tfoot/>').appendTo($this);
|
|
391
|
+
}
|
|
392
|
+
oSettings.nTFoot = tfoot[0];
|
|
393
|
+
$('tr', tfoot).addClass(oClasses.tfoot.row);
|
|
428
394
|
|
|
429
|
-
|
|
430
|
-
|
|
395
|
+
// Copy the data index array
|
|
396
|
+
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
|
|
431
397
|
|
|
432
|
-
|
|
433
|
-
|
|
398
|
+
// Initialisation complete - table can be drawn
|
|
399
|
+
oSettings.bInitialised = true;
|
|
434
400
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if ( bInitHandedOff === false ) {
|
|
439
|
-
_fnInitialise( oSettings );
|
|
440
|
-
}
|
|
441
|
-
};
|
|
401
|
+
// Language definitions
|
|
402
|
+
var oLanguage = oSettings.oLanguage;
|
|
403
|
+
$.extend( true, oLanguage, oInit.oLanguage );
|
|
442
404
|
|
|
443
|
-
|
|
444
|
-
|
|
405
|
+
if ( oLanguage.sUrl ) {
|
|
406
|
+
// Get the language definitions from a file
|
|
407
|
+
$.ajax( {
|
|
408
|
+
dataType: 'json',
|
|
409
|
+
url: oLanguage.sUrl,
|
|
410
|
+
success: function ( json ) {
|
|
411
|
+
_fnCamelToHungarian( defaults.oLanguage, json );
|
|
412
|
+
$.extend( true, oLanguage, json, oSettings.oInit.oLanguage );
|
|
445
413
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
414
|
+
_fnCallbackFire( oSettings, null, 'i18n', [oSettings], true);
|
|
415
|
+
_fnInitialise( oSettings );
|
|
416
|
+
},
|
|
417
|
+
error: function () {
|
|
418
|
+
// Error occurred loading language file
|
|
419
|
+
_fnLog( oSettings, 0, 'i18n file loading error', 21 );
|
|
420
|
+
|
|
421
|
+
// Continue on as best we can
|
|
422
|
+
_fnInitialise( oSettings );
|
|
423
|
+
}
|
|
424
|
+
} );
|
|
450
425
|
}
|
|
451
426
|
else {
|
|
452
|
-
|
|
427
|
+
_fnCallbackFire( oSettings, null, 'i18n', [oSettings]);
|
|
428
|
+
_fnInitialise( oSettings );
|
|
453
429
|
}
|
|
454
|
-
|
|
455
430
|
} );
|
|
456
431
|
_that = null;
|
|
457
432
|
return this;
|
|
@@ -968,6 +943,15 @@ $.extend( DataTable.ext.classes, {
|
|
|
968
943
|
info: {
|
|
969
944
|
container: 'dt-info'
|
|
970
945
|
},
|
|
946
|
+
layout: {
|
|
947
|
+
row: 'dt-layout-row',
|
|
948
|
+
cell: 'dt-layout-cell',
|
|
949
|
+
tableRow: 'dt-layout-table',
|
|
950
|
+
tableCell: '',
|
|
951
|
+
start: 'dt-layout-start',
|
|
952
|
+
end: 'dt-layout-end',
|
|
953
|
+
full: 'dt-layout-full'
|
|
954
|
+
},
|
|
971
955
|
length: {
|
|
972
956
|
container: 'dt-length',
|
|
973
957
|
select: 'dt-input'
|
|
@@ -1091,7 +1075,7 @@ var _numToDecimal = function ( num, decimalPoint ) {
|
|
|
1091
1075
|
};
|
|
1092
1076
|
|
|
1093
1077
|
|
|
1094
|
-
var _isNumber = function ( d, decimalPoint, formatted ) {
|
|
1078
|
+
var _isNumber = function ( d, decimalPoint, formatted, allowEmpty ) {
|
|
1095
1079
|
var type = typeof d;
|
|
1096
1080
|
var strType = type === 'string';
|
|
1097
1081
|
|
|
@@ -1102,7 +1086,7 @@ var _isNumber = function ( d, decimalPoint, formatted ) {
|
|
|
1102
1086
|
// If empty return immediately so there must be a number if it is a
|
|
1103
1087
|
// formatted string (this stops the string "k", or "kr", etc being detected
|
|
1104
1088
|
// as a formatted number for currency
|
|
1105
|
-
if ( _empty( d ) ) {
|
|
1089
|
+
if ( allowEmpty && _empty( d ) ) {
|
|
1106
1090
|
return true;
|
|
1107
1091
|
}
|
|
1108
1092
|
|
|
@@ -1124,8 +1108,8 @@ var _isHtml = function ( d ) {
|
|
|
1124
1108
|
};
|
|
1125
1109
|
|
|
1126
1110
|
// Is a string a number surrounded by HTML?
|
|
1127
|
-
var _htmlNumeric = function ( d, decimalPoint, formatted ) {
|
|
1128
|
-
if ( _empty( d ) ) {
|
|
1111
|
+
var _htmlNumeric = function ( d, decimalPoint, formatted, allowEmpty ) {
|
|
1112
|
+
if ( allowEmpty && _empty( d ) ) {
|
|
1129
1113
|
return true;
|
|
1130
1114
|
}
|
|
1131
1115
|
|
|
@@ -1137,7 +1121,7 @@ var _htmlNumeric = function ( d, decimalPoint, formatted ) {
|
|
|
1137
1121
|
var html = _isHtml( d );
|
|
1138
1122
|
return ! html ?
|
|
1139
1123
|
null :
|
|
1140
|
-
_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
|
|
1124
|
+
_isNumber( _stripHtml( d ), decimalPoint, formatted, allowEmpty ) ?
|
|
1141
1125
|
true :
|
|
1142
1126
|
null;
|
|
1143
1127
|
};
|
|
@@ -1233,6 +1217,10 @@ var _removeEmpty = function ( a )
|
|
|
1233
1217
|
|
|
1234
1218
|
// Replaceable function in api.util
|
|
1235
1219
|
var _stripHtml = function (input) {
|
|
1220
|
+
if (! input) {
|
|
1221
|
+
return input;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1236
1224
|
// Irrelevant check to workaround CodeQL's false positive on the regex
|
|
1237
1225
|
if (input.length > _max_str_len) {
|
|
1238
1226
|
throw new Error('Exceeded max str len');
|
|
@@ -2199,6 +2187,21 @@ function _fnGetColumns( oSettings, sParam )
|
|
|
2199
2187
|
return a;
|
|
2200
2188
|
}
|
|
2201
2189
|
|
|
2190
|
+
/**
|
|
2191
|
+
* Allow the result from a type detection function to be `true` while
|
|
2192
|
+
* translating that into a string. Old type detection functions will
|
|
2193
|
+
* return the type name if it passes. An obect store would be better,
|
|
2194
|
+
* but not backwards compatible.
|
|
2195
|
+
*
|
|
2196
|
+
* @param {*} typeDetect Object or function for type detection
|
|
2197
|
+
* @param {*} res Result from the type detection function
|
|
2198
|
+
* @returns Type name or false
|
|
2199
|
+
*/
|
|
2200
|
+
function _typeResult (typeDetect, res) {
|
|
2201
|
+
return res === true
|
|
2202
|
+
? typeDetect.name
|
|
2203
|
+
: res;
|
|
2204
|
+
}
|
|
2202
2205
|
|
|
2203
2206
|
/**
|
|
2204
2207
|
* Calculate the 'type' of a column
|
|
@@ -2213,7 +2216,13 @@ function _fnColumnTypes ( settings )
|
|
|
2213
2216
|
var i, ien, j, jen, k, ken;
|
|
2214
2217
|
var col, detectedType, cache;
|
|
2215
2218
|
|
|
2216
|
-
//
|
|
2219
|
+
// If SSP then we don't have the full data set, so any type detection would be
|
|
2220
|
+
// unreliable and error prone
|
|
2221
|
+
if (_fnDataSource( settings ) === 'ssp') {
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// For each column, spin over the data type detection functions, seeing if one matches
|
|
2217
2226
|
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
|
2218
2227
|
col = columns[i];
|
|
2219
2228
|
cache = [];
|
|
@@ -2223,8 +2232,27 @@ function _fnColumnTypes ( settings )
|
|
|
2223
2232
|
}
|
|
2224
2233
|
else if ( ! col.sType ) {
|
|
2225
2234
|
for ( j=0, jen=types.length ; j<jen ; j++ ) {
|
|
2226
|
-
|
|
2235
|
+
var typeDetect = types[j];
|
|
2236
|
+
|
|
2237
|
+
// There can be either one, or three type detection functions
|
|
2238
|
+
var oneOf = typeDetect.oneOf;
|
|
2239
|
+
var allOf = typeDetect.allOf || typeDetect;
|
|
2240
|
+
var init = typeDetect.init;
|
|
2241
|
+
var one = false;
|
|
2242
|
+
|
|
2243
|
+
detectedType = null;
|
|
2244
|
+
|
|
2245
|
+
// Fast detect based on column assignment
|
|
2246
|
+
if (init) {
|
|
2247
|
+
detectedType = _typeResult(typeDetect, init(settings, col, i));
|
|
2248
|
+
|
|
2249
|
+
if (detectedType) {
|
|
2250
|
+
col.sType = detectedType;
|
|
2251
|
+
break;
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2227
2254
|
|
|
2255
|
+
for ( k=0, ken=data.length ; k<ken ; k++ ) {
|
|
2228
2256
|
if (! data[k]) {
|
|
2229
2257
|
continue;
|
|
2230
2258
|
}
|
|
@@ -2235,14 +2263,20 @@ function _fnColumnTypes ( settings )
|
|
|
2235
2263
|
cache[k] = _fnGetCellData( settings, k, i, 'type' );
|
|
2236
2264
|
}
|
|
2237
2265
|
|
|
2238
|
-
|
|
2266
|
+
// Only one data point in the column needs to match this function
|
|
2267
|
+
if (oneOf && ! one) {
|
|
2268
|
+
one = _typeResult(typeDetect, oneOf( cache[k], settings ));
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
// All data points need to match this function
|
|
2272
|
+
detectedType = _typeResult(typeDetect, allOf( cache[k], settings ));
|
|
2239
2273
|
|
|
2240
2274
|
// If null, then this type can't apply to this column, so
|
|
2241
2275
|
// rather than testing all cells, break out. There is an
|
|
2242
2276
|
// exception for the last type which is `html`. We need to
|
|
2243
2277
|
// scan all rows since it is possible to mix string and HTML
|
|
2244
2278
|
// types
|
|
2245
|
-
if ( ! detectedType && j !== types.length-
|
|
2279
|
+
if ( ! detectedType && j !== types.length-3 ) {
|
|
2246
2280
|
break;
|
|
2247
2281
|
}
|
|
2248
2282
|
|
|
@@ -2256,7 +2290,7 @@ function _fnColumnTypes ( settings )
|
|
|
2256
2290
|
|
|
2257
2291
|
// Type is valid for all data points in the column - use this
|
|
2258
2292
|
// type
|
|
2259
|
-
if ( detectedType ) {
|
|
2293
|
+
if ( (oneOf && one && detectedType) || (!oneOf && detectedType) ) {
|
|
2260
2294
|
col.sType = detectedType;
|
|
2261
2295
|
break;
|
|
2262
2296
|
}
|
|
@@ -2278,7 +2312,7 @@ function _fnColumnTypes ( settings )
|
|
|
2278
2312
|
|
|
2279
2313
|
var renderer = _ext.type.render[col.sType];
|
|
2280
2314
|
|
|
2281
|
-
// This can only happen once! There is no way to
|
|
2315
|
+
// This can only happen once! There is no way to remove
|
|
2282
2316
|
// a renderer. After the first time the renderer has
|
|
2283
2317
|
// already been set so createTr will run the renderer itself.
|
|
2284
2318
|
if (renderer && ! col._render) {
|
|
@@ -3322,7 +3356,13 @@ function _fnDraw( oSettings, ajaxComplete )
|
|
|
3322
3356
|
oSettings.bDrawing = true;
|
|
3323
3357
|
|
|
3324
3358
|
/* Server-side processing draw intercept */
|
|
3325
|
-
if (
|
|
3359
|
+
if ( oSettings.deferLoading )
|
|
3360
|
+
{
|
|
3361
|
+
oSettings.deferLoading = false;
|
|
3362
|
+
oSettings.iDraw++;
|
|
3363
|
+
_fnProcessingDisplay( oSettings, false );
|
|
3364
|
+
}
|
|
3365
|
+
else if ( !bServerSide )
|
|
3326
3366
|
{
|
|
3327
3367
|
oSettings.iDraw++;
|
|
3328
3368
|
}
|
|
@@ -3423,6 +3463,9 @@ function _fnReDraw( settings, holdPosition, recompute )
|
|
|
3423
3463
|
filter = features.bFilter;
|
|
3424
3464
|
|
|
3425
3465
|
if (recompute === undefined || recompute === true) {
|
|
3466
|
+
// Resolve any column types that are unknown due to addition or invalidation
|
|
3467
|
+
_fnColumnTypes( settings );
|
|
3468
|
+
|
|
3426
3469
|
if ( sort ) {
|
|
3427
3470
|
_fnSort( settings );
|
|
3428
3471
|
}
|
|
@@ -3478,113 +3521,154 @@ function _emptyRow ( settings ) {
|
|
|
3478
3521
|
|
|
3479
3522
|
|
|
3480
3523
|
/**
|
|
3481
|
-
*
|
|
3482
|
-
* for the renderer. This is done twice, once for above and once for below
|
|
3483
|
-
* the table. Ordering must also be considered.
|
|
3484
|
-
*
|
|
3485
|
-
* @param {*} settings DataTables settings object
|
|
3486
|
-
* @param {*} layout Layout object to convert
|
|
3487
|
-
* @param {string} side `top` or `bottom`
|
|
3488
|
-
* @returns Converted array structure - one item for each row.
|
|
3524
|
+
* Expand the layout items into an object for the rendering function
|
|
3489
3525
|
*/
|
|
3490
|
-
function
|
|
3491
|
-
{
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
// Combine into like groups (e.g. `top`, `top2`, etc)
|
|
3495
|
-
$.each( layout, function ( pos, val ) {
|
|
3496
|
-
if (val === null) {
|
|
3497
|
-
return;
|
|
3526
|
+
function _layoutItems (row, align, items) {
|
|
3527
|
+
if ( Array.isArray(items)) {
|
|
3528
|
+
for (var i=0 ; i<items.length ; i++) {
|
|
3529
|
+
_layoutItems(row, align, items[i]);
|
|
3498
3530
|
}
|
|
3499
3531
|
|
|
3500
|
-
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3501
3534
|
|
|
3502
|
-
|
|
3503
|
-
groups[ splitPos[0] ] = {};
|
|
3504
|
-
}
|
|
3535
|
+
var rowCell = row[align];
|
|
3505
3536
|
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
if ( $.isPlainObject( innerVal ) ) {
|
|
3513
|
-
Object.keys(innerVal).map(function (key) {
|
|
3514
|
-
contents.push( {
|
|
3515
|
-
feature: key,
|
|
3516
|
-
opts: innerVal[key]
|
|
3517
|
-
});
|
|
3518
|
-
});
|
|
3537
|
+
// If it is an object, then there can be multiple features contained in it
|
|
3538
|
+
if ( $.isPlainObject( items ) ) {
|
|
3539
|
+
// A feature plugin cannot be named "features" due to this check
|
|
3540
|
+
if (items.features) {
|
|
3541
|
+
if (items.rowId) {
|
|
3542
|
+
row.id = items.rowId;
|
|
3519
3543
|
}
|
|
3520
|
-
|
|
3521
|
-
|
|
3544
|
+
if (items.rowClass) {
|
|
3545
|
+
row.className = items.rowClass;
|
|
3522
3546
|
}
|
|
3523
|
-
}
|
|
3524
3547
|
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3548
|
+
rowCell.id = items.id;
|
|
3549
|
+
rowCell.className = items.className;
|
|
3550
|
+
|
|
3551
|
+
_layoutItems(row, align, items.features);
|
|
3552
|
+
}
|
|
3553
|
+
else {
|
|
3554
|
+
Object.keys(items).map(function (key) {
|
|
3555
|
+
rowCell.contents.push( {
|
|
3556
|
+
feature: key,
|
|
3557
|
+
opts: items[key]
|
|
3558
|
+
});
|
|
3559
|
+
});
|
|
3528
3560
|
}
|
|
3561
|
+
}
|
|
3562
|
+
else {
|
|
3563
|
+
rowCell.contents.push(items);
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3567
|
+
/**
|
|
3568
|
+
* Find, or create a layout row
|
|
3569
|
+
*/
|
|
3570
|
+
function _layoutGetRow(rows, rowNum, align) {
|
|
3571
|
+
var row;
|
|
3572
|
+
|
|
3573
|
+
// Find existing rows
|
|
3574
|
+
for (var i=0; i<rows.length; i++) {
|
|
3575
|
+
row = rows[i];
|
|
3576
|
+
|
|
3577
|
+
if (row.rowNum === rowNum) {
|
|
3578
|
+
// full is on its own, but start and end share a row
|
|
3579
|
+
if (
|
|
3580
|
+
(align === 'full' && row.full) ||
|
|
3581
|
+
((align === 'start' || align === 'end') && (row.start || row.end))
|
|
3582
|
+
) {
|
|
3583
|
+
if (! row[align]) {
|
|
3584
|
+
row[align] = {
|
|
3585
|
+
contents: []
|
|
3586
|
+
};
|
|
3587
|
+
}
|
|
3529
3588
|
|
|
3530
|
-
|
|
3531
|
-
if ( Array.isArray(val)) {
|
|
3532
|
-
for (var i=0 ; i<val.length ; i++) {
|
|
3533
|
-
groupRun(group[align].contents, val[i]);
|
|
3589
|
+
return row;
|
|
3534
3590
|
}
|
|
3535
3591
|
}
|
|
3536
|
-
|
|
3537
|
-
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3594
|
+
// If we get this far, then there was no match, create a new row
|
|
3595
|
+
row = {
|
|
3596
|
+
rowNum: rowNum
|
|
3597
|
+
};
|
|
3598
|
+
|
|
3599
|
+
row[align] = {
|
|
3600
|
+
contents: []
|
|
3601
|
+
};
|
|
3602
|
+
|
|
3603
|
+
rows.push(row);
|
|
3604
|
+
|
|
3605
|
+
return row;
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
/**
|
|
3609
|
+
* Convert a `layout` object given by a user to the object structure needed
|
|
3610
|
+
* for the renderer. This is done twice, once for above and once for below
|
|
3611
|
+
* the table. Ordering must also be considered.
|
|
3612
|
+
*
|
|
3613
|
+
* @param {*} settings DataTables settings object
|
|
3614
|
+
* @param {*} layout Layout object to convert
|
|
3615
|
+
* @param {string} side `top` or `bottom`
|
|
3616
|
+
* @returns Converted array structure - one item for each row.
|
|
3617
|
+
*/
|
|
3618
|
+
function _layoutArray ( settings, layout, side ) {
|
|
3619
|
+
var rows = [];
|
|
3620
|
+
|
|
3621
|
+
// Split out into an array
|
|
3622
|
+
$.each( layout, function ( pos, items ) {
|
|
3623
|
+
if (items === null) {
|
|
3624
|
+
return;
|
|
3538
3625
|
}
|
|
3539
3626
|
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3627
|
+
var parts = pos.match(/^([a-z]+)([0-9]*)([A-Za-z]*)$/);
|
|
3628
|
+
var rowNum = parts[2]
|
|
3629
|
+
? parts[2] * 1
|
|
3630
|
+
: 0;
|
|
3631
|
+
var align = parts[3]
|
|
3632
|
+
? parts[3].toLowerCase()
|
|
3633
|
+
: 'full';
|
|
3634
|
+
|
|
3635
|
+
// Filter out the side we aren't interested in
|
|
3636
|
+
if (parts[1] !== side) {
|
|
3637
|
+
return;
|
|
3543
3638
|
}
|
|
3544
|
-
} );
|
|
3545
3639
|
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
// Filter to only the side we need
|
|
3549
|
-
if ( pos.indexOf(side) !== 0 ) {
|
|
3550
|
-
return null;
|
|
3551
|
-
}
|
|
3640
|
+
// Get or create the row we should attach to
|
|
3641
|
+
var row = _layoutGetRow(rows, rowNum, align);
|
|
3552
3642
|
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
val: groups[pos]
|
|
3556
|
-
};
|
|
3557
|
-
} )
|
|
3558
|
-
.filter( function (item) {
|
|
3559
|
-
return item !== null;
|
|
3560
|
-
});
|
|
3643
|
+
_layoutItems(row, align, items);
|
|
3644
|
+
});
|
|
3561
3645
|
|
|
3562
3646
|
// Order by item identifier
|
|
3563
|
-
|
|
3564
|
-
var order1 = a.
|
|
3565
|
-
var order2 = b.
|
|
3647
|
+
rows.sort( function ( a, b ) {
|
|
3648
|
+
var order1 = a.rowNum;
|
|
3649
|
+
var order2 = b.rowNum;
|
|
3650
|
+
|
|
3651
|
+
// If both in the same row, then the row with `full` comes first
|
|
3652
|
+
if (order1 === order2) {
|
|
3653
|
+
var ret = a.full && ! b.full ? -1 : 1;
|
|
3654
|
+
|
|
3655
|
+
return side === 'bottom'
|
|
3656
|
+
? ret * -1
|
|
3657
|
+
: ret;
|
|
3658
|
+
}
|
|
3566
3659
|
|
|
3567
3660
|
return order2 - order1;
|
|
3568
3661
|
} );
|
|
3569
|
-
|
|
3662
|
+
|
|
3663
|
+
// Invert for below the table
|
|
3570
3664
|
if ( side === 'bottom' ) {
|
|
3571
|
-
|
|
3665
|
+
rows.reverse();
|
|
3572
3666
|
}
|
|
3573
3667
|
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
for ( var i=0, ien=filtered.length ; i<ien ; i++ ) {
|
|
3577
|
-
if ( filtered[i].val.full ) {
|
|
3578
|
-
rows.push( { full: filtered[i].val.full } );
|
|
3579
|
-
_layoutResolve( settings, rows[ rows.length - 1 ] );
|
|
3580
|
-
|
|
3581
|
-
delete filtered[i].val.full;
|
|
3582
|
-
}
|
|
3668
|
+
for (var row = 0; row<rows.length; row++) {
|
|
3669
|
+
delete rows[row].rowNum;
|
|
3583
3670
|
|
|
3584
|
-
|
|
3585
|
-
rows.push( filtered[i].val );
|
|
3586
|
-
_layoutResolve( settings, rows[ rows.length - 1 ] );
|
|
3587
|
-
}
|
|
3671
|
+
_layoutResolve(settings, rows[row]);
|
|
3588
3672
|
}
|
|
3589
3673
|
|
|
3590
3674
|
return rows;
|
|
@@ -3608,6 +3692,10 @@ function _layoutResolve( settings, row ) {
|
|
|
3608
3692
|
};
|
|
3609
3693
|
|
|
3610
3694
|
var resolve = function ( item ) {
|
|
3695
|
+
if (! row[ item ]) {
|
|
3696
|
+
return;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3611
3699
|
var line = row[ item ].contents;
|
|
3612
3700
|
|
|
3613
3701
|
for ( var i=0, ien=line.length ; i<ien ; i++ ) {
|
|
@@ -3635,9 +3723,9 @@ function _layoutResolve( settings, row ) {
|
|
|
3635
3723
|
}
|
|
3636
3724
|
};
|
|
3637
3725
|
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3726
|
+
resolve('start');
|
|
3727
|
+
resolve('end');
|
|
3728
|
+
resolve('full');
|
|
3641
3729
|
}
|
|
3642
3730
|
|
|
3643
3731
|
|
|
@@ -3970,6 +4058,17 @@ function _fnBuildAjax( oSettings, data, fn )
|
|
|
3970
4058
|
_fnLog( oSettings, 0, error );
|
|
3971
4059
|
}
|
|
3972
4060
|
|
|
4061
|
+
// Microsoft often wrap JSON as a string in another JSON object
|
|
4062
|
+
// Let's handle that automatically
|
|
4063
|
+
if (json.d && typeof json.d === 'string') {
|
|
4064
|
+
try {
|
|
4065
|
+
json = JSON.parse(json.d);
|
|
4066
|
+
}
|
|
4067
|
+
catch (e) {
|
|
4068
|
+
// noop
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
|
|
3973
4072
|
oSettings.json = json;
|
|
3974
4073
|
|
|
3975
4074
|
_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR], true );
|
|
@@ -4046,11 +4145,11 @@ function _fnBuildAjax( oSettings, data, fn )
|
|
|
4046
4145
|
else {
|
|
4047
4146
|
// Object to extend the base settings
|
|
4048
4147
|
oSettings.jqXHR = $.ajax( baseAjax );
|
|
4148
|
+
}
|
|
4049
4149
|
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
}
|
|
4150
|
+
// Restore for next time around
|
|
4151
|
+
if ( ajaxData ) {
|
|
4152
|
+
ajax.data = ajaxData;
|
|
4054
4153
|
}
|
|
4055
4154
|
}
|
|
4056
4155
|
|
|
@@ -4275,10 +4374,6 @@ function _fnFilterComplete ( settings, input )
|
|
|
4275
4374
|
{
|
|
4276
4375
|
var columnsSearch = settings.aoPreSearchCols;
|
|
4277
4376
|
|
|
4278
|
-
// Resolve any column types that are unknown due to addition or invalidation
|
|
4279
|
-
// @todo As per sort - can this be moved into an event handler?
|
|
4280
|
-
_fnColumnTypes( settings );
|
|
4281
|
-
|
|
4282
4377
|
// In server-side processing all filtering is done by the server, so no point hanging around here
|
|
4283
4378
|
if ( _fnDataSource( settings ) != 'ssp' )
|
|
4284
4379
|
{
|
|
@@ -4584,8 +4679,11 @@ function _fnFilterData ( settings )
|
|
|
4584
4679
|
function _fnInitialise ( settings )
|
|
4585
4680
|
{
|
|
4586
4681
|
var i, iAjaxStart=settings.iInitDisplayStart;
|
|
4682
|
+
var init = settings.oInit;
|
|
4683
|
+
var deferLoading = settings.deferLoading;
|
|
4684
|
+
var dataSrc = _fnDataSource( settings );
|
|
4587
4685
|
|
|
4588
|
-
|
|
4686
|
+
// Ensure that the table data is fully initialised
|
|
4589
4687
|
if ( ! settings.bInitialised ) {
|
|
4590
4688
|
setTimeout( function(){ _fnInitialise( settings ); }, 200 );
|
|
4591
4689
|
return;
|
|
@@ -4597,52 +4695,68 @@ function _fnInitialise ( settings )
|
|
|
4597
4695
|
_fnDrawHead( settings, settings.aoHeader );
|
|
4598
4696
|
_fnDrawHead( settings, settings.aoFooter );
|
|
4599
4697
|
|
|
4600
|
-
//
|
|
4601
|
-
|
|
4602
|
-
|
|
4698
|
+
// Load the table's state (if needed) and then render around it and draw draw
|
|
4699
|
+
_fnLoadState( settings, init, function () {
|
|
4700
|
+
// Local data load
|
|
4701
|
+
// Check if there is data passing into the constructor
|
|
4702
|
+
if ( init.aaData ) {
|
|
4703
|
+
for ( i=0 ; i<init.aaData.length ; i++ ) {
|
|
4704
|
+
_fnAddData( settings, init.aaData[ i ] );
|
|
4705
|
+
}
|
|
4706
|
+
}
|
|
4707
|
+
else if ( deferLoading || dataSrc == 'dom' ) {
|
|
4708
|
+
// Grab the data from the page
|
|
4709
|
+
_fnAddTr( settings, $(settings.nTBody).children('tr') );
|
|
4710
|
+
}
|
|
4603
4711
|
|
|
4604
|
-
|
|
4712
|
+
// Filter not yet applied - copy the display master
|
|
4713
|
+
settings.aiDisplay = settings.aiDisplayMaster.slice();
|
|
4605
4714
|
|
|
4606
|
-
|
|
4607
|
-
|
|
4715
|
+
// Enable features
|
|
4716
|
+
_fnAddOptionsHtml( settings );
|
|
4717
|
+
_fnSortInit( settings );
|
|
4608
4718
|
|
|
4609
|
-
|
|
4719
|
+
_colGroup( settings );
|
|
4610
4720
|
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
// Ajax source - this allows the table to look initialised for Ajax sourcing
|
|
4614
|
-
// data (show 'loading' message possibly)
|
|
4615
|
-
_fnReDraw( settings );
|
|
4721
|
+
/* Okay to show that something is going on now */
|
|
4722
|
+
_fnProcessingDisplay( settings, true );
|
|
4616
4723
|
|
|
4617
|
-
|
|
4724
|
+
_fnCallbackFire( settings, null, 'preInit', [settings], true );
|
|
4618
4725
|
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
//
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
var aData = _fnAjaxDataSrc( settings, json );
|
|
4726
|
+
// If there is default sorting required - let's do it. The sort function
|
|
4727
|
+
// will do the drawing for us. Otherwise we draw the table regardless of the
|
|
4728
|
+
// Ajax source - this allows the table to look initialised for Ajax sourcing
|
|
4729
|
+
// data (show 'loading' message possibly)
|
|
4730
|
+
_fnReDraw( settings );
|
|
4625
4731
|
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4732
|
+
// Server-side processing init complete is done by _fnAjaxUpdateDraw
|
|
4733
|
+
if ( dataSrc != 'ssp' || deferLoading ) {
|
|
4734
|
+
// if there is an ajax source load the data
|
|
4735
|
+
if ( dataSrc == 'ajax' ) {
|
|
4736
|
+
_fnBuildAjax( settings, {}, function(json) {
|
|
4737
|
+
var aData = _fnAjaxDataSrc( settings, json );
|
|
4630
4738
|
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4739
|
+
// Got the data - add it to the table
|
|
4740
|
+
for ( i=0 ; i<aData.length ; i++ ) {
|
|
4741
|
+
_fnAddData( settings, aData[i] );
|
|
4742
|
+
}
|
|
4635
4743
|
|
|
4636
|
-
|
|
4637
|
-
|
|
4744
|
+
// Reset the init display for cookie saving. We've already done
|
|
4745
|
+
// a filter, and therefore cleared it before. So we need to make
|
|
4746
|
+
// it appear 'fresh'
|
|
4747
|
+
settings.iInitDisplayStart = iAjaxStart;
|
|
4748
|
+
|
|
4749
|
+
_fnReDraw( settings );
|
|
4750
|
+
_fnProcessingDisplay( settings, false );
|
|
4751
|
+
_fnInitComplete( settings );
|
|
4752
|
+
}, settings );
|
|
4753
|
+
}
|
|
4754
|
+
else {
|
|
4638
4755
|
_fnInitComplete( settings );
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
else {
|
|
4642
|
-
_fnInitComplete( settings );
|
|
4643
|
-
_fnProcessingDisplay( settings, false );
|
|
4756
|
+
_fnProcessingDisplay( settings, false );
|
|
4757
|
+
}
|
|
4644
4758
|
}
|
|
4645
|
-
}
|
|
4759
|
+
} );
|
|
4646
4760
|
}
|
|
4647
4761
|
|
|
4648
4762
|
|
|
@@ -4799,6 +4913,30 @@ function _fnProcessingDisplay ( settings, show )
|
|
|
4799
4913
|
{
|
|
4800
4914
|
_fnCallbackFire( settings, null, 'processing', [settings, show] );
|
|
4801
4915
|
}
|
|
4916
|
+
|
|
4917
|
+
/**
|
|
4918
|
+
* Show the processing element if an action takes longer than a given time
|
|
4919
|
+
*
|
|
4920
|
+
* @param {*} settings DataTables settings object
|
|
4921
|
+
* @param {*} enable Do (true) or not (false) async processing (local feature enablement)
|
|
4922
|
+
* @param {*} run Function to run
|
|
4923
|
+
*/
|
|
4924
|
+
function _fnProcessingRun( settings, enable, run ) {
|
|
4925
|
+
if (! enable) {
|
|
4926
|
+
// Immediate execution, synchronous
|
|
4927
|
+
run();
|
|
4928
|
+
}
|
|
4929
|
+
else {
|
|
4930
|
+
_fnProcessingDisplay(settings, true);
|
|
4931
|
+
|
|
4932
|
+
// Allow the processing display to show if needed
|
|
4933
|
+
setTimeout(function () {
|
|
4934
|
+
run();
|
|
4935
|
+
|
|
4936
|
+
_fnProcessingDisplay(settings, false);
|
|
4937
|
+
}, 0);
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4802
4940
|
/**
|
|
4803
4941
|
* Add any control elements for the table - specifically scrolling
|
|
4804
4942
|
* @param {object} settings dataTables settings object
|
|
@@ -5129,8 +5267,17 @@ function _fnCalculateColumnWidths ( settings )
|
|
|
5129
5267
|
tableWidthAttr = table.getAttribute('width'), // from DOM element
|
|
5130
5268
|
tableContainer = table.parentNode,
|
|
5131
5269
|
i, column, columnIdx;
|
|
5132
|
-
|
|
5270
|
+
|
|
5133
5271
|
var styleWidth = table.style.width;
|
|
5272
|
+
|
|
5273
|
+
// If there is no width applied as a CSS style or as an attribute, we assume that
|
|
5274
|
+
// the width is intended to be 100%, which is usually is in CSS, but it is very
|
|
5275
|
+
// difficult to correctly parse the rules to get the final result.
|
|
5276
|
+
if ( ! styleWidth && ! tableWidthAttr) {
|
|
5277
|
+
table.style.width = '100%';
|
|
5278
|
+
styleWidth = '100%';
|
|
5279
|
+
}
|
|
5280
|
+
|
|
5134
5281
|
if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
|
|
5135
5282
|
tableWidthAttr = styleWidth;
|
|
5136
5283
|
}
|
|
@@ -5444,22 +5591,16 @@ function _fnSortAttachListener(settings, node, selector, column, callback) {
|
|
|
5444
5591
|
}
|
|
5445
5592
|
|
|
5446
5593
|
if (run) {
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
// Allow the processing display to show
|
|
5450
|
-
setTimeout( function () {
|
|
5594
|
+
_fnProcessingRun(settings, true, function () {
|
|
5451
5595
|
_fnSort( settings );
|
|
5452
5596
|
_fnSortDisplay( settings, settings.aiDisplay );
|
|
5453
5597
|
|
|
5454
|
-
// Sort processing done - redraw has its own processing display
|
|
5455
|
-
_fnProcessingDisplay( settings, false );
|
|
5456
|
-
|
|
5457
5598
|
_fnReDraw( settings, false, false );
|
|
5458
5599
|
|
|
5459
5600
|
if (callback) {
|
|
5460
5601
|
callback();
|
|
5461
5602
|
}
|
|
5462
|
-
}
|
|
5603
|
+
});
|
|
5463
5604
|
}
|
|
5464
5605
|
}
|
|
5465
5606
|
} );
|
|
@@ -5618,11 +5759,6 @@ function _fnSort ( oSettings, col, dir )
|
|
|
5618
5759
|
displayMaster = oSettings.aiDisplayMaster,
|
|
5619
5760
|
aSort;
|
|
5620
5761
|
|
|
5621
|
-
// Resolve any column types that are unknown due to addition or invalidation
|
|
5622
|
-
// @todo Can this be moved into a 'data-ready' handler which is called when
|
|
5623
|
-
// data is going to be used in the table?
|
|
5624
|
-
_fnColumnTypes( oSettings );
|
|
5625
|
-
|
|
5626
5762
|
// Allow a specific column to be sorted, which will _not_ alter the display
|
|
5627
5763
|
// master
|
|
5628
5764
|
if (col !== undefined) {
|
|
@@ -5659,7 +5795,7 @@ function _fnSort ( oSettings, col, dir )
|
|
|
5659
5795
|
|
|
5660
5796
|
// If the first sort is desc, then reverse the array to preserve original
|
|
5661
5797
|
// order, just in reverse
|
|
5662
|
-
if (aSort.length && aSort[0].dir === 'desc') {
|
|
5798
|
+
if (aSort.length && aSort[0].dir === 'desc' && oSettings.orderDescReverse) {
|
|
5663
5799
|
aiOrig.reverse();
|
|
5664
5800
|
}
|
|
5665
5801
|
|
|
@@ -5729,6 +5865,7 @@ function _fnSort ( oSettings, col, dir )
|
|
|
5729
5865
|
if (col === undefined) {
|
|
5730
5866
|
// Tell the draw function that we have sorted the data
|
|
5731
5867
|
oSettings.bSorted = true;
|
|
5868
|
+
oSettings.sortDetails = aSort;
|
|
5732
5869
|
|
|
5733
5870
|
_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort] );
|
|
5734
5871
|
}
|
|
@@ -7507,6 +7644,16 @@ var _selector_row_indexes = function ( settings, opts )
|
|
|
7507
7644
|
order = opts.order, // applied, current, index (original - compatibility with 1.9)
|
|
7508
7645
|
page = opts.page; // all, current
|
|
7509
7646
|
|
|
7647
|
+
if ( _fnDataSource( settings ) == 'ssp' ) {
|
|
7648
|
+
// In server-side processing mode, most options are irrelevant since
|
|
7649
|
+
// rows not shown don't exist and the index order is the applied order
|
|
7650
|
+
// Removed is a special case - for consistency just return an empty
|
|
7651
|
+
// array
|
|
7652
|
+
return search === 'removed' ?
|
|
7653
|
+
[] :
|
|
7654
|
+
_range( 0, displayMaster.length );
|
|
7655
|
+
}
|
|
7656
|
+
|
|
7510
7657
|
if ( page == 'current' ) {
|
|
7511
7658
|
// Current page implies that order=current and filter=applied, since it is
|
|
7512
7659
|
// fairly senseless otherwise, regardless of what order and search actually
|
|
@@ -8178,7 +8325,7 @@ _api_register( [
|
|
|
8178
8325
|
_api_register( _child_obj+'.isShown()', function () {
|
|
8179
8326
|
var ctx = this.context;
|
|
8180
8327
|
|
|
8181
|
-
if ( ctx.length && this.length ) {
|
|
8328
|
+
if ( ctx.length && this.length && ctx[0].aoData[ this[0] ] ) {
|
|
8182
8329
|
// _detailsShown as false or undefined will fall through to return false
|
|
8183
8330
|
return ctx[0].aoData[ this[0] ]._detailsShow || false;
|
|
8184
8331
|
}
|
|
@@ -8201,7 +8348,7 @@ _api_register( _child_obj+'.isShown()', function () {
|
|
|
8201
8348
|
// can be an array of these items, comma separated list, or an array of comma
|
|
8202
8349
|
// separated lists
|
|
8203
8350
|
|
|
8204
|
-
var __re_column_selector = /^([^:]+)
|
|
8351
|
+
var __re_column_selector = /^([^:]+)?:(name|title|visIdx|visible)$/;
|
|
8205
8352
|
|
|
8206
8353
|
|
|
8207
8354
|
// r1 and r2 are redundant - but it means that the parameters match for the
|
|
@@ -8273,17 +8420,24 @@ var __column_selector = function ( settings, selector, opts )
|
|
|
8273
8420
|
switch( match[2] ) {
|
|
8274
8421
|
case 'visIdx':
|
|
8275
8422
|
case 'visible':
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8423
|
+
if (match[1]) {
|
|
8424
|
+
var idx = parseInt( match[1], 10 );
|
|
8425
|
+
// Visible index given, convert to column index
|
|
8426
|
+
if ( idx < 0 ) {
|
|
8427
|
+
// Counting from the right
|
|
8428
|
+
var visColumns = columns.map( function (col,i) {
|
|
8429
|
+
return col.bVisible ? i : null;
|
|
8430
|
+
} );
|
|
8431
|
+
return [ visColumns[ visColumns.length + idx ] ];
|
|
8432
|
+
}
|
|
8433
|
+
// Counting from the left
|
|
8434
|
+
return [ _fnVisibleToColumnIndex( settings, idx ) ];
|
|
8284
8435
|
}
|
|
8285
|
-
|
|
8286
|
-
|
|
8436
|
+
|
|
8437
|
+
// `:visible` on its own
|
|
8438
|
+
return columns.map( function (col, i) {
|
|
8439
|
+
return col.bVisible ? i : null;
|
|
8440
|
+
} );
|
|
8287
8441
|
|
|
8288
8442
|
case 'name':
|
|
8289
8443
|
// match by name. `names` is column index complete and in order
|
|
@@ -9133,23 +9287,60 @@ _api_register( 'state.save()', function () {
|
|
|
9133
9287
|
} );
|
|
9134
9288
|
|
|
9135
9289
|
/**
|
|
9136
|
-
* Set the
|
|
9137
|
-
*
|
|
9138
|
-
*
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9290
|
+
* Set the libraries that DataTables uses, or the global objects.
|
|
9291
|
+
* Note that the arguments can be either way around (legacy support)
|
|
9292
|
+
* and the second is optional. See docs.
|
|
9293
|
+
*/
|
|
9294
|
+
DataTable.use = function (arg1, arg2) {
|
|
9295
|
+
// Reverse arguments for legacy support
|
|
9296
|
+
var module = typeof arg1 === 'string'
|
|
9297
|
+
? arg2
|
|
9298
|
+
: arg1;
|
|
9299
|
+
var type = typeof arg2 === 'string'
|
|
9300
|
+
? arg2
|
|
9301
|
+
: arg1;
|
|
9302
|
+
|
|
9303
|
+
// Getter
|
|
9304
|
+
if (module === undefined && typeof type === 'string') {
|
|
9305
|
+
switch (type) {
|
|
9306
|
+
case 'lib':
|
|
9307
|
+
case 'jq':
|
|
9308
|
+
return $;
|
|
9309
|
+
|
|
9310
|
+
case 'win':
|
|
9311
|
+
return window;
|
|
9312
|
+
|
|
9313
|
+
case 'datetime':
|
|
9314
|
+
return DataTable.DateTime;
|
|
9315
|
+
|
|
9316
|
+
case 'luxon':
|
|
9317
|
+
return __luxon;
|
|
9318
|
+
|
|
9319
|
+
case 'moment':
|
|
9320
|
+
return __moment;
|
|
9321
|
+
|
|
9322
|
+
default:
|
|
9323
|
+
return null;
|
|
9324
|
+
}
|
|
9325
|
+
}
|
|
9326
|
+
|
|
9327
|
+
// Setter
|
|
9328
|
+
if (type === 'lib' || type === 'jq' || (module && module.fn && module.fn.jquery)) {
|
|
9144
9329
|
$ = module;
|
|
9145
9330
|
}
|
|
9146
|
-
else if (type == 'win' || module.document) {
|
|
9331
|
+
else if (type == 'win' || (module && module.document)) {
|
|
9147
9332
|
window = module;
|
|
9148
9333
|
document = module.document;
|
|
9149
9334
|
}
|
|
9150
|
-
else if (type === 'datetime' || module.type === 'DateTime') {
|
|
9335
|
+
else if (type === 'datetime' || (module && module.type === 'DateTime')) {
|
|
9151
9336
|
DataTable.DateTime = module;
|
|
9152
9337
|
}
|
|
9338
|
+
else if (type === 'luxon' || (module && module.FixedOffsetZone)) {
|
|
9339
|
+
__luxon = module;
|
|
9340
|
+
}
|
|
9341
|
+
else if (type === 'moment' || (module && module.isMoment)) {
|
|
9342
|
+
__moment = module;
|
|
9343
|
+
}
|
|
9153
9344
|
}
|
|
9154
9345
|
|
|
9155
9346
|
/**
|
|
@@ -9558,7 +9749,7 @@ _api_register( 'i18n()', function ( token, def, plural ) {
|
|
|
9558
9749
|
* @type string
|
|
9559
9750
|
* @default Version number
|
|
9560
9751
|
*/
|
|
9561
|
-
DataTable.version = "2.0
|
|
9752
|
+
DataTable.version = "2.1.0";
|
|
9562
9753
|
|
|
9563
9754
|
/**
|
|
9564
9755
|
* Private data store, containing all of the settings objects that are
|
|
@@ -10403,7 +10594,8 @@ DataTable.defaults = {
|
|
|
10403
10594
|
first: 'First',
|
|
10404
10595
|
last: 'Last',
|
|
10405
10596
|
next: 'Next',
|
|
10406
|
-
previous: 'Previous'
|
|
10597
|
+
previous: 'Previous',
|
|
10598
|
+
number: ''
|
|
10407
10599
|
}
|
|
10408
10600
|
},
|
|
10409
10601
|
|
|
@@ -10583,6 +10775,10 @@ DataTable.defaults = {
|
|
|
10583
10775
|
},
|
|
10584
10776
|
|
|
10585
10777
|
|
|
10778
|
+
/** The initial data order is reversed when `desc` ordering */
|
|
10779
|
+
orderDescReverse: true,
|
|
10780
|
+
|
|
10781
|
+
|
|
10586
10782
|
/**
|
|
10587
10783
|
* This parameter allows you to have define the global filtering state at
|
|
10588
10784
|
* initialisation time. As an object the `search` parameter must be
|
|
@@ -10631,7 +10827,7 @@ DataTable.defaults = {
|
|
|
10631
10827
|
* * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
|
|
10632
10828
|
* * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
|
|
10633
10829
|
*/
|
|
10634
|
-
"sPaginationType": "
|
|
10830
|
+
"sPaginationType": "",
|
|
10635
10831
|
|
|
10636
10832
|
|
|
10637
10833
|
/**
|
|
@@ -10701,7 +10897,13 @@ DataTable.defaults = {
|
|
|
10701
10897
|
/**
|
|
10702
10898
|
* Caption value
|
|
10703
10899
|
*/
|
|
10704
|
-
"caption": null
|
|
10900
|
+
"caption": null,
|
|
10901
|
+
|
|
10902
|
+
|
|
10903
|
+
/**
|
|
10904
|
+
* For server-side processing - use the data from the DOM for the first draw
|
|
10905
|
+
*/
|
|
10906
|
+
iDeferLoading: null
|
|
10705
10907
|
};
|
|
10706
10908
|
|
|
10707
10909
|
_fnHungarianMap( DataTable.defaults );
|
|
@@ -11644,7 +11846,10 @@ DataTable.models.oSettings = {
|
|
|
11644
11846
|
|
|
11645
11847
|
captionNode: null,
|
|
11646
11848
|
|
|
11647
|
-
colgroup: null
|
|
11849
|
+
colgroup: null,
|
|
11850
|
+
|
|
11851
|
+
/** Delay loading of data */
|
|
11852
|
+
deferLoading: null
|
|
11648
11853
|
};
|
|
11649
11854
|
|
|
11650
11855
|
/**
|
|
@@ -11668,7 +11873,7 @@ $.extend( extPagination, {
|
|
|
11668
11873
|
},
|
|
11669
11874
|
|
|
11670
11875
|
full: function () {
|
|
11671
|
-
return [
|
|
11876
|
+
return [ 'first', 'previous', 'next', 'last' ];
|
|
11672
11877
|
},
|
|
11673
11878
|
|
|
11674
11879
|
numbers: function () {
|
|
@@ -11682,11 +11887,11 @@ $.extend( extPagination, {
|
|
|
11682
11887
|
full_numbers: function () {
|
|
11683
11888
|
return [ 'first', 'previous', 'numbers', 'next', 'last' ];
|
|
11684
11889
|
},
|
|
11685
|
-
|
|
11890
|
+
|
|
11686
11891
|
first_last: function () {
|
|
11687
11892
|
return ['first', 'last'];
|
|
11688
11893
|
},
|
|
11689
|
-
|
|
11894
|
+
|
|
11690
11895
|
first_last_numbers: function () {
|
|
11691
11896
|
return ['first', 'numbers', 'last'];
|
|
11692
11897
|
},
|
|
@@ -11768,38 +11973,56 @@ var _filterString = function (stripHtml, normalize) {
|
|
|
11768
11973
|
* to make working with DataTables a little bit easier.
|
|
11769
11974
|
*/
|
|
11770
11975
|
|
|
11771
|
-
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
function __mld(
|
|
11777
|
-
if (
|
|
11778
|
-
return
|
|
11976
|
+
/**
|
|
11977
|
+
* Common logic for moment, luxon or a date action.
|
|
11978
|
+
*
|
|
11979
|
+
* Happens after __mldObj, so don't need to call `resolveWindowsLibs` again
|
|
11980
|
+
*/
|
|
11981
|
+
function __mld( dtLib, momentFn, luxonFn, dateFn, arg1 ) {
|
|
11982
|
+
if (__moment) {
|
|
11983
|
+
return dtLib[momentFn]( arg1 );
|
|
11779
11984
|
}
|
|
11780
|
-
else if (
|
|
11781
|
-
return
|
|
11985
|
+
else if (__luxon) {
|
|
11986
|
+
return dtLib[luxonFn]( arg1 );
|
|
11782
11987
|
}
|
|
11783
11988
|
|
|
11784
|
-
return dateFn ?
|
|
11989
|
+
return dateFn ? dtLib[dateFn]( arg1 ) : dtLib;
|
|
11785
11990
|
}
|
|
11786
11991
|
|
|
11787
11992
|
|
|
11788
11993
|
var __mlWarning = false;
|
|
11994
|
+
var __luxon; // Can be assigned in DateTeble.use()
|
|
11995
|
+
var __moment; // Can be assigned in DateTeble.use()
|
|
11996
|
+
|
|
11997
|
+
/**
|
|
11998
|
+
*
|
|
11999
|
+
*/
|
|
12000
|
+
function resolveWindowLibs() {
|
|
12001
|
+
if (window.luxon && ! __luxon) {
|
|
12002
|
+
__luxon = window.luxon;
|
|
12003
|
+
}
|
|
12004
|
+
|
|
12005
|
+
if (window.moment && ! __moment) {
|
|
12006
|
+
__moment = window.moment;
|
|
12007
|
+
}
|
|
12008
|
+
}
|
|
12009
|
+
|
|
11789
12010
|
function __mldObj (d, format, locale) {
|
|
11790
12011
|
var dt;
|
|
11791
12012
|
|
|
11792
|
-
|
|
11793
|
-
|
|
12013
|
+
resolveWindowLibs();
|
|
12014
|
+
|
|
12015
|
+
if (__moment) {
|
|
12016
|
+
dt = __moment.utc( d, format, locale, true );
|
|
11794
12017
|
|
|
11795
12018
|
if (! dt.isValid()) {
|
|
11796
12019
|
return null;
|
|
11797
12020
|
}
|
|
11798
12021
|
}
|
|
11799
|
-
else if (
|
|
12022
|
+
else if (__luxon) {
|
|
11800
12023
|
dt = format && typeof d === 'string'
|
|
11801
|
-
?
|
|
11802
|
-
:
|
|
12024
|
+
? __luxon.DateTime.fromFormat( d, format )
|
|
12025
|
+
: __luxon.DateTime.fromISO( d );
|
|
11803
12026
|
|
|
11804
12027
|
if (! dt.isValid) {
|
|
11805
12028
|
return null;
|
|
@@ -11844,7 +12067,7 @@ function __mlHelper (localeString) {
|
|
|
11844
12067
|
from = null;
|
|
11845
12068
|
}
|
|
11846
12069
|
|
|
11847
|
-
var typeName = 'datetime' + (to ? '-' +
|
|
12070
|
+
var typeName = 'datetime' + (to ? '-' + to : '');
|
|
11848
12071
|
|
|
11849
12072
|
// Add type detection and sorting specific to this date format - we need to be able to identify
|
|
11850
12073
|
// date type columns as such, rather than as numbers in extensions. Hence the need for this.
|
|
@@ -11947,7 +12170,7 @@ if (window.Intl !== undefined) {
|
|
|
11947
12170
|
|
|
11948
12171
|
// Formatted date time detection - use by declaring the formats you are going to use
|
|
11949
12172
|
DataTable.datetime = function ( format, locale ) {
|
|
11950
|
-
var typeName = 'datetime-
|
|
12173
|
+
var typeName = 'datetime-' + format;
|
|
11951
12174
|
|
|
11952
12175
|
if (! locale) {
|
|
11953
12176
|
locale = 'en';
|
|
@@ -12102,27 +12325,20 @@ DataTable.type = function (name, prop, val) {
|
|
|
12102
12325
|
var setProp = function(prop, propVal) {
|
|
12103
12326
|
_extTypes[prop][name] = propVal;
|
|
12104
12327
|
};
|
|
12105
|
-
var setDetect = function (
|
|
12106
|
-
//
|
|
12107
|
-
//
|
|
12108
|
-
|
|
12109
|
-
var ret = fn(d, s);
|
|
12110
|
-
|
|
12111
|
-
return ret === true
|
|
12112
|
-
? name
|
|
12113
|
-
: ret;
|
|
12114
|
-
};
|
|
12115
|
-
Object.defineProperty(cb, "name", {value: name});
|
|
12328
|
+
var setDetect = function (detect) {
|
|
12329
|
+
// `detect` can be a function or an object - we set a name
|
|
12330
|
+
// property for either - that is used for the detection
|
|
12331
|
+
Object.defineProperty(detect, "name", {value: name});
|
|
12116
12332
|
|
|
12117
|
-
var idx = _extTypes.detect.findIndex(function (
|
|
12118
|
-
return
|
|
12333
|
+
var idx = _extTypes.detect.findIndex(function (item) {
|
|
12334
|
+
return item.name === name;
|
|
12119
12335
|
});
|
|
12120
12336
|
|
|
12121
12337
|
if (idx === -1) {
|
|
12122
|
-
_extTypes.detect.unshift(
|
|
12338
|
+
_extTypes.detect.unshift(detect);
|
|
12123
12339
|
}
|
|
12124
12340
|
else {
|
|
12125
|
-
_extTypes.detect.splice(idx, 1,
|
|
12341
|
+
_extTypes.detect.splice(idx, 1, detect);
|
|
12126
12342
|
}
|
|
12127
12343
|
};
|
|
12128
12344
|
var setOrder = function (obj) {
|
|
@@ -12182,6 +12398,19 @@ DataTable.types = function () {
|
|
|
12182
12398
|
});
|
|
12183
12399
|
};
|
|
12184
12400
|
|
|
12401
|
+
var __diacriticSort = function (a, b) {
|
|
12402
|
+
a = a.toString().toLowerCase();
|
|
12403
|
+
b = b.toString().toLowerCase();
|
|
12404
|
+
|
|
12405
|
+
// Checked for `navigator.languages` support in `oneOf` so this code can't execute in old
|
|
12406
|
+
// Safari and thus can disable this check
|
|
12407
|
+
// eslint-disable-next-line compat/compat
|
|
12408
|
+
return a.localeCompare(b, navigator.languages[0] || navigator.language, {
|
|
12409
|
+
numeric: true,
|
|
12410
|
+
ignorePunctuation: true,
|
|
12411
|
+
});
|
|
12412
|
+
}
|
|
12413
|
+
|
|
12185
12414
|
//
|
|
12186
12415
|
// Built in data types
|
|
12187
12416
|
//
|
|
@@ -12206,11 +12435,38 @@ DataTable.type('string', {
|
|
|
12206
12435
|
search: _filterString(false, true)
|
|
12207
12436
|
});
|
|
12208
12437
|
|
|
12438
|
+
DataTable.type('string-utf8', {
|
|
12439
|
+
detect: {
|
|
12440
|
+
allOf: function ( d ) {
|
|
12441
|
+
return true;
|
|
12442
|
+
},
|
|
12443
|
+
oneOf: function ( d ) {
|
|
12444
|
+
// At least one data point must contain a non-ASCII character
|
|
12445
|
+
// This line will also check if navigator.languages is supported or not. If not (Safari 10.0-)
|
|
12446
|
+
// this data type won't be supported.
|
|
12447
|
+
// eslint-disable-next-line compat/compat
|
|
12448
|
+
return ! _empty( d ) && navigator.languages && typeof d === 'string' && d.match(/[^\x00-\x7F]/);
|
|
12449
|
+
}
|
|
12450
|
+
},
|
|
12451
|
+
order: {
|
|
12452
|
+
asc: __diacriticSort,
|
|
12453
|
+
desc: function (a, b) {
|
|
12454
|
+
return __diacriticSort(a, b) * -1;
|
|
12455
|
+
}
|
|
12456
|
+
},
|
|
12457
|
+
search: _filterString(false, true)
|
|
12458
|
+
});
|
|
12459
|
+
|
|
12209
12460
|
|
|
12210
12461
|
DataTable.type('html', {
|
|
12211
|
-
detect:
|
|
12212
|
-
|
|
12213
|
-
'
|
|
12462
|
+
detect: {
|
|
12463
|
+
allOf: function ( d ) {
|
|
12464
|
+
return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1);
|
|
12465
|
+
},
|
|
12466
|
+
oneOf: function ( d ) {
|
|
12467
|
+
// At least one data point must contain a `<`
|
|
12468
|
+
return ! _empty( d ) && typeof d === 'string' && d.indexOf('<') !== -1;
|
|
12469
|
+
}
|
|
12214
12470
|
},
|
|
12215
12471
|
order: {
|
|
12216
12472
|
pre: function ( a ) {
|
|
@@ -12227,16 +12483,21 @@ DataTable.type('html', {
|
|
|
12227
12483
|
|
|
12228
12484
|
DataTable.type('date', {
|
|
12229
12485
|
className: 'dt-type-date',
|
|
12230
|
-
detect:
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
|
|
12236
|
-
|
|
12486
|
+
detect: {
|
|
12487
|
+
allOf: function ( d ) {
|
|
12488
|
+
// V8 tries _very_ hard to make a string passed into `Date.parse()`
|
|
12489
|
+
// valid, so we need to use a regex to restrict date formats. Use a
|
|
12490
|
+
// plug-in for anything other than ISO8601 style strings
|
|
12491
|
+
if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
|
|
12492
|
+
return null;
|
|
12493
|
+
}
|
|
12494
|
+
var parsed = Date.parse(d);
|
|
12495
|
+
return (parsed !== null && !isNaN(parsed)) || _empty(d);
|
|
12496
|
+
},
|
|
12497
|
+
oneOf: function ( d ) {
|
|
12498
|
+
// At least one entry must be a date or a string with a date
|
|
12499
|
+
return (d instanceof Date) || (typeof d === 'string' && _re_date.test(d));
|
|
12237
12500
|
}
|
|
12238
|
-
var parsed = Date.parse(d);
|
|
12239
|
-
return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
|
|
12240
12501
|
},
|
|
12241
12502
|
order: {
|
|
12242
12503
|
pre: function ( d ) {
|
|
@@ -12249,10 +12510,16 @@ DataTable.type('date', {
|
|
|
12249
12510
|
|
|
12250
12511
|
DataTable.type('html-num-fmt', {
|
|
12251
12512
|
className: 'dt-type-numeric',
|
|
12252
|
-
detect:
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12513
|
+
detect: {
|
|
12514
|
+
allOf: function ( d, settings ) {
|
|
12515
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12516
|
+
return _htmlNumeric( d, decimal, true, false );
|
|
12517
|
+
},
|
|
12518
|
+
oneOf: function (d, settings) {
|
|
12519
|
+
// At least one data point must contain a numeric value
|
|
12520
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12521
|
+
return _htmlNumeric( d, decimal, true, false );
|
|
12522
|
+
}
|
|
12256
12523
|
},
|
|
12257
12524
|
order: {
|
|
12258
12525
|
pre: function ( d, s ) {
|
|
@@ -12266,10 +12533,16 @@ DataTable.type('html-num-fmt', {
|
|
|
12266
12533
|
|
|
12267
12534
|
DataTable.type('html-num', {
|
|
12268
12535
|
className: 'dt-type-numeric',
|
|
12269
|
-
detect:
|
|
12270
|
-
|
|
12271
|
-
|
|
12272
|
-
|
|
12536
|
+
detect: {
|
|
12537
|
+
allOf: function ( d, settings ) {
|
|
12538
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12539
|
+
return _htmlNumeric( d, decimal, false, true );
|
|
12540
|
+
},
|
|
12541
|
+
oneOf: function (d, settings) {
|
|
12542
|
+
// At least one data point must contain a numeric value
|
|
12543
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12544
|
+
return _htmlNumeric( d, decimal, false, false );
|
|
12545
|
+
}
|
|
12273
12546
|
},
|
|
12274
12547
|
order: {
|
|
12275
12548
|
pre: function ( d, s ) {
|
|
@@ -12283,10 +12556,16 @@ DataTable.type('html-num', {
|
|
|
12283
12556
|
|
|
12284
12557
|
DataTable.type('num-fmt', {
|
|
12285
12558
|
className: 'dt-type-numeric',
|
|
12286
|
-
detect:
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12559
|
+
detect: {
|
|
12560
|
+
allOf: function ( d, settings ) {
|
|
12561
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12562
|
+
return _isNumber( d, decimal, true, true );
|
|
12563
|
+
},
|
|
12564
|
+
oneOf: function (d, settings) {
|
|
12565
|
+
// At least one data point must contain a numeric value
|
|
12566
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12567
|
+
return _isNumber( d, decimal, true, false );
|
|
12568
|
+
}
|
|
12290
12569
|
},
|
|
12291
12570
|
order: {
|
|
12292
12571
|
pre: function ( d, s ) {
|
|
@@ -12299,10 +12578,16 @@ DataTable.type('num-fmt', {
|
|
|
12299
12578
|
|
|
12300
12579
|
DataTable.type('num', {
|
|
12301
12580
|
className: 'dt-type-numeric',
|
|
12302
|
-
detect:
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
|
|
12581
|
+
detect: {
|
|
12582
|
+
allOf: function ( d, settings ) {
|
|
12583
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12584
|
+
return _isNumber( d, decimal, false, true );
|
|
12585
|
+
},
|
|
12586
|
+
oneOf: function (d, settings) {
|
|
12587
|
+
// At least one data point must contain a numeric value
|
|
12588
|
+
var decimal = settings.oLanguage.sDecimal;
|
|
12589
|
+
return _isNumber( d, decimal, false, false );
|
|
12590
|
+
}
|
|
12306
12591
|
},
|
|
12307
12592
|
order: {
|
|
12308
12593
|
pre: function (d, s) {
|
|
@@ -12386,7 +12671,7 @@ $.extend( true, DataTable.ext.renderer, {
|
|
|
12386
12671
|
// `DT` namespace will allow the event to be removed automatically
|
|
12387
12672
|
// on destroy, while the `dt` namespaced event is the one we are
|
|
12388
12673
|
// listening for
|
|
12389
|
-
$(settings.nTable).on( 'order.dt.DT', function ( e, ctx
|
|
12674
|
+
$(settings.nTable).on( 'order.dt.DT column-visibility.dt.DT', function ( e, ctx ) {
|
|
12390
12675
|
if ( settings !== ctx ) { // need to check this this is the host
|
|
12391
12676
|
return; // table, not a nested one
|
|
12392
12677
|
}
|
|
@@ -12398,9 +12683,15 @@ $.extend( true, DataTable.ext.renderer, {
|
|
|
12398
12683
|
var ariaType = '';
|
|
12399
12684
|
var indexes = columns.indexes();
|
|
12400
12685
|
var sortDirs = columns.orderable(true).flatten();
|
|
12401
|
-
var
|
|
12402
|
-
|
|
12403
|
-
|
|
12686
|
+
var sorting = ctx.sortDetails;
|
|
12687
|
+
var orderedColumns = ',' + sorting
|
|
12688
|
+
.filter( function (sort) {
|
|
12689
|
+
// Filter to just the visible columns
|
|
12690
|
+
return ctx.aoColumns[sort.col].bVisible;
|
|
12691
|
+
} )
|
|
12692
|
+
.map( function (sort) {
|
|
12693
|
+
return sort.col;
|
|
12694
|
+
} ).join(',') + ',';
|
|
12404
12695
|
|
|
12405
12696
|
cell
|
|
12406
12697
|
.removeClass(
|
|
@@ -12410,7 +12701,8 @@ $.extend( true, DataTable.ext.renderer, {
|
|
|
12410
12701
|
.toggleClass( orderClasses.none, ! orderable )
|
|
12411
12702
|
.toggleClass( orderClasses.canAsc, orderable && sortDirs.includes('asc') )
|
|
12412
12703
|
.toggleClass( orderClasses.canDesc, orderable && sortDirs.includes('desc') );
|
|
12413
|
-
|
|
12704
|
+
|
|
12705
|
+
// Get the index of this cell in the sort array
|
|
12414
12706
|
var sortIdx = orderedColumns.indexOf( ',' + indexes.toArray().join(',') + ',' );
|
|
12415
12707
|
|
|
12416
12708
|
if ( sortIdx !== -1 ) {
|
|
@@ -12454,23 +12746,40 @@ $.extend( true, DataTable.ext.renderer, {
|
|
|
12454
12746
|
|
|
12455
12747
|
layout: {
|
|
12456
12748
|
_: function ( settings, container, items ) {
|
|
12749
|
+
var classes = settings.oClasses.layout;
|
|
12457
12750
|
var row = $('<div/>')
|
|
12458
|
-
.
|
|
12751
|
+
.attr('id', items.id || null)
|
|
12752
|
+
.addClass(items.className || classes.row)
|
|
12459
12753
|
.appendTo( container );
|
|
12460
12754
|
|
|
12461
12755
|
$.each( items, function (key, val) {
|
|
12462
|
-
|
|
12463
|
-
|
|
12464
|
-
|
|
12756
|
+
if (key === 'id' || key === 'className') {
|
|
12757
|
+
return;
|
|
12758
|
+
}
|
|
12759
|
+
|
|
12760
|
+
var klass = '';
|
|
12465
12761
|
|
|
12466
12762
|
if (val.table) {
|
|
12467
|
-
row.addClass(
|
|
12763
|
+
row.addClass(classes.tableRow);
|
|
12764
|
+
klass += classes.tableCell + ' ';
|
|
12765
|
+
}
|
|
12766
|
+
|
|
12767
|
+
if (key === 'start') {
|
|
12768
|
+
klass += classes.start;
|
|
12769
|
+
}
|
|
12770
|
+
else if (key === 'end') {
|
|
12771
|
+
klass += classes.end;
|
|
12772
|
+
}
|
|
12773
|
+
else {
|
|
12774
|
+
klass += classes.full;
|
|
12468
12775
|
}
|
|
12469
12776
|
|
|
12470
12777
|
$('<div/>')
|
|
12471
12778
|
.attr({
|
|
12472
12779
|
id: val.id || null,
|
|
12473
|
-
"class":
|
|
12780
|
+
"class": val.className
|
|
12781
|
+
? val.className
|
|
12782
|
+
: classes.cell + ' ' + klass
|
|
12474
12783
|
})
|
|
12475
12784
|
.append( val.contents )
|
|
12476
12785
|
.appendTo( row );
|
|
@@ -12494,6 +12803,25 @@ DataTable.feature.register = function ( name, cb, legacy ) {
|
|
|
12494
12803
|
}
|
|
12495
12804
|
};
|
|
12496
12805
|
|
|
12806
|
+
function _divProp(el, prop, val) {
|
|
12807
|
+
if (val) {
|
|
12808
|
+
el[prop] = val;
|
|
12809
|
+
}
|
|
12810
|
+
}
|
|
12811
|
+
|
|
12812
|
+
DataTable.feature.register( 'div', function ( settings, opts ) {
|
|
12813
|
+
var n = $('<div>')[0];
|
|
12814
|
+
|
|
12815
|
+
if (opts) {
|
|
12816
|
+
_divProp(n, 'className', opts.className);
|
|
12817
|
+
_divProp(n, 'id', opts.id);
|
|
12818
|
+
_divProp(n, 'innerHTML', opts.html);
|
|
12819
|
+
_divProp(n, 'textContent', opts.text);
|
|
12820
|
+
}
|
|
12821
|
+
|
|
12822
|
+
return n;
|
|
12823
|
+
} );
|
|
12824
|
+
|
|
12497
12825
|
DataTable.feature.register( 'info', function ( settings, opts ) {
|
|
12498
12826
|
// For compatibility with the legacy `info` top level option
|
|
12499
12827
|
if (! settings.oFeatures.bInfo) {
|
|
@@ -12593,6 +12921,7 @@ DataTable.feature.register( 'search', function ( settings, opts ) {
|
|
|
12593
12921
|
|
|
12594
12922
|
opts = $.extend({
|
|
12595
12923
|
placeholder: language.sSearchPlaceholder,
|
|
12924
|
+
processing: false,
|
|
12596
12925
|
text: language.sSearch
|
|
12597
12926
|
}, opts);
|
|
12598
12927
|
|
|
@@ -12636,13 +12965,15 @@ DataTable.feature.register( 'search', function ( settings, opts ) {
|
|
|
12636
12965
|
|
|
12637
12966
|
/* Now do the filter */
|
|
12638
12967
|
if ( val != previousSearch.search ) {
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12968
|
+
_fnProcessingRun(settings, opts.processing, function () {
|
|
12969
|
+
previousSearch.search = val;
|
|
12970
|
+
|
|
12971
|
+
_fnFilterComplete( settings, previousSearch );
|
|
12972
|
+
|
|
12973
|
+
// Need to redraw, without resorting
|
|
12974
|
+
settings._iDisplayStart = 0;
|
|
12975
|
+
_fnDraw( settings );
|
|
12976
|
+
});
|
|
12646
12977
|
}
|
|
12647
12978
|
};
|
|
12648
12979
|
|
|
@@ -12700,17 +13031,17 @@ DataTable.feature.register( 'paging', function ( settings, opts ) {
|
|
|
12700
13031
|
opts = $.extend({
|
|
12701
13032
|
buttons: DataTable.ext.pager.numbers_length,
|
|
12702
13033
|
type: settings.sPaginationType,
|
|
12703
|
-
boundaryNumbers: true
|
|
13034
|
+
boundaryNumbers: true,
|
|
13035
|
+
firstLast: true,
|
|
13036
|
+
previousNext: true,
|
|
13037
|
+
numbers: true
|
|
12704
13038
|
}, opts);
|
|
12705
13039
|
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
}
|
|
12710
|
-
|
|
12711
|
-
var host = $('<div/>').addClass( settings.oClasses.paging.container + ' paging_' + opts.type );
|
|
13040
|
+
var host = $('<div/>')
|
|
13041
|
+
.addClass(settings.oClasses.paging.container + (opts.type ? ' paging_' + opts.type : ''))
|
|
13042
|
+
.append('<nav>');
|
|
12712
13043
|
var draw = function () {
|
|
12713
|
-
_pagingDraw(settings, host, opts);
|
|
13044
|
+
_pagingDraw(settings, host.children(), opts);
|
|
12714
13045
|
};
|
|
12715
13046
|
|
|
12716
13047
|
settings.aoDrawCallback.push(draw);
|
|
@@ -12721,13 +13052,39 @@ DataTable.feature.register( 'paging', function ( settings, opts ) {
|
|
|
12721
13052
|
return host;
|
|
12722
13053
|
}, 'p' );
|
|
12723
13054
|
|
|
13055
|
+
/**
|
|
13056
|
+
* Dynamically create the button type array based on the configuration options.
|
|
13057
|
+
* This will only happen if the paging type is not defined.
|
|
13058
|
+
*/
|
|
13059
|
+
function _pagingDynamic(opts) {
|
|
13060
|
+
var out = [];
|
|
13061
|
+
|
|
13062
|
+
if (opts.numbers) {
|
|
13063
|
+
out.push('numbers');
|
|
13064
|
+
}
|
|
13065
|
+
|
|
13066
|
+
if (opts.previousNext) {
|
|
13067
|
+
out.unshift('previous');
|
|
13068
|
+
out.push('next');
|
|
13069
|
+
}
|
|
13070
|
+
|
|
13071
|
+
if (opts.firstLast) {
|
|
13072
|
+
out.unshift('first');
|
|
13073
|
+
out.push('last');
|
|
13074
|
+
}
|
|
13075
|
+
|
|
13076
|
+
return out;
|
|
13077
|
+
}
|
|
13078
|
+
|
|
12724
13079
|
function _pagingDraw(settings, host, opts) {
|
|
12725
13080
|
if (! settings._bInitComplete) {
|
|
12726
13081
|
return;
|
|
12727
13082
|
}
|
|
12728
13083
|
|
|
12729
13084
|
var
|
|
12730
|
-
plugin =
|
|
13085
|
+
plugin = opts.type
|
|
13086
|
+
? DataTable.ext.pager[ opts.type ]
|
|
13087
|
+
: _pagingDynamic,
|
|
12731
13088
|
aria = settings.oLanguage.oAria.paginate || {},
|
|
12732
13089
|
start = settings._iDisplayStart,
|
|
12733
13090
|
len = settings._iDisplayLength,
|
|
@@ -12735,7 +13092,7 @@ function _pagingDraw(settings, host, opts) {
|
|
|
12735
13092
|
all = len === -1,
|
|
12736
13093
|
page = all ? 0 : Math.ceil( start / len ),
|
|
12737
13094
|
pages = all ? 1 : Math.ceil( visRecords / len ),
|
|
12738
|
-
buttons = plugin()
|
|
13095
|
+
buttons = plugin(opts)
|
|
12739
13096
|
.map(function (val) {
|
|
12740
13097
|
return val === 'numbers'
|
|
12741
13098
|
? _pagingNumbers(page, pages, opts.buttons, opts.boundaryNumbers)
|
|
@@ -12757,14 +13114,24 @@ function _pagingDraw(settings, host, opts) {
|
|
|
12757
13114
|
btnInfo.disabled
|
|
12758
13115
|
);
|
|
12759
13116
|
|
|
13117
|
+
var ariaLabel = typeof button === 'string'
|
|
13118
|
+
? aria[ button ]
|
|
13119
|
+
: aria.number
|
|
13120
|
+
? aria.number + (button+1)
|
|
13121
|
+
: null;
|
|
13122
|
+
|
|
12760
13123
|
// Common attributes
|
|
12761
13124
|
$(btn.clicker).attr({
|
|
12762
13125
|
'aria-controls': settings.sTableId,
|
|
12763
13126
|
'aria-disabled': btnInfo.disabled ? 'true' : null,
|
|
12764
13127
|
'aria-current': btnInfo.active ? 'page' : null,
|
|
12765
|
-
'aria-label':
|
|
13128
|
+
'aria-label': ariaLabel,
|
|
12766
13129
|
'data-dt-idx': button,
|
|
12767
|
-
'tabIndex': btnInfo.disabled
|
|
13130
|
+
'tabIndex': btnInfo.disabled
|
|
13131
|
+
? -1
|
|
13132
|
+
: settings.iTabIndex
|
|
13133
|
+
? settings.iTabIndex
|
|
13134
|
+
: null, // `0` doesn't need a tabIndex since it is the default
|
|
12768
13135
|
});
|
|
12769
13136
|
|
|
12770
13137
|
if (typeof button !== 'number') {
|
|
@@ -12798,10 +13165,10 @@ function _pagingDraw(settings, host, opts) {
|
|
|
12798
13165
|
// height of the buttons and the container.
|
|
12799
13166
|
if (
|
|
12800
13167
|
buttonEls.length && // any buttons
|
|
12801
|
-
opts.
|
|
13168
|
+
opts.buttons > 1 && // prevent infinite
|
|
12802
13169
|
$(host).height() >= ($(buttonEls[0]).outerHeight() * 2) - 10
|
|
12803
13170
|
) {
|
|
12804
|
-
_pagingDraw(settings, host, $.extend({}, opts, {
|
|
13171
|
+
_pagingDraw(settings, host, $.extend({}, opts, { buttons: opts.buttons - 2 }));
|
|
12805
13172
|
}
|
|
12806
13173
|
}
|
|
12807
13174
|
|
|
@@ -13003,10 +13370,11 @@ DataTable.feature.register( 'pageLength', function ( settings, opts ) {
|
|
|
13003
13370
|
}
|
|
13004
13371
|
|
|
13005
13372
|
// Wrapper element - use a span as a holder for where the select will go
|
|
13373
|
+
var tmpId = 'tmp-' + (+new Date())
|
|
13006
13374
|
var div = $('<div/>')
|
|
13007
13375
|
.addClass( classes.container )
|
|
13008
13376
|
.append(
|
|
13009
|
-
str.replace( '_MENU_', '<span></span>' )
|
|
13377
|
+
str.replace( '_MENU_', '<span id="'+tmpId+'"></span>' )
|
|
13010
13378
|
);
|
|
13011
13379
|
|
|
13012
13380
|
// Save text node content for macro updating
|
|
@@ -13049,7 +13417,7 @@ DataTable.feature.register( 'pageLength', function ( settings, opts ) {
|
|
|
13049
13417
|
__lengthCounter++;
|
|
13050
13418
|
|
|
13051
13419
|
// Swap in the select list
|
|
13052
|
-
div.find('
|
|
13420
|
+
div.find('#' + tmpId).replaceWith(select);
|
|
13053
13421
|
|
|
13054
13422
|
// Can't use `select` variable as user might provide their own and the
|
|
13055
13423
|
// reference is broken by the use of outerHTML
|