@ntlab/ntjs-assets 2.50.0 → 2.51.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.
@@ -1,4 +1,4 @@
1
- /*! DataTables 2.2.2
1
+ /*! DataTables 2.3.0
2
2
  * © SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -89,15 +89,19 @@
89
89
  var defaults = DataTable.defaults;
90
90
  var $this = $(this);
91
91
 
92
-
93
- /* Sanity check */
92
+ // Sanity check
94
93
  if ( this.nodeName.toLowerCase() != 'table' )
95
94
  {
96
95
  _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
97
96
  return;
98
97
  }
99
98
 
100
- $(this).trigger( 'options.dt', oInit );
99
+ // Special case for options
100
+ if (oInit.on && oInit.on.options) {
101
+ _fnListener($this, 'options', oInit.on.options);
102
+ }
103
+
104
+ $this.trigger( 'options.dt', oInit );
101
105
 
102
106
  /* Backwards compatibility for the defaults */
103
107
  _fnCompatOpts( defaults );
@@ -236,6 +240,9 @@
236
240
  "caption",
237
241
  "layout",
238
242
  "orderDescReverse",
243
+ "orderIndicators",
244
+ "orderHandler",
245
+ "titleRow",
239
246
  "typeDetect",
240
247
  [ "iCookieDuration", "iStateDuration" ], // backwards compat
241
248
  [ "oSearch", "oPreviousSearch" ],
@@ -264,6 +271,13 @@
264
271
 
265
272
  oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
266
273
 
274
+ // Add event listeners
275
+ if (oInit.on) {
276
+ Object.keys(oInit.on).forEach(function (key) {
277
+ _fnListener($this, key, oInit.on[key]);
278
+ });
279
+ }
280
+
267
281
  /* Browser support detection */
268
282
  _fnBrowserDetect( oSettings );
269
283
 
@@ -324,7 +338,7 @@
324
338
  /* HTML5 attribute detection - build an mData object automatically if the
325
339
  * attributes are found
326
340
  */
327
- var rowOne = $this.children('tbody').find('tr').eq(0);
341
+ var rowOne = $this.children('tbody').find('tr:first-child').eq(0);
328
342
 
