datatables.net 2.0.2 → 2.0.4

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! DataTables 2.0.2
1
+ /*! DataTables 2.0.4
2
2
  * © SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -1043,7 +1043,8 @@ var _api_registerPlural; // DataTable.Api.registerPlural
1043
1043
 
1044
1044
  var _re_dic = {};
1045
1045
  var _re_new_lines = /[\r\n\u2028]/g;
1046
- var _re_html = /<.*?>/g;
1046
+ var _re_html = /<([^>]*>)/g;
1047
+ var _max_str_len = Math.pow(2, 28);
1047
1048
 
1048
1049
  // This is not strict ISO8601 - Date.parse() is quite lax, although
1049
1050
  // implementations differ between browsers.
@@ -1231,10 +1232,24 @@ var _removeEmpty = function ( a )
1231
1232
  };
1232
1233
 
1233
1234
  // Replaceable function in api.util
1234
- var _stripHtml = function ( d ) {
1235
- return d
1236
- .replace( _re_html, '' ) // Complete tags
1237
- .replace(/<script/i, ''); // Safety for incomplete script tag
1235
+ var _stripHtml = function (input) {
1236
+ // Irrelevant check to workaround CodeQL's false positive on the regex
1237
+ if (input.length > _max_str_len) {
1238
+ throw new Error('Exceeded max str len');
1239
+ }
1240
+
1241
+ var previous;
1242
+
1243
+ input = input.replace(_re_html, ''); // Complete tags
1244
+
1245
+ // Safety for incomplete script tag - use do / while to ensure that
1246
+ // we get all instances
1247
+ do {
1248
+ previous = input;
1249
+ input = input.replace(/<script/i, '');
1250
+ } while (input !== previous);
1251
+
1252
+ return previous;
1238
1253
  };
1239
1254
 
1240
1255
  // Replaceable function in api.util
@@ -1949,7 +1964,7 @@ function _fnAddColumn( oSettings )
1949
1964
  "mData": oDefaults.mData ? oDefaults.mData : iCol,
1950
1965
  idx: iCol,
1951
1966
  searchFixed: {},
1952
- colEl: $('<col>')
1967
+ colEl: $('<col>').attr('data-dt-column', iCol)
1953
1968
  } );
1954
1969
  oSettings.aoColumns.push( oCol );
1955
1970
 
@@ -3364,8 +3379,15 @@ function _fnDraw( oSettings, ajaxComplete )
3364
3379
  _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
3365
3380
  _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3366
3381
 
3367
- body.children().detach();
3368
- body.append( $(anRows) );
3382
+ // replaceChildren is faster, but only became widespread in 2020,
3383
+ // so a fall back in jQuery is provided for older browsers.
3384
+ if (body[0].replaceChildren) {
3385
+ body[0].replaceChildren.apply(body[0], anRows);
3386
+ }
3387
+ else {
3388
+ body.children().detach();
3389
+ body.append( $(anRows) );
3390
+ }
3369
3391
 
3370
3392
  // Empty table needs a specific class
3371
3393
  $(oSettings.nTableWrapper).toggleClass('dt-empty-footer', $('tr', oSettings.nTFoot).length === 0);
@@ -3633,15 +3655,15 @@ function _fnAddOptionsHtml ( settings )
3633
3655
 
3634
3656
  settings.nTableWrapper = insert[0];
3635
3657
 
3636
- var top = _layoutArray( settings, settings.layout, 'top' );
3637
- var bottom = _layoutArray( settings, settings.layout, 'bottom' );
3638
- var renderer = _fnRenderer( settings, 'layout' );
3639
-
3640
3658
  if (settings.sDom) {
3641
3659
  // Legacy
3642
3660
  _fnLayoutDom(settings, settings.sDom, insert);
3643
3661
  }
3644
3662
  else {
3663
+ var top = _layoutArray( settings, settings.layout, 'top' );
3664
+ var bottom = _layoutArray( settings, settings.layout, 'bottom' );
3665
+ var renderer = _fnRenderer( settings, 'layout' );
3666
+
3645
3667
  // Everything above - the renderer will actually insert the contents into the document
3646
3668
  top.forEach(function (item) {
3647
3669
  renderer( settings, insert, item );
@@ -3827,7 +3849,7 @@ function _fnDetectHeader ( settings, thead, write )
3827
3849
  }
3828
3850
 
3829
3851
  if (! columnDef.sTitle && unique) {
3830
- columnDef.sTitle = cell.innerHTML.replace( /<.*?>/g, "" );
3852
+ columnDef.sTitle = _stripHtml(cell.innerHTML);
3831
3853
  columnDef.autoTitle = true;
3832
3854
  }
3833
3855
  }
@@ -4448,7 +4470,7 @@ function _fnFilterCreateSearch( search, inOpts )
4448
4470
  word = '';
4449
4471
  }
4450
4472
 
4451
- return word.replace('"', '');
4473
+ return word.replace(/"/g, '');
4452
4474
  } );
4453
4475
 
4454
4476
  var match = not.length
@@ -4980,20 +5002,27 @@ function _fnScrollDraw ( settings )
4980
5002
  // uses a cell which has a longer string, but isn't the widest! For example
4981
5003
  // "Chief Executive Officer (CEO)" is the longest string in the demo, but
4982
5004
  // "Systems Administrator" is actually the widest string since it doesn't collapse.
5005
+ // Note the use of translating into a column index to get the `col` element. This
5006
+ // is because of Responsive which might remove `col` elements, knocking the alignment
5007
+ // of the indexes out.
4983
5008
  if (settings.aiDisplay.length) {
4984
5009
  // Get the column sizes from the first row in the table
4985
- var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function () {
4986
- return $(this).outerWidth();
5010
+ var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function (vis) {
5011
+ return {
5012
+ idx: _fnVisibleToColumnIndex(settings, vis),
5013
+ width: $(this).outerWidth()
5014
+ }
4987
5015
  });
4988
5016
 
4989
5017
  // Check against what the colgroup > col is set to and correct if needed
4990
- $('col', settings.colgroup).each(function (i) {
4991
- var colWidth = this.style.width.replace('px', '');
5018
+ for (var i=0 ; i<colSizes.length ; i++) {
5019
+ var colEl = settings.aoColumns[ colSizes[i].idx ].colEl[0];
5020
+ var colWidth = colEl.style.width.replace('px', '');
4992
5021
 
4993
- if (colWidth !== colSizes[i]) {
4994
- this.style.width = colSizes[i] + 'px';
5022
+ if (colWidth !== colSizes[i].width) {
5023
+ colEl.style.width = colSizes[i].width + 'px';
4995
5024
  }
4996
- });
5025
+ }
4997
5026
  }
4998
5027
 
4999
5028
  // 3. Copy the colgroup over to the header and footer
@@ -5401,10 +5430,13 @@ function _fnSortAttachListener(settings, node, selector, column, callback) {
5401
5430
  // Allow the processing display to show
5402
5431
  setTimeout( function () {
5403
5432
  _fnSort( settings );
5404
- _fnSortDisplay( settings );
5405
- _fnReDraw( settings, false, false );
5433
+ _fnSortDisplay( settings, settings.aiDisplay );
5434
+
5435
+ // Sort processing done - redraw has its own processing display
5406
5436
  _fnProcessingDisplay( settings, false );
5407
5437
 
5438
+ _fnReDraw( settings, false, false );
5439
+
5408
5440
  if (callback) {
5409
5441
  callback();
5410
5442
  }
@@ -5418,8 +5450,7 @@ function _fnSortAttachListener(settings, node, selector, column, callback) {
5418
5450
  * Sort the display array to match the master's order
5419
5451
  * @param {*} settings
5420
5452
  */
