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.js CHANGED
@@ -1,11 +1,11 @@
1
- /*! DataTables 2.0.2
1
+ /*! DataTables 2.0.4
2
2
  * © SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary DataTables
7
7
  * @description Paginate, search and order HTML tables
8
- * @version 2.0.2
8
+ * @version 2.0.4
9
9
  * @author SpryMedia Ltd
10
10
  * @contact www.datatables.net
11
11
  * @copyright SpryMedia Ltd.
@@ -1096,7 +1096,8 @@
1096
1096
 
1097
1097
  var _re_dic = {};
1098
1098
  var _re_new_lines = /[\r\n\u2028]/g;
1099
- var _re_html = /<.*?>/g;
1099
+ var _re_html = /<([^>]*>)/g;
1100
+ var _max_str_len = Math.pow(2, 28);
1100
1101
 
1101
1102
  // This is not strict ISO8601 - Date.parse() is quite lax, although
1102
1103
  // implementations differ between browsers.
@@ -1284,10 +1285,24 @@
1284
1285
  };
1285
1286
 
1286
1287
  // Replaceable function in api.util
1287
- var _stripHtml = function ( d ) {
1288
- return d
1289
- .replace( _re_html, '' ) // Complete tags
1290
- .replace(/<script/i, ''); // Safety for incomplete script tag
1288
+ var _stripHtml = function (input) {
1289
+ // Irrelevant check to workaround CodeQL's false positive on the regex
1290
+ if (input.length > _max_str_len) {
1291
+ throw new Error('Exceeded max str len');
1292
+ }
1293
+
1294
+ var previous;
1295
+
1296
+ input = input.replace(_re_html, ''); // Complete tags
1297
+
1298
+ // Safety for incomplete script tag - use do / while to ensure that
1299
+ // we get all instances
1300
+ do {
1301
+ previous = input;
1302
+ input = input.replace(/<script/i, '');
1303
+ } while (input !== previous);
1304
+
1305
+ return previous;
1291
1306
  };
1292
1307
 
1293
1308
  // Replaceable function in api.util
@@ -2002,7 +2017,7 @@
2002
2017
  "mData": oDefaults.mData ? oDefaults.mData : iCol,
2003
2018
  idx: iCol,
2004
2019
  searchFixed: {},
2005
- colEl: $('<col>')
2020
+ colEl: $('<col>').attr('data-dt-column', iCol)
2006
2021
  } );
2007
2022
  oSettings.aoColumns.push( oCol );
2008
2023
 
@@ -3417,8 +3432,15 @@
3417
3432
  _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
3418
3433
  _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3419
3434
 
3420
- body.children().detach();
3421
- body.append( $(anRows) );
3435
+ // replaceChildren is faster, but only became widespread in 2020,
3436
+ // so a fall back in jQuery is provided for older browsers.
3437
+ if (body[0].replaceChildren) {
3438
+ body[0].replaceChildren.apply(body[0], anRows);
3439
+ }
3440
+ else {
3441
+ body.children().detach();
3442
+ body.append( $(anRows) );
3443
+ }
3422
3444
 
3423
3445
  // Empty table needs a specific class
3424
3446
  $(oSettings.nTableWrapper).toggleClass('dt-empty-footer', $('tr', oSettings.nTFoot).length === 0);
@@ -3686,15 +3708,15 @@
3686
3708
 
3687
3709
  settings.nTableWrapper = insert[0];
3688
3710
 
3689
- var top = _layoutArray( settings, settings.layout, 'top' );
3690
- var bottom = _layoutArray( settings, settings.layout, 'bottom' );
3691
- var renderer = _fnRenderer( settings, 'layout' );
3692
-
3693
3711
  if (settings.sDom) {
3694
3712
  // Legacy
3695
3713
  _fnLayoutDom(settings, settings.sDom, insert);
3696
3714
  }
3697
3715
  else {
3716
+ var top = _layoutArray( settings, settings.layout, 'top' );
3717
+ var bottom = _layoutArray( settings, settings.layout, 'bottom' );
3718
+ var renderer = _fnRenderer( settings, 'layout' );
3719
+
3698
3720
  // Everything above - the renderer will actually insert the contents into the document
3699
3721
  top.forEach(function (item) {
3700
3722
  renderer( settings, insert, item );
@@ -3880,7 +3902,7 @@
3880
3902
  }
3881
3903
 
3882
3904
  if (! columnDef.sTitle && unique) {
3883
- columnDef.sTitle = cell.innerHTML.replace( /<.*?>/g, "" );
3905
+ columnDef.sTitle = _stripHtml(cell.innerHTML);
3884
3906
  columnDef.autoTitle = true;
3885
3907
  }
3886
3908
  }
@@ -4501,7 +4523,7 @@
4501
4523
  word = '';
4502
4524
  }
4503
4525
 
4504
- return word.replace('"', '');
4526
+ return word.replace(/"/g, '');
4505
4527
  } );
4506
4528
 
4507
4529
  var match = not.length
@@ -5033,20 +5055,27 @@
5033
5055
  // uses a cell which has a longer string, but isn't the widest! For example
5034
5056
  // "Chief Executive Officer (CEO)" is the longest string in the demo, but
5035
5057
  // "Systems Administrator" is actually the widest string since it doesn't collapse.
5058
+ // Note the use of translating into a column index to get the `col` element. This
5059
+ // is because of Responsive which might remove `col` elements, knocking the alignment
5060
+ // of the indexes out.
5036
5061
  if (settings.aiDisplay.length) {
5037
5062
  // Get the column sizes from the first row in the table
5038
- var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function () {
5039
- return $(this).outerWidth();
5063
+ var colSizes = table.find('tbody tr').eq(0).find('th, td').map(function (vis) {
5064
+ return {
5065
+ idx: _fnVisibleToColumnIndex(settings, vis),
5066
+ width: $(this).outerWidth()
5067
+ }
5040
5068
  });
5041
5069
 
5042
5070
  // Check against what the colgroup > col is set to and correct if needed
5043
- $('col', settings.colgroup).each(function (i) {
5044
- var colWidth = this.style.width.replace('px', '');
5071
+ for (var i=0 ; i<colSizes.length ; i++) {
5072
+ var colEl = settings.aoColumns[ colSizes[i].idx ].colEl[0];
5073
+ var colWidth = colEl.style.width.replace('px', '');
5045
5074
 
5046
- if (colWidth !== colSizes[i]) {
5047
- this.style.width = colSizes[i] + 'px';
5075
+ if (colWidth !== colSizes[i].width) {
5076
+ colEl.style.width = colSizes[i].width + 'px';
5048
5077
  }
5049
- });
5078
+ }
5050
5079
  }
5051
5080
 
5052
5081
  // 3. Copy the colgroup over to the header and footer
@@ -5454,10 +5483,13 @@
5454
5483
  // Allow the processing display to show
5455
5484
  setTimeout( function () {
5456
5485
  _fnSort( settings );
5457
- _fnSortDisplay( settings );
5458
- _fnReDraw( settings, false, false );
5486
+ _fnSortDisplay( settings, settings.aiDisplay );
5487
+
5488
+ // Sort processing done - redraw has its own processing display
5459
5489
  _fnProcessingDisplay( settings, false );
5460
5490
 
5491
+ _fnReDraw( settings, false, false );
5492
+
5461
5493
  if (callback) {
5462
5494
  callback();
5463
5495
  }
@@ -5471,8 +5503,7 @@
5471
5503
  * Sort the display array to match the master's order
5472
5504
  * @param {*} settings
5473
5505
  */