329
343
  if ( rowOne.length ) {
330
344
  var a = function ( cell, name ) {
@@ -482,6 +496,13 @@
482
496
  * @namespace
483
497
  */
484
498
  DataTable.ext = _ext = {
499
+ /**
500
+ * DataTables build type (expanded by the download builder)
501
+ *
502
+ * @type string
503
+ */
504
+ builder: "-source-",
505
+
485
506
  /**
486
507
  * Buttons. For use with the Buttons extension for DataTables. This is
487
508
  * defined here so other extensions can define buttons regardless of load
@@ -494,20 +515,20 @@
494
515
 
495
516
 
496
517
  /**
497
- * Element class names
518
+ * ColumnControl buttons and content
498
519
  *
499
520
  * @type object
500
- * @default {}
501
521
  */
502
- classes: {},
522
+ ccContent: {},
503
523
 
504
524
 
505
525
  /**
506
- * DataTables build type (expanded by the download builder)
526
+ * Element class names
507
527
  *
508
- * @type string
528
+ * @type object
529
+ * @default {}
509
530
  */
510
- builder: "-source-",
531
+ classes: {},
511
532
 
512
533
 
513
534
  /**
@@ -1875,6 +1896,22 @@
1875
1896
  init.scrollX = init.scrollX ? '100%' : '';
1876
1897
  }
1877
1898
 
1899
+ // Objects for ordering
1900
+ if ( typeof init.bSort === 'object' ) {
1901
+ init.orderIndicators = init.bSort.indicators !== undefined ? init.bSort.indicators : true;
1902
+ init.orderHandler = init.bSort.handler !== undefined ? init.bSort.handler : true;
1903
+ init.bSort = true;
1904
+ }
1905
+ else if (init.bSort === false) {
1906
+ init.orderIndicators = false;
1907
+ init.orderHandler = false;
1908
+ }
1909
+
1910
+ // Which cells are the title cells?
1911
+ if (typeof init.bSortCellsTop === 'boolean') {
1912
+ init.titleRow = init.bSortCellsTop;
1913
+ }
1914
+
1878
1915
  // Column search objects are in an array, so it needs to be converted
1879
1916
  // element by element
1880
1917
  var searchCols = init.aoSearchCols;
@@ -3252,7 +3289,7 @@
3252
3289
  * @param {*} settings DataTables settings
3253
3290
  * @param {*} source Source layout array
3254
3291
  * @param {*} incColumns What columns should be included
3255
- * @returns Layout array
3292
+ * @returns Layout array in column index order
3256
3293
  */
3257
3294
  function _fnHeaderLayout( settings, source, incColumns )
3258
3295
  {
@@ -3548,10 +3585,9 @@
3548
3585
  var zero = oLang.sZeroRecords;
3549
3586
  var dataSrc = _fnDataSource( settings );
3550
3587
 
3551
- if (
3552
- (settings.iDraw < 1 && dataSrc === 'ssp') ||
3553
- (settings.iDraw <= 1 && dataSrc === 'ajax')
3554
- ) {
3588
+ // Make use of the fact that settings.json is only set once the initial data has
3589
+ // been loaded. Show loading when that isn't the case
3590
+ if ((dataSrc === 'ssp' || dataSrc === 'ajax') && ! settings.json) {
3555
3591
  zero = oLang.sLoadingRecords;
3556
3592
  }
3557
3593
  else if ( oLang.sEmptyTable && settings.fnRecordsTotal() === 0 )
@@ -3921,6 +3957,7 @@
3921
3957
  var rows = $(thead).children('tr');
3922
3958
  var row, cell;
3923
3959
  var i, k, l, iLen, shifted, column, colspan, rowspan;
3960
+ var titleRow = settings.titleRow;
3924
3961
  var isHeader = thead && thead.nodeName.toLowerCase() === 'thead';
3925
3962
  var layout = [];
3926
3963
  var unique;
@@ -3949,6 +3986,7 @@
3949
3986
  cell.nodeName.toUpperCase() == 'TH'
3950
3987
  ) {
3951
3988
  var cols = [];
3989
+ var jqCell = $(cell);
3952
3990
 
3953
3991
  // Get the col and rowspan attributes from the DOM and sanitise them
3954
3992
  colspan = cell.getAttribute('colspan') * 1;
@@ -3969,7 +4007,7 @@
3969
4007
  if ( write ) {
3970
4008
  if (unique) {
3971
4009
  // Allow column options to be set from HTML attributes
3972
- _fnColumnOptions( settings, shifted, $(cell).data() );
4010
+ _fnColumnOptions( settings, shifted, jqCell.data() );
3973
4011
 
3974
4012
  // Get the width for the column. This can be defined from the
3975
4013
  // width attribute, style attribute or `columns.width` option
@@ -3986,7 +4024,14 @@
3986
4024
  // Column title handling - can be user set, or read from the DOM
3987
4025
  // This happens before the render, so the original is still in place
3988
4026
  if ( columnDef.sTitle !== null && ! columnDef.autoTitle ) {
3989
- cell.innerHTML = columnDef.sTitle;
4027
+ if (
4028
+ (titleRow === true && i === 0) || // top row
4029
+ (titleRow === false && i === rows.length -1) || // bottom row
4030
+ (titleRow === i) || // specific row
4031
+ (titleRow === null)
4032
+ ) {
4033
+ cell.innerHTML = columnDef.sTitle;
4034
+ }
3990
4035
  }
3991
4036
 
3992
4037
  if (! columnDef.sTitle && unique) {
@@ -4004,12 +4049,12 @@
4004
4049
  // Fall back to the aria-label attribute on the table header if no ariaTitle is
4005
4050
  // provided.
4006
4051
  if (! columnDef.ariaTitle) {
4007
- columnDef.ariaTitle = $(cell).attr("aria-label") || columnDef.sTitle;
4052
+ columnDef.ariaTitle = jqCell.attr("aria-label") || columnDef.sTitle;
4008
4053
  }
4009
4054
 
4010
4055
  // Column specific class names
4011
4056
  if ( columnDef.className ) {
4012
- $(cell).addClass( columnDef.className );
4057
+ jqCell.addClass( columnDef.className );
4013
4058
  }
4014
4059
  }
4015
4060
 
@@ -4021,11 +4066,28 @@
4021
4066
  .appendTo(cell);
4022
4067
  }
4023
4068
 
4024
- if ( isHeader && $('span.dt-column-order', cell).length === 0) {
4069
+ if (
4070
+ settings.orderIndicators &&
4071
+ isHeader &&
4072
+ jqCell.filter(':not([data-dt-order=disable])').length !== 0 &&
4073
+ jqCell.parent(':not([data-dt-order=disable])').length !== 0 &&
4074
+ $('span.dt-column-order', cell).length === 0
4075
+ ) {
4025
4076
  $('<span>')
4026
4077
  .addClass('dt-column-order')
4027
4078
  .appendTo(cell);
4028
4079
  }
4080
+
4081
+ // We need to wrap the elements in the header in another element to use flexbox
4082
+ // layout for those elements
4083
+ var headerFooter = isHeader ? 'header' : 'footer';
4084
+
4085
+ if ( $('span.dt-column-' + headerFooter, cell).length === 0) {
4086
+ $('<div>')
4087
+ .addClass('dt-column-' + headerFooter)
4088
+ .append(cell.childNodes)
4089
+ .appendTo(cell);
4090
+ }
4029
4091
  }
4030
4092
 
4031
4093
  // If there is col / rowspan, copy the information into the layout grid
@@ -4176,6 +4238,11 @@
4176
4238
  // Allow plug-ins and external processes to modify the data
4177
4239
  _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data, baseAjax], true );
4178
4240
 
4241
+ // Custom Ajax option to submit the parameters as a JSON string
4242
+ if (baseAjax.submitAs === 'json' && typeof data === 'object') {
4243
+ baseAjax.data = JSON.stringify(data);
4244
+ }
4245
+
4179
4246
  if ( typeof ajax === 'function' )
4180
4247
  {
4181
4248
  // Is a function - let the caller define what needs to be done
@@ -5676,24 +5743,30 @@
5676
5743
  function _fnSortInit( settings ) {
5677
5744
  var target = settings.nTHead;
5678
5745
  var headerRows = target.querySelectorAll('tr');
5679
- var legacyTop = settings.bSortCellsTop;
5746
+ var titleRow = settings.titleRow;
5680
5747
  var notSelector = ':not([data-dt-order="disable"]):not([data-dt-order="icon-only"])';
5681
5748
 
5682
5749
  // Legacy support for `orderCellsTop`
5683
- if (legacyTop === true) {
5750
+ if (titleRow === true) {
5684
5751
  target = headerRows[0];
5685
5752
  }
5686
- else if (legacyTop === false) {
5753
+ else if (titleRow === false) {
5687
5754
  target = headerRows[ headerRows.length - 1 ];
5688
5755
  }
5756
+ else if (titleRow !== null) {
5757
+ target = headerRows[titleRow];
5758
+ }
5759
+ // else - all rows
5689
5760
 
5690
- _fnSortAttachListener(
5691
- settings,
5692
- target,
5693
- target === settings.nTHead
5694
- ? 'tr'+notSelector+' th'+notSelector+', tr'+notSelector+' td'+notSelector
5695
- : 'th'+notSelector+', td'+notSelector
5696
- );
5761
+ if (settings.orderHandler) {
5762
+ _fnSortAttachListener(
5763
+ settings,
5764
+ target,
5765
+ target === settings.nTHead
5766
+ ? 'tr'+notSelector+' th'+notSelector+', tr'+notSelector+' td'+notSelector
5767
+ : 'th'+notSelector+', td'+notSelector
5768
+ );
5769
+ }
5697
5770
 
5698
5771
  // Need to resolve the user input array into our internal structure
5699
5772
  var order = [];
@@ -5708,7 +5781,9 @@
5708
5781
  var run = false;
5709
5782
  var columns = column === undefined
5710
5783
  ? _fnColumnsFromHeader( e.target )
5711
- : [column];
5784
+ : Array.isArray(column)
5785
+ ? column
5786
+ : [column];
5712
5787
 
5713
5788
  if ( columns.length ) {
5714
5789
  for ( var i=0, ien=columns.length ; i<ien ; i++ ) {
@@ -6331,16 +6406,19 @@
6331
6406
 
6332
6407
  // A column name was stored and should be used for restore
6333
6408
  if (typeof col[0] === 'string') {
6409
+ // Find the name from the current list of column names
6334
6410
  var idx = currentNames.indexOf(col[0]);
6335
6411
 
6336
- // Find the name from the current list of column names, or fallback to index 0
6337
- set[0] = idx >= 0
6338
- ? idx
6339
- : 0;
6412
+ if (idx < 0) {
6413
+ // If the column was not found ignore it and continue
6414
+ return;
6415
+ }
6416
+
6417
+ set[0] = idx;
6340
6418
  }
6341
6419
  else if (set[0] >= columns.length) {
6342
- // If a column name, but it is out of bounds, set to 0
6343
- set[0] = 0;
6420
+ // If the column index is out of bounds ignore it and continue
6421
+ return;
6344
6422
  }
6345
6423
 
6346
6424
  settings.aaSorting.push(set);
@@ -6753,6 +6831,23 @@
6753
6831
  }
6754
6832
  }
6755
6833
 
6834
+ /**
6835
+ * Add one or more listeners to the table
6836
+ *
6837
+ * @param {*} that JQ for the table
6838
+ * @param {*} name Event name
6839
+ * @param {*} src Listener(s)
6840
+ */
6841
+ function _fnListener(that, name, src) {
6842
+ if (!Array.isArray(src)) {
6843
+ src = [src];
6844
+ }
6845
+
6846
+ for (i=0 ; i<src.length ; i++) {
6847
+ that.on(name + '.dt', src[i]);
6848
+ }
6849
+ }
6850
+
6756
6851
 
6757
6852
 
6758
6853
  /**
@@ -7409,12 +7504,24 @@
7409
7504
  ['footer', 'aoFooter'],
7410
7505
  ].forEach(function (item) {
7411
7506
  _api_register( 'table().' + item[0] + '.structure()' , function (selector) {
7412
- var indexes = this.columns(selector).indexes().flatten();
7507
+ var indexes = this.columns(selector).indexes().flatten().toArray();
7413
7508
  var ctx = this.context[0];
7414
-
7415
- return _fnHeaderLayout(ctx, ctx[item[1]], indexes);
7416
- } );
7417
- })
7509
+ var structure = _fnHeaderLayout(ctx, ctx[item[1]], indexes);
7510
+
7511
+ // The structure is in column index order - but from this method we want the return to be
7512
+ // in the columns() selector API order. In order to do that we need to map from one form
7513
+ // to the other
7514
+ var orderedIndexes = indexes.slice().sort(function (a, b) {
7515
+ return a - b;
7516
+ });
7517
+
7518
+ return structure.map(function (row) {
7519
+ return indexes.map(function (colIdx) {
7520
+ return row[orderedIndexes.indexOf(colIdx)];
7521
+ });
7522
+ });
7523
+ });
7524
+ });
7418
7525
 
7419
7526
 
7420
7527
  _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
@@ -7763,7 +7870,7 @@
7763
7870
  {
7764
7871
  var
7765
7872
  out = [], res,
7766
- a, i, ien, j, jen,
7873
+ i, ien,
7767
7874
  selectorType = typeof selector;
7768
7875
 
7769
7876
  // Can't just check for isArray here, as an API or jQuery instance might be
@@ -7773,22 +7880,15 @@
7773
7880
  }
7774
7881
 
7775
7882
  for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7776
- // Only split on simple strings - complex expressions will be jQuery selectors
7777
- a = selector[i] && selector[i].split && ! selector[i].match(/[[(:]/) ?
7778
- selector[i].split(',') :
7779
- [ selector[i] ];
7883
+ res = selectFn( typeof selector[i] === 'string' ? selector[i].trim() : selector[i] );
7780
7884
 
7781
- for ( j=0, jen=a.length ; j<jen ; j++ ) {
7782
- res = selectFn( typeof a[j] === 'string' ? (a[j]).trim() : a[j] );
7783
-
7784
- // Remove empty items
7785
- res = res.filter( function (item) {
7786
- return item !== null && item !== undefined;
7787
- });
7885
+ // Remove empty items
7886
+ res = res.filter( function (item) {
7887
+ return item !== null && item !== undefined;
7888
+ });
7788
7889
 
7789
- if ( res && res.length ) {
7790
- out = out.concat( res );
7791
- }
7890
+ if ( res && res.length ) {
7891
+ out = out.concat( res );
7792
7892
  }
7793
7893
  }
7794
7894
 
@@ -7817,6 +7917,7 @@
7817
7917
  }
7818
7918
 
7819
7919
  return $.extend( {
7920
+ columnOrder: 'implied',
7820
7921
  search: 'none',
7821
7922
  order: 'current',
7822
7923
  page: 'all'
@@ -8578,23 +8679,60 @@
8578
8679
 
8579
8680
  var __column_header = function ( settings, column, row ) {
8580
8681
  var header = settings.aoHeader;
8581
- var target = row !== undefined
8582
- ? row
8583
- : settings.bSortCellsTop // legacy support
8584
- ? 0
8585
- : header.length - 1;
8682
+ var titleRow = settings.titleRow;
8683
+ var target = null;
8684
+
8685
+ if (row !== undefined) {
8686
+ target = row;
8687
+ }
8688
+ else if (titleRow === true) { // legacy orderCellsTop support
8689
+ target = 0;
8690
+ }
8691
+ else if (titleRow === false) {
8692
+ target = header.length - 1;
8693
+ }
8694
+ else if (titleRow !== null) {
8695
+ target = titleRow;
8696
+ }
8697
+ else {
8698
+ // Automatic - find the _last_ unique cell from the top that is not empty (last for
8699
+ // backwards compatibility)
8700
+ for (var i=0 ; i<header.length ; i++) {
8701
+ if (header[i][column].unique && $('span.dt-column-title', header[i][column].cell).text()) {
8702
+ target = i;
8703
+ }
8704
+ }
8705
+
8706
+ if (target === null) {
8707
+ target = 0;
8708
+ }
8709
+ }
8586
8710
 
8587
8711
  return header[target][column].cell;
8588
8712
  };
8589
8713
 
8714
+ var __column_header_cells = function (header) {
8715
+ var out = [];
8716
+
8717
+ for (var i=0 ; i<header.length ; i++) {
8718
+ for (var j=0 ; j<header[i].length ; j++) {
8719
+ var cell = header[i][j].cell;
8720
+
8721
+ if (!out.includes(cell)) {
8722
+ out.push(cell);
8723
+ }
8724
+ }
8725
+ }
8726
+
8727
+ return out;
8728
+ }
8729
+
8590
8730
  var __column_selector = function ( settings, selector, opts )
8591
8731
  {
8592
8732
  var
8593
8733
  columns = settings.aoColumns,
8594
- names = _pluck( columns, 'sName' ),
8595
- titles = _pluck( columns, 'sTitle' ),
8596
- cells = DataTable.util.get('[].[].cell')(settings.aoHeader),
8597
- nodes = _unique( _flatten([], cells) );
8734
+ names, titles,
8735
+ nodes = __column_header_cells(settings.aoHeader);
8598
8736
 
8599
8737
  var run = function ( s ) {
8600
8738
  var selInt = _intVal( s );
@@ -8666,12 +8804,21 @@
8666
8804
  } );
8667
8805
 
8668
8806
  case 'name':
8807
+ // Don't get names, unless needed, and only get once if it is
8808
+ if (!names) {
8809
+ names = _pluck( columns, 'sName' );
8810
+ }
8811
+
8669
8812
  // match by name. `names` is column index complete and in order
8670
8813
  return names.map( function (name, i) {
8671
8814
  return name === match[1] ? i : null;
8672
8815
  } );
8673
8816
 
8674
8817
  case 'title':
8818
+ if (!titles) {
8819
+ titles = _pluck( columns, 'sTitle' );
8820
+ }
8821
+
8675
8822
  // match by column title
8676
8823
  return titles.map( function (title, i) {
8677
8824
  return title === match[1] ? i : null;
@@ -8710,7 +8857,11 @@
8710
8857
  [];
8711
8858
  };
8712
8859
 
8713
- return _selector_run( 'column', selector, run, settings, opts );
8860
+ var selected = _selector_run( 'column', selector, run, settings, opts );
8861
+
8862
+ return opts.columnOrder && opts.columnOrder === 'index'
8863
+ ? selected.sort(function (a, b) { return a - b; })
8864
+ : selected; // implied
8714
8865
  };
8715
8866
 
8716
8867
 
@@ -8834,6 +8985,12 @@
8834
8985
  }, 1 );
8835
8986
  } );
8836
8987
 
8988
+ _api_registerPlural( 'columns().names()', 'column().name()', function () {
8989
+ return this.iterator( 'column', function ( settings, column ) {
8990
+ return settings.aoColumns[column].sName;
8991
+ }, 1 );
8992
+ } );
8993
+
8837
8994
  _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8838
8995
  return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8839
8996
  return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
@@ -9260,7 +9417,10 @@
9260
9417
  // otherwise a 2D array was passed in
9261
9418
 
9262
9419
  return this.iterator( 'table', function ( settings ) {
9263
- settings.aaSorting = Array.isArray(order) ? order.slice() : order;
9420
+ var resolved = [];
9421
+ _fnSortResolve(settings, resolved, order);
9422
+
9423
+ settings.aaSorting = resolved;
9264
9424
  } );
9265
9425
  } );
9266
9426
 
@@ -9386,7 +9546,7 @@
9386
9546
  var fixed = settings.searchFixed;
9387
9547
 
9388
9548
  if (! name) {
9389
- return Object.keys(fixed)
9549
+ return Object.keys(fixed);
9390
9550
  }
9391
9551
  else if (search === undefined) {
9392
9552
  return fixed[name];
@@ -9453,10 +9613,10 @@
9453
9613
  var fixed = settings.aoColumns[colIdx].searchFixed;
9454
9614
 
9455
9615
  if (! name) {
9456
- return Object.keys(fixed)
9616
+ return Object.keys(fixed);
9457
9617
  }
9458
9618
  else if (search === undefined) {
9459
- return fixed[name];
9619
+ return fixed[name] || null;
9460
9620
  }
9461
9621
  else if (search === null) {
9462
9622
  delete fixed[name];
@@ -9908,14 +10068,9 @@
9908
10068
  jqTable.append( tfoot );
9909
10069
  }
9910
10070
 
9911
- // Clean up the header
9912
- $(thead).find('span.dt-column-order').remove();
9913
- $(thead).find('span.dt-column-title').each(function () {
9914
- var title = $(this).html();
9915
- $(this).parent().append(title);
9916
- $(this).remove();
9917
- });
9918
-
10071
+ // Clean up the header / footer
10072
+ cleanHeader(thead, 'header');
10073
+ cleanHeader(tfoot, 'footer');
9919
10074
  settings.colgroup.remove();
9920
10075
 
9921
10076
  settings.aaSorting = [];
@@ -9937,7 +10092,6 @@
9937
10092
  orderClasses.isDesc
9938
10093
  )
9939
10094
  .css('width', '')
9940
- .removeAttr('data-dt-column')
9941
10095
  .removeAttr('aria-sort');
9942
10096
 
9943
10097
  // Add the TR elements back into the table in their original order
@@ -10018,6 +10172,19 @@
10018
10172
  : resolved;
10019
10173
  } );
10020
10174
 
10175
+ // Needed for header and footer, so pulled into its own function
10176
+ function cleanHeader(node, className) {
10177
+ $(node).find('span.dt-column-order').remove();
10178
+ $(node).find('span.dt-column-title').each(function () {
10179
+ var title = $(this).html();
10180
+ $(this).parent().parent().append(title);
10181
+ $(this).remove();
10182
+ });
10183
+ $(node).find('div.dt-column-' + className).remove();
10184
+
10185
+ $('th, td', node).removeAttr('data-dt-column');
10186
+ }
10187
+
10021
10188
  /**
10022
10189
  * Version string for plug-ins to check compatibility. Allowed format is
10023
10190
  * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
@@ -10026,7 +10193,7 @@
10026
10193
  * @type string
10027
10194
  * @default Version number
10028
10195
  */
10029
- DataTable.version = "2.2.2";
10196
+ DataTable.version = "2.3.0";
10030
10197
 
10031
10198
  /**
10032
10199
  * Private data store, containing all of the settings objects that are
@@ -10633,6 +10800,10 @@
10633
10800
  "bSortCellsTop": null,
10634
10801
 
10635
10802
 
10803
+ /** Specify which row is the title row in the header. Replacement for bSortCellsTop */
10804
+ titleRow: null,
10805
+
10806
+
10636
10807
  /**
10637
10808
  * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10638
10809
  * `sorting\_3` to the columns which are currently being sorted on. This is
@@ -10910,6 +11081,13 @@
10910
11081
  1: "entry"
10911
11082
  },
10912
11083
 
11084
+ /**
11085
+ * Page length options
11086
+ */
11087
+ lengthLabels: {
11088
+ '-1': 'All'
11089
+ },
11090
+
10913
11091
  /**
10914
11092
  * This string is shown in preference to `zeroRecords` when the table is
10915
11093
  * empty of data (regardless of filtering). Note that this is an optional
@@ -11180,7 +11358,10 @@
11180
11358
  /**
11181
11359
  * For server-side processing - use the data from the DOM for the first draw
11182
11360
  */
11183
- iDeferLoading: null
11361
+ iDeferLoading: null,
11362
+
11363
+ /** Event listeners */
11364
+ on: null
11184
11365
  };
11185
11366
 
11186
11367
  _fnHungarianMap( DataTable.defaults );
@@ -12007,10 +12188,7 @@
12007
12188
 
12008
12189
  /**
12009
12190
  * Indicate that if multiple rows are in the header and there is more than
12010
- * one unique cell per column, if the top one (true) or bottom one (false)
12011
- * should be used for sorting / title by DataTables.
12012
- * Note that this parameter will be set by the initialisation routine. To
12013
- * set a default use {@link DataTable.defaults}.
12191
+ * one unique cell per column. Replaced by titleRow
12014
12192
  */
12015
12193
  "bSortCellsTop": null,
12016
12194
 
@@ -12135,7 +12313,19 @@
12135
12313
  resizeObserver: null,
12136
12314
 
12137
12315
  /** Keep a record of the last size of the container, so we can skip duplicates */
12138
- containerWidth: -1
12316
+ containerWidth: -1,
12317
+
12318
+ /** Reverse the initial order of the data set on desc ordering */
12319
+ orderDescReverse: null,
12320
+
12321
+ /** Show / hide ordering indicators in headers */
12322
+ orderIndicators: true,
12323
+
12324
+ /** Default ordering listener */
12325
+ orderHandler: true,
12326
+
12327
+ /** Title row indicator */
12328
+ titleRow: null
12139
12329
  };
12140
12330
 
12141
12331
  /**
@@ -12965,7 +13155,7 @@
12965
13155
  cell.addClass(classes.order.none);
12966
13156
  }
12967
13157
 
12968
- var legacyTop = settings.bSortCellsTop;
13158
+ var titleRow = settings.titleRow;
12969
13159
  var headerRows = cell.closest('thead').find('tr');
12970
13160
  var rowIdx = cell.parent().index();
12971
13161
 
@@ -12975,11 +13165,10 @@
12975
13165
  cell.attr('data-dt-order') === 'disable' ||
12976
13166
  cell.parent().attr('data-dt-order') === 'disable' ||
12977
13167
 
12978
- // Legacy support for `orderCellsTop`. If it is set, then cells
12979
- // which are not in the top or bottom row of the header (depending
12980
- // on the value) do not get the sorting classes applied to them
12981
- (legacyTop === true && rowIdx !== 0) ||
12982
- (legacyTop === false && rowIdx !== headerRows.length - 1)
13168
+ // titleRow support, for defining a specific row in the header
13169
+ (titleRow === true && rowIdx !== 0) ||
13170
+ (titleRow === false && rowIdx !== headerRows.length - 1) ||
13171
+ (typeof titleRow === 'number' && rowIdx !== titleRow)
12983
13172
  ) {
12984
13173
  return;
12985
13174
  }
@@ -12989,7 +13178,7 @@
12989
13178
  // `DT` namespace will allow the event to be removed automatically
12990
13179
  // on destroy, while the `dt` namespaced event is the one we are
12991
13180
  // listening for
12992
- $(settings.nTable).on( 'order.dt.DT column-visibility.dt.DT', function ( e, ctx ) {
13181
+ $(settings.nTable).on( 'order.dt.DT column-visibility.dt.DT', function ( e, ctx, column ) {
12993
13182
  if ( settings !== ctx ) { // need to check this this is the host
12994
13183
  return; // table, not a nested one
12995
13184
  }
@@ -13000,6 +13189,16 @@
13000
13189
  return;
13001
13190
  }
13002
13191
 
13192
+ var orderedColumns = _pluck(sorting, 'col');
13193
+
13194
+ // This handler is only needed on column visibility if the column is part of the
13195
+ // ordering. If it isn't, then we can bail out to save performance. It could be a
13196
+ // separate event handler, but this is a balance between code reuse / size and performance
13197
+ // console.log(e, e.name, column, orderedColumns, orderedColumns.includes(column))
13198
+ if (e.type === 'column-visibility' && ! orderedColumns.includes(column)) {
13199
+ return;
13200
+ }
13201
+
13003
13202
  var i;
13004
13203
  var orderClasses = classes.order;
13005
13204
  var columns = ctx.api.columns( cell );
@@ -13008,8 +13207,8 @@
13008
13207
  var ariaType = '';
13009
13208
  var indexes = columns.indexes();
13010
13209
  var sortDirs = columns.orderable(true).flatten();
13011
- var orderedColumns = _pluck(sorting, 'col');
13012
13210
  var tabIndex = settings.iTabIndex;
13211
+ var canOrder = ctx.orderHandler && orderable;
13013
13212
 
13014
13213
  cell
13015
13214
  .removeClass(
@@ -13017,8 +13216,8 @@
13017
13216
  orderClasses.isDesc
13018
13217
  )
13019
13218
  .toggleClass( orderClasses.none, ! orderable )
13020
- .toggleClass( orderClasses.canAsc, orderable && sortDirs.includes('asc') )
13021
- .toggleClass( orderClasses.canDesc, orderable && sortDirs.includes('desc') );
13219
+ .toggleClass( orderClasses.canAsc, canOrder && sortDirs.includes('asc') )
13220
+ .toggleClass( orderClasses.canDesc, canOrder && sortDirs.includes('desc') );
13022
13221
 
13023
13222
  // Determine if all of the columns that this cell covers are included in the
13024
13223
  // current ordering
@@ -13777,12 +13976,17 @@
13777
13976
  } );
13778
13977
 
13779
13978
  for ( i=0 ; i<lengths.length ; i++ ) {
13780
- select[0][ i ] = new Option(
13781
- typeof language[i] === 'number' ?
13979
+ // Attempt to look up the length from the i18n options
13980
+ var label = settings.api.i18n('lengthLabels.' + lengths[i], null);
13981
+
13982
+ if (label === null) {
13983
+ // If not present, fallback to old style
13984
+ label = typeof language[i] === 'number' ?
13782
13985
  settings.fnFormatNumber( language[i] ) :
13783
- language[i],
13784
- lengths[i]
13785
- );
13986
+ language[i];
13987
+ }
13988
+
13989
+ select[0][ i ] = new Option(label, lengths[i]);
13786
13990
  }
13787
13991
 
13788
13992
  // add for and id to label and input