5421
- function _fnSortDisplay(settings) {
5422
- var display = settings.aiDisplay;
5453
+ function _fnSortDisplay(settings, display) {
5423
5454
  var master = settings.aiDisplayMaster;
5424
5455
  var masterMap = {};
5425
5456
  var map = {};
@@ -6787,6 +6818,10 @@ _Api.extend = function ( scope, obj, ext )
6787
6818
  for ( i=0, ien=ext.length ; i<ien ; i++ ) {
6788
6819
  struct = ext[i];
6789
6820
 
6821
+ if (struct.name === '__proto__') {
6822
+ continue;
6823
+ }
6824
+
6790
6825
  // Value
6791
6826
  obj[ struct.name ] = struct.type === 'function' ?
6792
6827
  _api_scope( scope, struct.val, struct ) :
@@ -7449,16 +7484,7 @@ var _selector_row_indexes = function ( settings, opts )
7449
7484
  order = opts.order, // applied, current, index (original - compatibility with 1.9)
7450
7485
  page = opts.page; // all, current
7451
7486
 
7452
- if ( _fnDataSource( settings ) == 'ssp' ) {
7453
- // In server-side processing mode, most options are irrelevant since
7454
- // rows not shown don't exist and the index order is the applied order
7455
- // Removed is a special case - for consistency just return an empty
7456
- // array
7457
- return search === 'removed' ?
7458
- [] :
7459
- _range( 0, displayMaster.length );
7460
- }
7461
- else if ( page == 'current' ) {
7487
+ if ( page == 'current' ) {
7462
7488
  // Current page implies that order=current and filter=applied, since it is
7463
7489
  // fairly senseless otherwise, regardless of what order and search actually
7464
7490
  // are
@@ -7640,11 +7666,7 @@ var __row_selector = function ( settings, selector, opts )
7640
7666
  var matched = _selector_run( 'row', selector, run, settings, opts );
7641
7667
 
7642
7668
  if (opts.order === 'current' || opts.order === 'applied') {
7643
- var master = settings.aiDisplayMaster;
7644
-
7645
- matched.sort(function(a, b) {
7646
- return master.indexOf(a) - master.indexOf(b);
7647
- });
7669
+ _fnSortDisplay(settings, matched);
7648
7670
  }
7649
7671
 
7650
7672
  return matched;
@@ -7885,8 +7907,9 @@ var __details_state_load = function (api, state)
7885
7907
  {
7886
7908
  if ( state && state.childRows ) {
7887
7909
  api
7888
- .rows( state.childRows.map(function (id){
7889
- return id.replace(/:/g, '\\:')
7910
+ .rows( state.childRows.map(function (id) {
7911
+ // Escape any `:` characters from the row id, unless previously escaped
7912
+ return id.replace(/(?<!\\):/g, '\\:');
7890
7913
  }) )
7891
7914
  .every( function () {
7892
7915
  _fnCallbackFire( api.settings()[0], null, 'requestChild', [ this ] )
@@ -8167,6 +8190,17 @@ var __columnData = function ( settings, column, r1, r2, rows, type ) {
8167
8190
  };
8168
8191
 
8169
8192
 
8193
+ var __column_header = function ( settings, column, row ) {
8194
+ var header = settings.aoHeader;
8195
+ var target = row !== undefined
8196
+ ? row
8197
+ : settings.bSortCellsTop // legacy support
8198
+ ? 0
8199
+ : header.length - 1;
8200
+
8201
+ return header[target][column].cell;
8202
+ };
8203
+
8170
8204
  var __column_selector = function ( settings, selector, opts )
8171
8205
  {
8172
8206
  var
@@ -8199,7 +8233,8 @@ var __column_selector = function ( settings, selector, opts )
8199
8233
  return columns.map(function (col, idx) {
8200
8234
  return s(
8201
8235
  idx,
8202
- __columnData( settings, idx, 0, 0, rows )
8236
+ __columnData( settings, idx, 0, 0, rows ),
8237
+ __column_header( settings, idx )
8203
8238
  ) ? idx : null;
8204
8239
  });
8205
8240
  }
@@ -8344,15 +8379,8 @@ _api_register( 'columns()', function ( selector, opts ) {
8344
8379
  } );
8345
8380
 
8346
8381
  _api_registerPlural( 'columns().header()', 'column().header()', function ( row ) {
8347
- return this.iterator( 'column', function ( settings, column ) {
8348
- var header = settings.aoHeader;
8349
- var target = row !== undefined
8350
- ? row
8351
- : settings.bSortCellsTop // legacy support
8352
- ? 0
8353
- : header.length - 1;
8354
-
8355
- return header[target][column].cell;
8382
+ return this.iterator( 'column', function (settings, column) {
8383
+ return __column_header(settings, column, row);
8356
8384
  }, 1 );
8357
8385
  } );
8358
8386
 
@@ -9505,7 +9533,7 @@ _api_register( 'i18n()', function ( token, def, plural ) {
9505
9533
  * @type string
9506
9534
  * @default Version number
9507
9535
  */
9508
- DataTable.version = "2.0.2";
9536
+ DataTable.version = "2.0.4";
9509
9537
 
9510
9538
  /**
9511
9539
  * Private data store, containing all of the settings objects that are
@@ -10360,24 +10388,24 @@ DataTable.defaults = {
10360
10388
  */
10361
10389
  "oPaginate": {
10362
10390
  /**
10363
- * Label and character for first page button
10391
+ * Label and character for first page button («)
10364
10392
  */
10365
- "sFirst": "«",
10393
+ "sFirst": "\u00AB",
10366
10394
 
10367
10395
  /**
10368
- * Last page button
10396
+ * Last page button (»)
10369
10397
  */
10370
- "sLast": "»",
10398
+ "sLast": "\u00BB",
10371
10399
 
10372
10400
  /**
10373
- * Next page button
10401
+ * Next page button (›)
10374
10402
  */
10375
- "sNext": "",
10403
+ "sNext": "\u203A",
10376
10404
 
10377
10405
  /**
10378
- * Previous page button
10406
+ * Previous page button (‹)
10379
10407
  */
10380
- "sPrevious": "",
10408
+ "sPrevious": "\u2039",
10381
10409
  },
10382
10410
 
10383
10411
  /**
@@ -11606,648 +11634,86 @@ DataTable.models.oSettings = {
11606
11634
  */
11607
11635
 
11608
11636
 
11609
- /**
11610
- * DataTables extensions
11611
- *
11612
- * This namespace acts as a collection area for plug-ins that can be used to
11613
- * extend DataTables capabilities. Indeed many of the build in methods
11614
- * use this method to provide their own capabilities (sorting methods for
11615
- * example).
11616
- *
11617
- * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
11618
- * reasons
11619
- *
11620
- * @namespace
11621
- */
11622
- DataTable.ext = _ext = {
11623
- /**
11624
- * Buttons. For use with the Buttons extension for DataTables. This is
11625
- * defined here so other extensions can define buttons regardless of load
11626
- * order. It is _not_ used by DataTables core.
11627
- *
11628
- * @type object
11629
- * @default {}
11630
- */
11631
- buttons: {},
11632
-
11633
-
11634
- /**
11635
- * Element class names
11636
- *
11637
- * @type object
11638
- * @default {}
11639
- */
11640
- classes: {},
11637
+ var extPagination = DataTable.ext.pager;
11641
11638
 
11639
+ // Paging buttons configuration
11640
+ $.extend( extPagination, {
11641
+ simple: function () {
11642
+ return [ 'previous', 'next' ];
11643
+ },
11642
11644
 
11643
- /**
11644
- * DataTables build type (expanded by the download builder)
11645
- *
11646
- * @type string
11647
- */
11648
- builder: "-source-",
11645
+ full: function () {
11646
+ return [ 'first', 'previous', 'next', 'last' ];
11647
+ },
11649
11648
 
11649
+ numbers: function () {
11650
+ return [ 'numbers' ];
11651
+ },
11650
11652
 
11651
- /**
11652
- * Error reporting.
11653
- *
11654
- * How should DataTables report an error. Can take the value 'alert',
11655
- * 'throw', 'none' or a function.
11656
- *
11657
- * @type string|function
11658
- * @default alert
11659
- */
11660
- errMode: "alert",
11653
+ simple_numbers: function () {
11654
+ return [ 'previous', 'numbers', 'next' ];
11655
+ },
11661
11656
 
11657
+ full_numbers: function () {
11658
+ return [ 'first', 'previous', 'numbers', 'next', 'last' ];
11659
+ },
11660
+
11661
+ first_last: function () {
11662
+ return ['first', 'last'];
11663
+ },
11664
+
11665
+ first_last_numbers: function () {
11666
+ return ['first', 'numbers', 'last'];
11667
+ },
11662
11668
 
11663
- /**
11664
- * Legacy so v1 plug-ins don't throw js errors on load
11665
- */
11666
- feature: [],
11669
+ // For testing and plug-ins to use
11670
+ _numbers: _pagingNumbers,
11667
11671
 
11668
- /**
11669
- * Feature plug-ins.
11670
- *
11671
- * This is an object of callbacks which provide the features for DataTables
11672
- * to be initialised via the `layout` option.
11673
- */
11674
- features: {},
11672
+ // Number of number buttons - legacy, use `numbers` option for paging feature
11673
+ numbers_length: 7
11674
+ } );
11675
11675
 
11676
11676
 
11677
- /**
11678
- * Row searching.
11679
- *
11680
- * This method of searching is complimentary to the default type based
11681
- * searching, and a lot more comprehensive as it allows you complete control
11682
- * over the searching logic. Each element in this array is a function
11683
- * (parameters described below) that is called for every row in the table,
11684
- * and your logic decides if it should be included in the searching data set
11685
- * or not.
11686
- *
11687
- * Searching functions have the following input parameters:
11688
- *
11689
- * 1. `{object}` DataTables settings object: see
11690
- * {@link DataTable.models.oSettings}
11691
- * 2. `{array|object}` Data for the row to be processed (same as the
11692
- * original format that was passed in as the data source, or an array
11693
- * from a DOM data source
11694
- * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
11695
- * can be useful to retrieve the `TR` element if you need DOM interaction.
11696
- *
11697
- * And the following return is expected:
11698
- *
11699
- * * {boolean} Include the row in the searched result set (true) or not
11700
- * (false)
11701
- *
11702
- * Note that as with the main search ability in DataTables, technically this
11703
- * is "filtering", since it is subtractive. However, for consistency in
11704
- * naming we call it searching here.
11705
- *
11706
- * @type array
11707
- * @default []
11708
- *
11709
- * @example
11710
- * // The following example shows custom search being applied to the
11711
- * // fourth column (i.e. the data[3] index) based on two input values
11712
- * // from the end-user, matching the data in a certain range.
11713
- * $.fn.dataTable.ext.search.push(
11714
- * function( settings, data, dataIndex ) {
11715
- * var min = document.getElementById('min').value * 1;
11716
- * var max = document.getElementById('max').value * 1;
11717
- * var version = data[3] == "-" ? 0 : data[3]*1;
11718
- *
11719
- * if ( min == "" && max == "" ) {
11720
- * return true;
11721
- * }
11722
- * else if ( min == "" && version < max ) {
11723
- * return true;
11724
- * }
11725
- * else if ( min < version && "" == max ) {
11726
- * return true;
11727
- * }
11728
- * else if ( min < version && version < max ) {
11729
- * return true;
11730
- * }
11731
- * return false;
11732
- * }
11733
- * );
11734
- */
11735
- search: [],
11677
+ $.extend( true, DataTable.ext.renderer, {
11678
+ pagingButton: {
11679
+ _: function (settings, buttonType, content, active, disabled) {
11680
+ var classes = settings.oClasses.paging;
11681
+ var btnClasses = [classes.button];
11682
+ var btn;
11736
11683
 
11684
+ if (active) {
11685
+ btnClasses.push(classes.active);
11686
+ }
11737
11687
 
11738
- /**
11739
- * Selector extensions
11740
- *
11741
- * The `selector` option can be used to extend the options available for the
11742
- * selector modifier options (`selector-modifier` object data type) that
11743
- * each of the three built in selector types offer (row, column and cell +
11744
- * their plural counterparts). For example the Select extension uses this
11745
- * mechanism to provide an option to select only rows, columns and cells
11746
- * that have been marked as selected by the end user (`{selected: true}`),
11747
- * which can be used in conjunction with the existing built in selector
11748
- * options.
11749
- *
11750
- * Each property is an array to which functions can be pushed. The functions
11751
- * take three attributes:
11752
- *
11753
- * * Settings object for the host table
11754
- * * Options object (`selector-modifier` object type)
11755
- * * Array of selected item indexes
11756
- *
11757
- * The return is an array of the resulting item indexes after the custom
11758
- * selector has been applied.
11759
- *
11760
- * @type object
11761
- */
11762
- selector: {
11763
- cell: [],
11764
- column: [],
11765
- row: []
11766
- },
11688
+ if (disabled) {
11689
+ btnClasses.push(classes.disabled)
11690
+ }
11767
11691
 
11692
+ if (buttonType === 'ellipsis') {
11693
+ btn = $('<span class="ellipsis"></span>').html(content)[0];
11694
+ }
11695
+ else {
11696
+ btn = $('<button>', {
11697
+ class: btnClasses.join(' '),
11698
+ role: 'link',
11699
+ type: 'button'
11700
+ }).html(content);
11701
+ }
11768
11702
 
11769
- /**
11770
- * Legacy configuration options. Enable and disable legacy options that
11771
- * are available in DataTables.
11772
- *
11773
- * @type object
11774
- */
11775
- legacy: {
11776
- /**
11777
- * Enable / disable DataTables 1.9 compatible server-side processing
11778
- * requests
11779
- *
11780
- * @type boolean
11781
- * @default null
11782
- */
11783
- ajax: null
11703
+ return {
11704
+ display: btn,
11705
+ clicker: btn
11706
+ }
11707
+ }
11784
11708
  },
11785
11709
 
11786
-
11787
- /**
11788
- * Pagination plug-in methods.
11789
- *
11790
- * Each entry in this object is a function and defines which buttons should
11791
- * be shown by the pagination rendering method that is used for the table:
11792
- * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
11793
- * buttons are displayed in the document, while the functions here tell it
11794
- * what buttons to display. This is done by returning an array of button
11795
- * descriptions (what each button will do).
11796
- *
11797
- * Pagination types (the four built in options and any additional plug-in
11798
- * options defined here) can be used through the `paginationType`
11799
- * initialisation parameter.
11800
- *
11801
- * The functions defined take two parameters:
11802
- *
11803
- * 1. `{int} page` The current page index
11804
- * 2. `{int} pages` The number of pages in the table
11805
- *
11806
- * Each function is expected to return an array where each element of the
11807
- * array can be one of:
11808
- *
11809
- * * `first` - Jump to first page when activated
11810
- * * `last` - Jump to last page when activated
11811
- * * `previous` - Show previous page when activated
11812
- * * `next` - Show next page when activated
11813
- * * `{int}` - Show page of the index given
11814
- * * `{array}` - A nested array containing the above elements to add a
11815
- * containing 'DIV' element (might be useful for styling).
11816
- *
11817
- * Note that DataTables v1.9- used this object slightly differently whereby
11818
- * an object with two functions would be defined for each plug-in. That
11819
- * ability is still supported by DataTables 1.10+ to provide backwards
11820
- * compatibility, but this option of use is now decremented and no longer
11821
- * documented in DataTables 1.10+.
11822
- *
11823
- * @type object
11824
- * @default {}
11825
- *
11826
- * @example
11827
- * // Show previous, next and current page buttons only
11828
- * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
11829
- * return [ 'previous', page, 'next' ];
11830
- * };
11831
- */
11832
- pager: {},
11833
-
11834
-
11835
- renderer: {
11836
- pageButton: {},
11837
- header: {}
11838
- },
11839
-
11840
-
11841
- /**
11842
- * Ordering plug-ins - custom data source
11843
- *
11844
- * The extension options for ordering of data available here is complimentary
11845
- * to the default type based ordering that DataTables typically uses. It
11846
- * allows much greater control over the the data that is being used to
11847
- * order a column, but is necessarily therefore more complex.
11848
- *
11849
- * This type of ordering is useful if you want to do ordering based on data
11850
- * live from the DOM (for example the contents of an 'input' element) rather
11851
- * than just the static string that DataTables knows of.
11852
- *
11853
- * The way these plug-ins work is that you create an array of the values you
11854
- * wish to be ordering for the column in question and then return that
11855
- * array. The data in the array much be in the index order of the rows in
11856
- * the table (not the currently ordering order!). Which order data gathering
11857
- * function is run here depends on the `dt-init columns.orderDataType`
11858
- * parameter that is used for the column (if any).
11859
- *
11860
- * The functions defined take two parameters:
11861
- *
11862
- * 1. `{object}` DataTables settings object: see
11863
- * {@link DataTable.models.oSettings}
11864
- * 2. `{int}` Target column index
11865
- *
11866
- * Each function is expected to return an array:
11867
- *
11868
- * * `{array}` Data for the column to be ordering upon
11869
- *
11870
- * @type array
11871
- *
11872
- * @example
11873
- * // Ordering using `input` node values
11874
- * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
11875
- * {
11876
- * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
11877
- * return $('input', td).val();
11878
- * } );
11879
- * }
11880
- */
11881
- order: {},
11882
-
11883
-
11884
- /**
11885
- * Type based plug-ins.
11886
- *
11887
- * Each column in DataTables has a type assigned to it, either by automatic
11888
- * detection or by direct assignment using the `type` option for the column.
11889
- * The type of a column will effect how it is ordering and search (plug-ins
11890
- * can also make use of the column type if required).
11891
- *
11892
- * @namespace
11893
- */
11894
- type: {
11895
- /**
11896
- * Automatic column class assignment
11897
- */
11898
- className: {},
11899
-
11900
- /**
11901
- * Type detection functions.
11902
- *
11903
- * The functions defined in this object are used to automatically detect
11904
- * a column's type, making initialisation of DataTables super easy, even
11905
- * when complex data is in the table.
11906
- *
11907
- * The functions defined take two parameters:
11908
- *
11909
- * 1. `{*}` Data from the column cell to be analysed
11910
- * 2. `{settings}` DataTables settings object. This can be used to
11911
- * perform context specific type detection - for example detection
11912
- * based on language settings such as using a comma for a decimal
11913
- * place. Generally speaking the options from the settings will not
11914
- * be required
11915
- *
11916
- * Each function is expected to return:
11917
- *
11918
- * * `{string|null}` Data type detected, or null if unknown (and thus
11919
- * pass it on to the other type detection functions.
11920
- *
11921
- * @type array
11922
- *
11923
- * @example
11924
- * // Currency type detection plug-in:
11925
- * $.fn.dataTable.ext.type.detect.push(
11926
- * function ( data, settings ) {
11927
- * // Check the numeric part
11928
- * if ( ! data.substring(1).match(/[0-9]/) ) {
11929
- * return null;
11930
- * }
11931
- *
11932
- * // Check prefixed by currency
11933
- * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
11934
- * return 'currency';
11935
- * }
11936
- * return null;
11937
- * }
11938
- * );
11939
- */
11940
- detect: [],
11941
-
11942
- /**
11943
- * Automatic renderer assignment
11944
- */
11945
- render: {},
11946
-
11947
-
11948
- /**
11949
- * Type based search formatting.
11950
- *
11951
- * The type based searching functions can be used to pre-format the
11952
- * data to be search on. For example, it can be used to strip HTML
11953
- * tags or to de-format telephone numbers for numeric only searching.
11954
- *
11955
- * Note that is a search is not defined for a column of a given type,
11956
- * no search formatting will be performed.
11957
- *
11958
- * Pre-processing of searching data plug-ins - When you assign the sType
11959
- * for a column (or have it automatically detected for you by DataTables
11960
- * or a type detection plug-in), you will typically be using this for
11961
- * custom sorting, but it can also be used to provide custom searching
11962
- * by allowing you to pre-processing the data and returning the data in
11963
- * the format that should be searched upon. This is done by adding
11964
- * functions this object with a parameter name which matches the sType
11965
- * for that target column. This is the corollary of <i>afnSortData</i>
11966
- * for searching data.
11967
- *
11968
- * The functions defined take a single parameter:
11969
- *
11970
- * 1. `{*}` Data from the column cell to be prepared for searching
11971
- *
11972
- * Each function is expected to return:
11973
- *
11974
- * * `{string|null}` Formatted string that will be used for the searching.
11975
- *
11976
- * @type object
11977
- * @default {}
11978
- *
11979
- * @example
11980
- * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
11981
- * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
11982
- * }
11983
- */
11984
- search: {},
11985
-
11986
-
11987
- /**
11988
- * Type based ordering.
11989
- *
11990
- * The column type tells DataTables what ordering to apply to the table
11991
- * when a column is sorted upon. The order for each type that is defined,
11992
- * is defined by the functions available in this object.
11993
- *
11994
- * Each ordering option can be described by three properties added to
11995
- * this object:
11996
- *
11997
- * * `{type}-pre` - Pre-formatting function
11998
- * * `{type}-asc` - Ascending order function
11999
- * * `{type}-desc` - Descending order function
12000
- *
12001
- * All three can be used together, only `{type}-pre` or only
12002
- * `{type}-asc` and `{type}-desc` together. It is generally recommended
12003
- * that only `{type}-pre` is used, as this provides the optimal
12004
- * implementation in terms of speed, although the others are provided
12005
- * for compatibility with existing Javascript sort functions.
12006
- *
12007
- * `{type}-pre`: Functions defined take a single parameter:
12008
- *
12009
- * 1. `{*}` Data from the column cell to be prepared for ordering
12010
- *
12011
- * And return:
12012
- *
12013
- * * `{*}` Data to be sorted upon
12014
- *
12015
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
12016
- * functions, taking two parameters:
12017
- *
12018
- * 1. `{*}` Data to compare to the second parameter
12019
- * 2. `{*}` Data to compare to the first parameter
12020
- *
12021
- * And returning:
12022
- *
12023
- * * `{*}` Ordering match: <0 if first parameter should be sorted lower
12024
- * than the second parameter, ===0 if the two parameters are equal and
12025
- * >0 if the first parameter should be sorted height than the second
12026
- * parameter.
12027
- *
12028
- * @type object
12029
- * @default {}
12030
- *
12031
- * @example
12032
- * // Numeric ordering of formatted numbers with a pre-formatter
12033
- * $.extend( $.fn.dataTable.ext.type.order, {
12034
- * "string-pre": function(x) {
12035
- * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
12036
- * return parseFloat( a );
12037
- * }
12038
- * } );
12039
- *
12040
- * @example
12041
- * // Case-sensitive string ordering, with no pre-formatting method
12042
- * $.extend( $.fn.dataTable.ext.order, {
12043
- * "string-case-asc": function(x,y) {
12044
- * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
12045
- * },
12046
- * "string-case-desc": function(x,y) {
12047
- * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
12048
- * }
12049
- * } );
12050
- */
12051
- order: {}
12052
- },
12053
-
12054
- /**
12055
- * Unique DataTables instance counter
12056
- *
12057
- * @type int
12058
- * @private
12059
- */
12060
- _unique: 0,
12061
-
12062
-
12063
- //
12064
- // Depreciated
12065
- // The following properties are retained for backwards compatibility only.
12066
- // The should not be used in new projects and will be removed in a future
12067
- // version
12068
- //
12069
-
12070
- /**
12071
- * Version check function.
12072
- * @type function
12073
- * @depreciated Since 1.10
12074
- */
12075
- fnVersionCheck: DataTable.fnVersionCheck,
12076
-
12077
-
12078
- /**
12079
- * Index for what 'this' index API functions should use
12080
- * @type int
12081
- * @deprecated Since v1.10
12082
- */
12083
- iApiIndex: 0,
12084
-
12085
-
12086
- /**
12087
- * Software version
12088
- * @type string
12089
- * @deprecated Since v1.10
12090
- */
12091
- sVersion: DataTable.version
12092
- };
12093
-
12094
-
12095
- //
12096
- // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
12097
- //
12098
- $.extend( _ext, {
12099
- afnFiltering: _ext.search,
12100
- aTypes: _ext.type.detect,
12101
- ofnSearch: _ext.type.search,
12102
- oSort: _ext.type.order,
12103
- afnSortData: _ext.order,
12104
- aoFeatures: _ext.feature,
12105
- oStdClasses: _ext.classes,
12106
- oPagination: _ext.pager
12107
- } );
12108
-
12109
-
12110
- $.extend( DataTable.ext.classes, {
12111
- container: 'dt-container',
12112
- empty: {
12113
- row: 'dt-empty'
12114
- },
12115
- info: {
12116
- container: 'dt-info'
12117
- },
12118
- length: {
12119
- container: 'dt-length',
12120
- select: 'dt-input'
12121
- },
12122
- order: {
12123
- canAsc: 'dt-orderable-asc',
12124
- canDesc: 'dt-orderable-desc',
12125
- isAsc: 'dt-ordering-asc',
12126
- isDesc: 'dt-ordering-desc',
12127
- none: 'dt-orderable-none',
12128
- position: 'sorting_'
12129
- },
12130
- processing: {
12131
- container: 'dt-processing'
12132
- },
12133
- scrolling: {
12134
- body: 'dt-scroll-body',
12135
- container: 'dt-scroll',
12136
- footer: {
12137
- self: 'dt-scroll-foot',
12138
- inner: 'dt-scroll-footInner'
12139
- },
12140
- header: {
12141
- self: 'dt-scroll-head',
12142
- inner: 'dt-scroll-headInner'
12143
- }
12144
- },
12145
- search: {
12146
- container: 'dt-search',
12147
- input: 'dt-input'
12148
- },
12149
- table: 'dataTable',
12150
- tbody: {
12151
- cell: '',
12152
- row: ''
12153
- },
12154
- thead: {
12155
- cell: '',
12156
- row: ''
12157
- },
12158
- tfoot: {
12159
- cell: '',
12160
- row: ''
12161
- },
12162
- paging: {
12163
- active: 'current',
12164
- button: 'dt-paging-button',
12165
- container: 'dt-paging',
12166
- disabled: 'disabled'
12167
- }
12168
- } );
12169
-
12170
-
12171
- var extPagination = DataTable.ext.pager;
12172
-
12173
- // Paging buttons configuration
12174
- $.extend( extPagination, {
12175
- simple: function () {
12176
- return [ 'previous', 'next' ];
12177
- },
12178
-
12179
- full: function () {
12180
- return [ 'first', 'previous', 'next', 'last' ];
12181
- },
12182
-
12183
- numbers: function () {
12184
- return [ 'numbers' ];
12185
- },
12186
-
12187
- simple_numbers: function () {
12188
- return [ 'previous', 'numbers', 'next' ];
12189
- },
12190
-
12191
- full_numbers: function () {
12192
- return [ 'first', 'previous', 'numbers', 'next', 'last' ];
12193
- },
12194
-
12195
- first_last: function () {
12196
- return ['first', 'last'];
12197
- },
12198
-
12199
- first_last_numbers: function () {
12200
- return ['first', 'numbers', 'last'];
12201
- },
12202
-
12203
- // For testing and plug-ins to use
12204
- _numbers: _pagingNumbers,
12205
-
12206
- // Number of number buttons - legacy, use `numbers` option for paging feature
12207
- numbers_length: 7
12208
- } );
12209
-
12210
-
12211
- $.extend( true, DataTable.ext.renderer, {
12212
- pagingButton: {
12213
- _: function (settings, buttonType, content, active, disabled) {
12214
- var classes = settings.oClasses.paging;
12215
- var btnClasses = [classes.button];
12216
- var btn;
12217
-
12218
- if (active) {
12219
- btnClasses.push(classes.active);
12220
- }
12221
-
12222
- if (disabled) {
12223
- btnClasses.push(classes.disabled)
12224
- }
12225
-
12226
- if (buttonType === 'ellipsis') {
12227
- btn = $('<span class="ellipsis"></span>').html(content)[0];
12228
- }
12229
- else {
12230
- btn = $('<button>', {
12231
- class: btnClasses.join(' '),
12232
- role: 'link',
12233
- type: 'button'
12234
- }).html(content);
12235
- }
12236
-
12237
- return {
12238
- display: btn,
12239
- clicker: btn
12240
- }
12241
- }
12242
- },
12243
-
12244
- pagingContainer: {
12245
- _: function (settings, buttons) {
12246
- // No wrapping element - just append directly to the host
12247
- return buttons;
12248
- }
12249
- }
12250
- } );
11710
+ pagingContainer: {
11711
+ _: function (settings, buttons) {
11712
+ // No wrapping element - just append directly to the host
11713
+ return buttons;
11714
+ }
11715
+ }
11716
+ } );
12251
11717
 
12252
11718
  // Common function to remove new lines, strip HTML and diacritic control
12253
11719
  var _filterString = function (stripHtml, normalize) {
@@ -12907,9 +12373,9 @@ $.extend( true, DataTable.ext.renderer, {
12907
12373
  var ariaType = '';
12908
12374
  var indexes = columns.indexes();
12909
12375
  var sortDirs = columns.orderable(true).flatten();
12910
- var orderedColumns = sorting.map( function (val) {
12376
+ var orderedColumns = ',' + sorting.map( function (val) {
12911
12377
  return val.col;
12912
- } ).join(',');
12378
+ } ).join(',') + ',';
12913
12379
 
12914
12380
  cell
12915
12381
  .removeClass(
@@ -12920,7 +12386,7 @@ $.extend( true, DataTable.ext.renderer, {
12920
12386
  .toggleClass( orderClasses.canAsc, orderable && sortDirs.includes('asc') )
12921
12387
  .toggleClass( orderClasses.canDesc, orderable && sortDirs.includes('desc') );
12922
12388
 
12923
- var sortIdx = orderedColumns.indexOf( indexes.toArray().join(',') );
12389
+ var sortIdx = orderedColumns.indexOf( ',' + indexes.toArray().join(',') + ',' );
12924
12390
 
12925
12391
  if ( sortIdx !== -1 ) {
12926
12392
  // Get the ordering direction for the columns under this cell
@@ -12935,7 +12401,7 @@ $.extend( true, DataTable.ext.renderer, {
12935
12401
  }
12936
12402
 
12937
12403
  // The ARIA spec says that only one column should be marked with aria-sort
12938
- if ( sortIdx === 0 && orderedColumns.length === indexes.count() ) {
12404
+ if ( sortIdx === 0 ) {
12939
12405
  var firstSort = sorting[0];
12940
12406
  var sortOrder = col.asSorting;
12941
12407
 
@@ -13031,7 +12497,7 @@ DataTable.feature.register( 'info', function ( settings, opts ) {
13031
12497
  });
13032
12498
 
13033
12499
  // For the first info display in the table, we add a callback and aria information.
13034
- if (! $('#' + tid+'_info', settings.nWrapper).length) {
12500
+ if (! settings._infoEl) {
13035
12501
  n.attr({
13036
12502
  'aria-live': 'polite',
13037
12503
  id: tid+'_info',
@@ -13040,6 +12506,8 @@ DataTable.feature.register( 'info', function ( settings, opts ) {
13040
12506
 
13041
12507
  // Table is described by our info div
13042
12508
  $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
12509
+
12510
+ settings._infoEl = n;
13043
12511
  }
13044
12512
 
13045
12513
  return n;
@@ -13197,7 +12665,7 @@ DataTable.feature.register( 'search', function ( settings, opts ) {
13197
12665
 
13198
12666
  // opts
13199
12667
  // - type - button configuration
13200
- // - numbers - number of buttons to show - must be odd
12668
+ // - buttons - number of buttons to show - must be odd
13201
12669
  DataTable.feature.register( 'paging', function ( settings, opts ) {
13202
12670
  // Don't show the paging input if the table doesn't have paging enabled
13203
12671
  if (! settings.oFeatures.bPaginate) {
@@ -13205,9 +12673,15 @@ DataTable.feature.register( 'paging', function ( settings, opts ) {
13205
12673
  }
13206
12674
 
13207
12675
  opts = $.extend({
13208
- numbers: DataTable.ext.pager.numbers_length,
13209
- type: settings.sPaginationType
13210
- }, opts)
12676
+ buttons: DataTable.ext.pager.numbers_length,
12677
+ type: settings.sPaginationType,
12678
+ boundaryNumbers: true
12679
+ }, opts);
12680
+
12681
+ // To be removed in 2.1
12682
+ if (opts.numbers) {
12683
+ opts.buttons = opts.numbers;
12684
+ }
13211
12685
 
13212
12686
  var host = $('<div/>').addClass( settings.oClasses.paging.container + ' paging_' + opts.type );
13213
12687
  var draw = function () {
@@ -13239,7 +12713,7 @@ function _pagingDraw(settings, host, opts) {
13239
12713
  buttons = plugin()
13240
12714
  .map(function (val) {
13241
12715
  return val === 'numbers'
13242
- ? _pagingNumbers(page, pages, opts.numbers)
12716
+ ? _pagingNumbers(page, pages, opts.buttons, opts.boundaryNumbers)
13243
12717
  : val;
13244
12718
  })
13245
12719
  .flat();
@@ -13381,12 +12855,15 @@ function _pagingButtonInfo(settings, button, page, pages) {
13381
12855
  * @param {*} page Current page
13382
12856
  * @param {*} pages Total number of pages
13383
12857
  * @param {*} buttons Target number of number buttons
12858
+ * @param {boolean} addFirstLast Indicate if page 1 and end should be included
13384
12859
  * @returns Buttons to show
13385
12860
  */
13386
- function _pagingNumbers ( page, pages, buttons ) {
12861
+ function _pagingNumbers ( page, pages, buttons, addFirstLast ) {
13387
12862
  var
13388
12863
  numbers = [],
13389
- half = Math.floor(buttons / 2);
12864
+ half = Math.floor(buttons / 2),
12865
+ before = addFirstLast ? 2 : 1,
12866
+ after = addFirstLast ? 1 : 0;
13390
12867
 
13391
12868
  if ( pages <= buttons ) {
13392
12869
  numbers = _range(0, pages);
@@ -13409,17 +12886,30 @@ function _pagingNumbers ( page, pages, buttons ) {
13409
12886
  }
13410
12887
  }
13411
12888
  else if ( page <= half ) {
13412
- numbers = _range(0, buttons-2);
13413
- numbers.push('ellipsis', pages-1);
12889
+ numbers = _range(0, buttons-before);
12890
+ numbers.push('ellipsis');
12891
+
12892
+ if (addFirstLast) {
12893
+ numbers.push(pages-1);
12894
+ }
13414
12895
  }
13415
12896
  else if ( page >= pages - 1 - half ) {
13416
- numbers = _range(pages-(buttons-2), pages);
13417
- numbers.unshift(0, 'ellipsis');
12897
+ numbers = _range(pages-(buttons-before), pages);
12898
+ numbers.unshift('ellipsis');
12899
+
12900
+ if (addFirstLast) {
12901
+ numbers.unshift(0);
12902
+ }
13418
12903
  }
13419
12904
  else {
13420
- numbers = _range(page-half+2, page+half-1);
13421
- numbers.push('ellipsis', pages-1);
13422
- numbers.unshift(0, 'ellipsis');
12905
+ numbers = _range(page-half+before, page+half-after);
12906
+ numbers.push('ellipsis');
12907
+ numbers.unshift('ellipsis');
12908
+
12909
+ if (addFirstLast) {
12910
+ numbers.push(pages-1);
12911
+ numbers.unshift(0);
12912
+ }
13423
12913
  }
13424
12914
 
13425
12915
  return numbers;