5474
- function _fnSortDisplay(settings) {
5475
- var display = settings.aiDisplay;
5506
+ function _fnSortDisplay(settings, display) {
5476
5507
  var master = settings.aiDisplayMaster;
5477
5508
  var masterMap = {};
5478
5509
  var map = {};
@@ -6840,6 +6871,10 @@
6840
6871
  for ( i=0, ien=ext.length ; i<ien ; i++ ) {
6841
6872
  struct = ext[i];
6842
6873
 
6874
+ if (struct.name === '__proto__') {
6875
+ continue;
6876
+ }
6877
+
6843
6878
  // Value
6844
6879
  obj[ struct.name ] = struct.type === 'function' ?
6845
6880
  _api_scope( scope, struct.val, struct ) :
@@ -7502,16 +7537,7 @@
7502
7537
  order = opts.order, // applied, current, index (original - compatibility with 1.9)
7503
7538
  page = opts.page; // all, current
7504
7539
 
7505
- if ( _fnDataSource( settings ) == 'ssp' ) {
7506
- // In server-side processing mode, most options are irrelevant since
7507
- // rows not shown don't exist and the index order is the applied order
7508
- // Removed is a special case - for consistency just return an empty
7509
- // array
7510
- return search === 'removed' ?
7511
- [] :
7512
- _range( 0, displayMaster.length );
7513
- }
7514
- else if ( page == 'current' ) {
7540
+ if ( page == 'current' ) {
7515
7541
  // Current page implies that order=current and filter=applied, since it is
7516
7542
  // fairly senseless otherwise, regardless of what order and search actually
7517
7543
  // are
@@ -7693,11 +7719,7 @@
7693
7719
  var matched = _selector_run( 'row', selector, run, settings, opts );
7694
7720
 
7695
7721
  if (opts.order === 'current' || opts.order === 'applied') {
7696
- var master = settings.aiDisplayMaster;
7697
-
7698
- matched.sort(function(a, b) {
7699
- return master.indexOf(a) - master.indexOf(b);
7700
- });
7722
+ _fnSortDisplay(settings, matched);
7701
7723
  }
7702
7724
 
7703
7725
  return matched;
@@ -7938,8 +7960,9 @@
7938
7960
  {
7939
7961
  if ( state && state.childRows ) {
7940
7962
  api
7941
- .rows( state.childRows.map(function (id){
7942
- return id.replace(/:/g, '\\:')
7963
+ .rows( state.childRows.map(function (id) {
7964
+ // Escape any `:` characters from the row id, unless previously escaped
7965
+ return id.replace(/(?<!\\):/g, '\\:');
7943
7966
  }) )
7944
7967
  .every( function () {
7945
7968
  _fnCallbackFire( api.settings()[0], null, 'requestChild', [ this ] )
@@ -8220,6 +8243,17 @@
8220
8243
  };
8221
8244
 
8222
8245
 
8246
+ var __column_header = function ( settings, column, row ) {
8247
+ var header = settings.aoHeader;
8248
+ var target = row !== undefined
8249
+ ? row
8250
+ : settings.bSortCellsTop // legacy support
8251
+ ? 0
8252
+ : header.length - 1;
8253
+
8254
+ return header[target][column].cell;
8255
+ };
8256
+
8223
8257
  var __column_selector = function ( settings, selector, opts )
8224
8258
  {
8225
8259
  var
@@ -8252,7 +8286,8 @@
8252
8286
  return columns.map(function (col, idx) {
8253
8287
  return s(
8254
8288
  idx,
8255
- __columnData( settings, idx, 0, 0, rows )
8289
+ __columnData( settings, idx, 0, 0, rows ),
8290
+ __column_header( settings, idx )
8256
8291
  ) ? idx : null;
8257
8292
  });
8258
8293
  }
@@ -8397,15 +8432,8 @@
8397
8432
  } );
8398
8433
 
8399
8434
  _api_registerPlural( 'columns().header()', 'column().header()', function ( row ) {
8400
- return this.iterator( 'column', function ( settings, column ) {
8401
- var header = settings.aoHeader;
8402
- var target = row !== undefined
8403
- ? row
8404
- : settings.bSortCellsTop // legacy support
8405
- ? 0
8406
- : header.length - 1;
8407
-
8408
- return header[target][column].cell;
8435
+ return this.iterator( 'column', function (settings, column) {
8436
+ return __column_header(settings, column, row);
8409
8437
  }, 1 );
8410
8438
  } );
8411
8439
 
@@ -9558,7 +9586,7 @@
9558
9586
  * @type string
9559
9587
  * @default Version number
9560
9588
  */
9561
- DataTable.version = "2.0.2";
9589
+ DataTable.version = "2.0.4";
9562
9590
 
9563
9591
  /**
9564
9592
  * Private data store, containing all of the settings objects that are
@@ -10413,24 +10441,24 @@
10413
10441
  */
10414
10442
  "oPaginate": {
10415
10443
  /**
10416
- * Label and character for first page button
10444
+ * Label and character for first page button («)
10417
10445
  */
10418
- "sFirst": "«",
10446
+ "sFirst": "\u00AB",
10419
10447
 
10420
10448
  /**
10421
- * Last page button
10449
+ * Last page button (»)
10422
10450
  */
10423
- "sLast": "»",
10451
+ "sLast": "\u00BB",
10424
10452
 
10425
10453
  /**
10426
- * Next page button
10454
+ * Next page button (›)
10427
10455
  */
10428
- "sNext": "",
10456
+ "sNext": "\u203A",
10429
10457
 
10430
10458
  /**
10431
- * Previous page button
10459
+ * Previous page button (‹)
10432
10460
  */
10433
- "sPrevious": "",
10461
+ "sPrevious": "\u2039",
10434
10462
  },
10435
10463
 
10436
10464
  /**
@@ -11659,648 +11687,86 @@
11659
11687
  */
11660
11688
 
11661
11689
 
11662
- /**
11663
- * DataTables extensions
11664
- *
11665
- * This namespace acts as a collection area for plug-ins that can be used to
11666
- * extend DataTables capabilities. Indeed many of the build in methods
11667
- * use this method to provide their own capabilities (sorting methods for
11668
- * example).
11669
- *
11670
- * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
11671
- * reasons
11672
- *
11673
- * @namespace
11674
- */
11675
- DataTable.ext = _ext = {
11676
- /**
11677
- * Buttons. For use with the Buttons extension for DataTables. This is
11678
- * defined here so other extensions can define buttons regardless of load
11679
- * order. It is _not_ used by DataTables core.
11680
- *
11681
- * @type object
11682
- * @default {}
11683
- */
11684
- buttons: {},
11685
-
11686
-
11687
- /**
11688
- * Element class names
11689
- *
11690
- * @type object
11691
- * @default {}
11692
- */
11693
- classes: {},
11690
+ var extPagination = DataTable.ext.pager;
11694
11691
 
11692
+ // Paging buttons configuration
11693
+ $.extend( extPagination, {
11694
+ simple: function () {
11695
+ return [ 'previous', 'next' ];
11696
+ },
11695
11697
 
11696
- /**
11697
- * DataTables build type (expanded by the download builder)
11698
- *
11699
- * @type string
11700
- */
11701
- builder: "-source-",
11698
+ full: function () {
11699
+ return [ 'first', 'previous', 'next', 'last' ];
11700
+ },
11702
11701
 
11702
+ numbers: function () {
11703
+ return [ 'numbers' ];
11704
+ },
11703
11705
 
11704
- /**
11705
- * Error reporting.
11706
- *
11707
- * How should DataTables report an error. Can take the value 'alert',
11708
- * 'throw', 'none' or a function.
11709
- *
11710
- * @type string|function
11711
- * @default alert
11712
- */
11713
- errMode: "alert",
11706
+ simple_numbers: function () {
11707
+ return [ 'previous', 'numbers', 'next' ];
11708
+ },
11714
11709
 
11710
+ full_numbers: function () {
11711
+ return [ 'first', 'previous', 'numbers', 'next', 'last' ];
11712
+ },
11713
+
11714
+ first_last: function () {
11715
+ return ['first', 'last'];
11716
+ },
11717
+
11718
+ first_last_numbers: function () {
11719
+ return ['first', 'numbers', 'last'];
11720
+ },
11715
11721
 
11716
- /**
11717
- * Legacy so v1 plug-ins don't throw js errors on load
11718
- */
11719
- feature: [],
11722
+ // For testing and plug-ins to use
11723
+ _numbers: _pagingNumbers,
11720
11724
 
11721
- /**
11722
- * Feature plug-ins.
11723
- *
11724
- * This is an object of callbacks which provide the features for DataTables
11725
- * to be initialised via the `layout` option.
11726
- */
11727
- features: {},
11725
+ // Number of number buttons - legacy, use `numbers` option for paging feature
11726
+ numbers_length: 7
11727
+ } );
11728
11728
 
11729
11729
 
11730
- /**
11731
- * Row searching.
11732
- *
11733
- * This method of searching is complimentary to the default type based
11734
- * searching, and a lot more comprehensive as it allows you complete control
11735
- * over the searching logic. Each element in this array is a function
11736
- * (parameters described below) that is called for every row in the table,
11737
- * and your logic decides if it should be included in the searching data set
11738
- * or not.
11739
- *
11740
- * Searching functions have the following input parameters:
11741
- *
11742
- * 1. `{object}` DataTables settings object: see
11743
- * {@link DataTable.models.oSettings}
11744
- * 2. `{array|object}` Data for the row to be processed (same as the
11745
- * original format that was passed in as the data source, or an array
11746
- * from a DOM data source
11747
- * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
11748
- * can be useful to retrieve the `TR` element if you need DOM interaction.
11749
- *
11750
- * And the following return is expected:
11751
- *
11752
- * * {boolean} Include the row in the searched result set (true) or not
11753
- * (false)
11754
- *
11755
- * Note that as with the main search ability in DataTables, technically this
11756
- * is "filtering", since it is subtractive. However, for consistency in
11757
- * naming we call it searching here.
11758
- *
11759
- * @type array
11760
- * @default []
11761
- *
11762
- * @example
11763
- * // The following example shows custom search being applied to the
11764
- * // fourth column (i.e. the data[3] index) based on two input values
11765
- * // from the end-user, matching the data in a certain range.
11766
- * $.fn.dataTable.ext.search.push(
11767
- * function( settings, data, dataIndex ) {
11768
- * var min = document.getElementById('min').value * 1;
11769
- * var max = document.getElementById('max').value * 1;
11770
- * var version = data[3] == "-" ? 0 : data[3]*1;
11771
- *
11772
- * if ( min == "" && max == "" ) {
11773
- * return true;
11774
- * }
11775
- * else if ( min == "" && version < max ) {
11776
- * return true;
11777
- * }
11778
- * else if ( min < version && "" == max ) {
11779
- * return true;
11780
- * }
11781
- * else if ( min < version && version < max ) {
11782
- * return true;
11783
- * }
11784
- * return false;
11785
- * }
11786
- * );
11787
- */
11788
- search: [],
11730
+ $.extend( true, DataTable.ext.renderer, {
11731
+ pagingButton: {
11732
+ _: function (settings, buttonType, content, active, disabled) {
11733
+ var classes = settings.oClasses.paging;
11734
+ var btnClasses = [classes.button];
11735
+ var btn;
11789
11736
 
11737
+ if (active) {
11738
+ btnClasses.push(classes.active);
11739
+ }
11790
11740
 
11791
- /**
11792
- * Selector extensions
11793
- *
11794
- * The `selector` option can be used to extend the options available for the
11795
- * selector modifier options (`selector-modifier` object data type) that
11796
- * each of the three built in selector types offer (row, column and cell +
11797
- * their plural counterparts). For example the Select extension uses this
11798
- * mechanism to provide an option to select only rows, columns and cells
11799
- * that have been marked as selected by the end user (`{selected: true}`),
11800
- * which can be used in conjunction with the existing built in selector
11801
- * options.
11802
- *
11803
- * Each property is an array to which functions can be pushed. The functions
11804
- * take three attributes:
11805
- *
11806
- * * Settings object for the host table
11807
- * * Options object (`selector-modifier` object type)
11808
- * * Array of selected item indexes
11809
- *
11810
- * The return is an array of the resulting item indexes after the custom
11811
- * selector has been applied.
11812
- *
11813
- * @type object
11814
- */
11815
- selector: {
11816
- cell: [],
11817
- column: [],
11818
- row: []
11819
- },
11741
+ if (disabled) {
11742
+ btnClasses.push(classes.disabled)
11743
+ }
11820
11744
 
11745
+ if (buttonType === 'ellipsis') {
11746
+ btn = $('<span class="ellipsis"></span>').html(content)[0];
11747
+ }
11748
+ else {
11749
+ btn = $('<button>', {
11750
+ class: btnClasses.join(' '),
11751
+ role: 'link',
11752
+ type: 'button'
11753
+ }).html(content);
11754
+ }
11821
11755
 
11822
- /**
11823
- * Legacy configuration options. Enable and disable legacy options that
11824
- * are available in DataTables.
11825
- *
11826
- * @type object
11827
- */
11828
- legacy: {
11829
- /**
11830
- * Enable / disable DataTables 1.9 compatible server-side processing
11831
- * requests
11832
- *
11833
- * @type boolean
11834
- * @default null
11835
- */
11836
- ajax: null
11756
+ return {
11757
+ display: btn,
11758
+ clicker: btn
11759
+ }
11760
+ }
11837
11761
  },
11838
11762
 
11839
-
11840
- /**
11841
- * Pagination plug-in methods.
11842
- *
11843
- * Each entry in this object is a function and defines which buttons should
11844
- * be shown by the pagination rendering method that is used for the table:
11845
- * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
11846
- * buttons are displayed in the document, while the functions here tell it
11847
- * what buttons to display. This is done by returning an array of button
11848
- * descriptions (what each button will do).
11849
- *
11850
- * Pagination types (the four built in options and any additional plug-in
11851
- * options defined here) can be used through the `paginationType`
11852
- * initialisation parameter.
11853
- *
11854
- * The functions defined take two parameters:
11855
- *
11856
- * 1. `{int} page` The current page index
11857
- * 2. `{int} pages` The number of pages in the table
11858
- *
11859
- * Each function is expected to return an array where each element of the
11860
- * array can be one of:
11861
- *
11862
- * * `first` - Jump to first page when activated
11863
- * * `last` - Jump to last page when activated
11864
- * * `previous` - Show previous page when activated
11865
- * * `next` - Show next page when activated
11866
- * * `{int}` - Show page of the index given
11867
- * * `{array}` - A nested array containing the above elements to add a
11868
- * containing 'DIV' element (might be useful for styling).
11869
- *
11870
- * Note that DataTables v1.9- used this object slightly differently whereby
11871
- * an object with two functions would be defined for each plug-in. That
11872
- * ability is still supported by DataTables 1.10+ to provide backwards
11873
- * compatibility, but this option of use is now decremented and no longer
11874
- * documented in DataTables 1.10+.
11875
- *
11876
- * @type object
11877
- * @default {}
11878
- *
11879
- * @example
11880
- * // Show previous, next and current page buttons only
11881
- * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
11882
- * return [ 'previous', page, 'next' ];
11883
- * };
11884
- */
11885
- pager: {},
11886
-
11887
-
11888
- renderer: {
11889
- pageButton: {},
11890
- header: {}
11891
- },
11892
-
11893
-
11894
- /**
11895
- * Ordering plug-ins - custom data source
11896
- *
11897
- * The extension options for ordering of data available here is complimentary
11898
- * to the default type based ordering that DataTables typically uses. It
11899
- * allows much greater control over the the data that is being used to
11900
- * order a column, but is necessarily therefore more complex.
11901
- *
11902
- * This type of ordering is useful if you want to do ordering based on data
11903
- * live from the DOM (for example the contents of an 'input' element) rather
11904
- * than just the static string that DataTables knows of.
11905
- *
11906
- * The way these plug-ins work is that you create an array of the values you
11907
- * wish to be ordering for the column in question and then return that
11908
- * array. The data in the array much be in the index order of the rows in
11909
- * the table (not the currently ordering order!). Which order data gathering
11910
- * function is run here depends on the `dt-init columns.orderDataType`
11911
- * parameter that is used for the column (if any).
11912
- *
11913
- * The functions defined take two parameters:
11914
- *
11915
- * 1. `{object}` DataTables settings object: see
11916
- * {@link DataTable.models.oSettings}
11917
- * 2. `{int}` Target column index
11918
- *
11919
- * Each function is expected to return an array:
11920
- *
11921
- * * `{array}` Data for the column to be ordering upon
11922
- *
11923
- * @type array
11924
- *
11925
- * @example
11926
- * // Ordering using `input` node values
11927
- * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
11928
- * {
11929
- * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
11930
- * return $('input', td).val();
11931
- * } );
11932
- * }
11933
- */
11934
- order: {},
11935
-
11936
-
11937
- /**
11938
- * Type based plug-ins.
11939
- *
11940
- * Each column in DataTables has a type assigned to it, either by automatic
11941
- * detection or by direct assignment using the `type` option for the column.
11942
- * The type of a column will effect how it is ordering and search (plug-ins
11943
- * can also make use of the column type if required).
11944
- *
11945
- * @namespace
11946
- */
11947
- type: {
11948
- /**
11949
- * Automatic column class assignment
11950
- */
11951
- className: {},
11952
-
11953
- /**
11954
- * Type detection functions.
11955
- *
11956
- * The functions defined in this object are used to automatically detect
11957
- * a column's type, making initialisation of DataTables super easy, even
11958
- * when complex data is in the table.
11959
- *
11960
- * The functions defined take two parameters:
11961
- *
11962
- * 1. `{*}` Data from the column cell to be analysed
11963
- * 2. `{settings}` DataTables settings object. This can be used to
11964
- * perform context specific type detection - for example detection
11965
- * based on language settings such as using a comma for a decimal
11966
- * place. Generally speaking the options from the settings will not
11967
- * be required
11968
- *
11969
- * Each function is expected to return:
11970
- *
11971
- * * `{string|null}` Data type detected, or null if unknown (and thus
11972
- * pass it on to the other type detection functions.
11973
- *
11974
- * @type array
11975
- *
11976
- * @example
11977
- * // Currency type detection plug-in:
11978
- * $.fn.dataTable.ext.type.detect.push(
11979
- * function ( data, settings ) {
11980
- * // Check the numeric part
11981
- * if ( ! data.substring(1).match(/[0-9]/) ) {
11982
- * return null;
11983
- * }
11984
- *
11985
- * // Check prefixed by currency
11986
- * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
11987
- * return 'currency';
11988
- * }
11989
- * return null;
11990
- * }
11991
- * );
11992
- */
11993
- detect: [],
11994
-
11995
- /**
11996
- * Automatic renderer assignment
11997
- */
11998
- render: {},
11999
-
12000
-
12001
- /**
12002
- * Type based search formatting.
12003
- *
12004
- * The type based searching functions can be used to pre-format the
12005
- * data to be search on. For example, it can be used to strip HTML
12006
- * tags or to de-format telephone numbers for numeric only searching.
12007
- *
12008
- * Note that is a search is not defined for a column of a given type,
12009
- * no search formatting will be performed.
12010
- *
12011
- * Pre-processing of searching data plug-ins - When you assign the sType
12012
- * for a column (or have it automatically detected for you by DataTables
12013
- * or a type detection plug-in), you will typically be using this for
12014
- * custom sorting, but it can also be used to provide custom searching
12015
- * by allowing you to pre-processing the data and returning the data in
12016
- * the format that should be searched upon. This is done by adding
12017
- * functions this object with a parameter name which matches the sType
12018
- * for that target column. This is the corollary of <i>afnSortData</i>
12019
- * for searching data.
12020
- *
12021
- * The functions defined take a single parameter:
12022
- *
12023
- * 1. `{*}` Data from the column cell to be prepared for searching
12024
- *
12025
- * Each function is expected to return:
12026
- *
12027
- * * `{string|null}` Formatted string that will be used for the searching.
12028
- *
12029
- * @type object
12030
- * @default {}
12031
- *
12032
- * @example
12033
- * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
12034
- * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
12035
- * }
12036
- */
12037
- search: {},
12038
-
12039
-
12040
- /**
12041
- * Type based ordering.
12042
- *
12043
- * The column type tells DataTables what ordering to apply to the table
12044
- * when a column is sorted upon. The order for each type that is defined,
12045
- * is defined by the functions available in this object.
12046
- *
12047
- * Each ordering option can be described by three properties added to
12048
- * this object:
12049
- *
12050
- * * `{type}-pre` - Pre-formatting function
12051
- * * `{type}-asc` - Ascending order function
12052
- * * `{type}-desc` - Descending order function
12053
- *
12054
- * All three can be used together, only `{type}-pre` or only
12055
- * `{type}-asc` and `{type}-desc` together. It is generally recommended
12056
- * that only `{type}-pre` is used, as this provides the optimal
12057
- * implementation in terms of speed, although the others are provided
12058
- * for compatibility with existing Javascript sort functions.
12059
- *
12060
- * `{type}-pre`: Functions defined take a single parameter:
12061
- *
12062
- * 1. `{*}` Data from the column cell to be prepared for ordering
12063
- *
12064
- * And return:
12065
- *
12066
- * * `{*}` Data to be sorted upon
12067
- *
12068
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
12069
- * functions, taking two parameters:
12070
- *
12071
- * 1. `{*}` Data to compare to the second parameter
12072
- * 2. `{*}` Data to compare to the first parameter
12073
- *
12074
- * And returning:
12075
- *
12076
- * * `{*}` Ordering match: <0 if first parameter should be sorted lower
12077
- * than the second parameter, ===0 if the two parameters are equal and
12078
- * >0 if the first parameter should be sorted height than the second
12079
- * parameter.
12080
- *
12081
- * @type object
12082
- * @default {}
12083
- *
12084
- * @example
12085
- * // Numeric ordering of formatted numbers with a pre-formatter
12086
- * $.extend( $.fn.dataTable.ext.type.order, {
12087
- * "string-pre": function(x) {
12088
- * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
12089
- * return parseFloat( a );
12090
- * }
12091
- * } );
12092
- *
12093
- * @example
12094
- * // Case-sensitive string ordering, with no pre-formatting method
12095
- * $.extend( $.fn.dataTable.ext.order, {
12096
- * "string-case-asc": function(x,y) {
12097
- * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
12098
- * },
12099
- * "string-case-desc": function(x,y) {
12100
- * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
12101
- * }
12102
- * } );
12103
- */
12104
- order: {}
12105
- },
12106
-
12107
- /**
12108
- * Unique DataTables instance counter
12109
- *
12110
- * @type int
12111
- * @private
12112
- */
12113
- _unique: 0,
12114
-
12115
-
12116
- //
12117
- // Depreciated
12118
- // The following properties are retained for backwards compatibility only.
12119
- // The should not be used in new projects and will be removed in a future
12120
- // version
12121
- //
12122
-
12123
- /**
12124
- * Version check function.
12125
- * @type function
12126
- * @depreciated Since 1.10
12127
- */
12128
- fnVersionCheck: DataTable.fnVersionCheck,
12129
-
12130
-
12131
- /**
12132
- * Index for what 'this' index API functions should use
12133
- * @type int
12134
- * @deprecated Since v1.10
12135
- */
12136
- iApiIndex: 0,
12137
-
12138
-
12139
- /**
12140
- * Software version
12141
- * @type string
12142
- * @deprecated Since v1.10
12143
- */
12144
- sVersion: DataTable.version
12145
- };
12146
-
12147
-
12148
- //
12149
- // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
12150
- //
12151
- $.extend( _ext, {
12152
- afnFiltering: _ext.search,
12153
- aTypes: _ext.type.detect,
12154
- ofnSearch: _ext.type.search,
12155
- oSort: _ext.type.order,
12156
- afnSortData: _ext.order,
12157
- aoFeatures: _ext.feature,
12158
- oStdClasses: _ext.classes,
12159
- oPagination: _ext.pager
12160
- } );
12161
-
12162
-
12163
- $.extend( DataTable.ext.classes, {
12164
- container: 'dt-container',
12165
- empty: {
12166
- row: 'dt-empty'
12167
- },
12168
- info: {
12169
- container: 'dt-info'
12170
- },
12171
- length: {
12172
- container: 'dt-length',
12173
- select: 'dt-input'
12174
- },
12175
- order: {
12176
- canAsc: 'dt-orderable-asc',
12177
- canDesc: 'dt-orderable-desc',
12178
- isAsc: 'dt-ordering-asc',
12179
- isDesc: 'dt-ordering-desc',
12180
- none: 'dt-orderable-none',
12181
- position: 'sorting_'
12182
- },
12183
- processing: {
12184
- container: 'dt-processing'
12185
- },
12186
- scrolling: {
12187
- body: 'dt-scroll-body',
12188
- container: 'dt-scroll',
12189
- footer: {
12190
- self: 'dt-scroll-foot',
12191
- inner: 'dt-scroll-footInner'
12192
- },
12193
- header: {
12194
- self: 'dt-scroll-head',
12195
- inner: 'dt-scroll-headInner'
12196
- }
12197
- },
12198
- search: {
12199
- container: 'dt-search',
12200
- input: 'dt-input'
12201
- },
12202
- table: 'dataTable',
12203
- tbody: {
12204
- cell: '',
12205
- row: ''
12206
- },
12207
- thead: {
12208
- cell: '',
12209
- row: ''
12210
- },
12211
- tfoot: {
12212
- cell: '',
12213
- row: ''
12214
- },
12215
- paging: {
12216
- active: 'current',
12217
- button: 'dt-paging-button',
12218
- container: 'dt-paging',
12219
- disabled: 'disabled'
12220
- }
12221
- } );
12222
-
12223
-
12224
- var extPagination = DataTable.ext.pager;
12225
-
12226
- // Paging buttons configuration
12227
- $.extend( extPagination, {
12228
- simple: function () {
12229
- return [ 'previous', 'next' ];
12230
- },
12231
-
12232
- full: function () {
12233
- return [ 'first', 'previous', 'next', 'last' ];
12234
- },
12235
-
12236
- numbers: function () {
12237
- return [ 'numbers' ];
12238
- },
12239
-
12240
- simple_numbers: function () {
12241
- return [ 'previous', 'numbers', 'next' ];
12242
- },
12243
-
12244
- full_numbers: function () {
12245
- return [ 'first', 'previous', 'numbers', 'next', 'last' ];
12246
- },
12247
-
12248
- first_last: function () {
12249
- return ['first', 'last'];
12250
- },
12251
-
12252
- first_last_numbers: function () {
12253
- return ['first', 'numbers', 'last'];
12254
- },
12255
-
12256
- // For testing and plug-ins to use
12257
- _numbers: _pagingNumbers,
12258
-
12259
- // Number of number buttons - legacy, use `numbers` option for paging feature
12260
- numbers_length: 7
12261
- } );
12262
-
12263
-
12264
- $.extend( true, DataTable.ext.renderer, {
12265
- pagingButton: {
12266
- _: function (settings, buttonType, content, active, disabled) {
12267
- var classes = settings.oClasses.paging;
12268
- var btnClasses = [classes.button];
12269
- var btn;
12270
-
12271
- if (active) {
12272
- btnClasses.push(classes.active);
12273
- }
12274
-
12275
- if (disabled) {
12276
- btnClasses.push(classes.disabled)
12277
- }
12278
-
12279
- if (buttonType === 'ellipsis') {
12280
- btn = $('<span class="ellipsis"></span>').html(content)[0];
12281
- }
12282
- else {
12283
- btn = $('<button>', {
12284
- class: btnClasses.join(' '),
12285
- role: 'link',
12286
- type: 'button'
12287
- }).html(content);
12288
- }
12289
-
12290
- return {
12291
- display: btn,
12292
- clicker: btn
12293
- }
12294
- }
12295
- },
12296
-
12297
- pagingContainer: {
12298
- _: function (settings, buttons) {
12299
- // No wrapping element - just append directly to the host
12300
- return buttons;
12301
- }
12302
- }
12303
- } );
11763
+ pagingContainer: {
11764
+ _: function (settings, buttons) {
11765
+ // No wrapping element - just append directly to the host
11766
+ return buttons;
11767
+ }
11768
+ }
11769
+ } );
12304
11770
 
12305
11771
  // Common function to remove new lines, strip HTML and diacritic control
12306
11772
  var _filterString = function (stripHtml, normalize) {
@@ -12960,9 +12426,9 @@
12960
12426
  var ariaType = '';
12961
12427
  var indexes = columns.indexes();
12962
12428
  var sortDirs = columns.orderable(true).flatten();
12963
- var orderedColumns = sorting.map( function (val) {
12429
+ var orderedColumns = ',' + sorting.map( function (val) {
12964
12430
  return val.col;
12965
- } ).join(',');
12431
+ } ).join(',') + ',';
12966
12432
 
12967
12433
  cell
12968
12434
  .removeClass(
@@ -12973,7 +12439,7 @@
12973
12439
  .toggleClass( orderClasses.canAsc, orderable && sortDirs.includes('asc') )
12974
12440
  .toggleClass( orderClasses.canDesc, orderable && sortDirs.includes('desc') );
12975
12441
 
12976
- var sortIdx = orderedColumns.indexOf( indexes.toArray().join(',') );
12442
+ var sortIdx = orderedColumns.indexOf( ',' + indexes.toArray().join(',') + ',' );
12977
12443
 
12978
12444
  if ( sortIdx !== -1 ) {
12979
12445
  // Get the ordering direction for the columns under this cell
@@ -12988,7 +12454,7 @@
12988
12454
  }
12989
12455
 
12990
12456
  // The ARIA spec says that only one column should be marked with aria-sort
12991
- if ( sortIdx === 0 && orderedColumns.length === indexes.count() ) {
12457
+ if ( sortIdx === 0 ) {
12992
12458
  var firstSort = sorting[0];
12993
12459
  var sortOrder = col.asSorting;
12994
12460
 
@@ -13084,7 +12550,7 @@
13084
12550
  });
13085
12551
 
13086
12552
  // For the first info display in the table, we add a callback and aria information.
13087
- if (! $('#' + tid+'_info', settings.nWrapper).length) {
12553
+ if (! settings._infoEl) {
13088
12554
  n.attr({
13089
12555
  'aria-live': 'polite',
13090
12556
  id: tid+'_info',
@@ -13093,6 +12559,8 @@
13093
12559
 
13094
12560
  // Table is described by our info div
13095
12561
  $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
12562
+
12563
+ settings._infoEl = n;
13096
12564
  }
13097
12565
 
13098
12566
  return n;
@@ -13250,7 +12718,7 @@
13250
12718
 
13251
12719
  // opts
13252
12720
  // - type - button configuration
13253
- // - numbers - number of buttons to show - must be odd
12721
+ // - buttons - number of buttons to show - must be odd
13254
12722
  DataTable.feature.register( 'paging', function ( settings, opts ) {
13255
12723
  // Don't show the paging input if the table doesn't have paging enabled
13256
12724
  if (! settings.oFeatures.bPaginate) {
@@ -13258,9 +12726,15 @@
13258
12726
  }
13259
12727
 
13260
12728
  opts = $.extend({
13261
- numbers: DataTable.ext.pager.numbers_length,
13262
- type: settings.sPaginationType
13263
- }, opts)
12729
+ buttons: DataTable.ext.pager.numbers_length,
12730
+ type: settings.sPaginationType,
12731
+ boundaryNumbers: true
12732
+ }, opts);
12733
+
12734
+ // To be removed in 2.1
12735
+ if (opts.numbers) {
12736
+ opts.buttons = opts.numbers;
12737
+ }
13264
12738
 
13265
12739
  var host = $('<div/>').addClass( settings.oClasses.paging.container + ' paging_' + opts.type );
13266
12740
  var draw = function () {
@@ -13292,7 +12766,7 @@
13292
12766
  buttons = plugin()
13293
12767
  .map(function (val) {
13294
12768
  return val === 'numbers'
13295
- ? _pagingNumbers(page, pages, opts.numbers)
12769
+ ? _pagingNumbers(page, pages, opts.buttons, opts.boundaryNumbers)
13296
12770
  : val;
13297
12771
  })
13298
12772
  .flat();
@@ -13434,12 +12908,15 @@
13434
12908
  * @param {*} page Current page
13435
12909
  * @param {*} pages Total number of pages
13436
12910
  * @param {*} buttons Target number of number buttons
12911
+ * @param {boolean} addFirstLast Indicate if page 1 and end should be included
13437
12912
  * @returns Buttons to show
13438
12913
  */
13439
- function _pagingNumbers ( page, pages, buttons ) {
12914
+ function _pagingNumbers ( page, pages, buttons, addFirstLast ) {
13440
12915
  var
13441
12916
  numbers = [],
13442
- half = Math.floor(buttons / 2);
12917
+ half = Math.floor(buttons / 2),
12918
+ before = addFirstLast ? 2 : 1,
12919
+ after = addFirstLast ? 1 : 0;
13443
12920
 
13444
12921
  if ( pages <= buttons ) {
13445
12922
  numbers = _range(0, pages);
@@ -13462,17 +12939,30 @@
13462
12939
  }
13463
12940
  }
13464
12941
  else if ( page <= half ) {
13465
- numbers = _range(0, buttons-2);
13466
- numbers.push('ellipsis', pages-1);
12942
+ numbers = _range(0, buttons-before);
12943
+ numbers.push('ellipsis');
12944
+
12945
+ if (addFirstLast) {
12946
+ numbers.push(pages-1);
12947
+ }
13467
12948
  }
13468
12949
  else if ( page >= pages - 1 - half ) {
13469
- numbers = _range(pages-(buttons-2), pages);
13470
- numbers.unshift(0, 'ellipsis');
12950
+ numbers = _range(pages-(buttons-before), pages);
12951
+ numbers.unshift('ellipsis');
12952
+
12953
+ if (addFirstLast) {
12954
+ numbers.unshift(0);
12955
+ }
13471
12956
  }
13472
12957
  else {
13473
- numbers = _range(page-half+2, page+half-1);
13474
- numbers.push('ellipsis', pages-1);
13475
- numbers.unshift(0, 'ellipsis');
12958
+ numbers = _range(page-half+before, page+half-after);
12959
+ numbers.push('ellipsis');
12960
+ numbers.unshift('ellipsis');
12961
+
12962
+ if (addFirstLast) {
12963
+ numbers.push(pages-1);
12964
+ numbers.unshift(0);
12965
+ }
13476
12966
  }
13477
12967
 
13478
12968
  return numbers;