ucb_rails_user 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,24 +4,24 @@
4
4
  *
5
5
  * To rebuild or modify this file with the latest versions of the included
6
6
  * software please visit:
7
- * https://datatables.net/download/#bs/dt-1.10.16
7
+ * https://datatables.net/download/#bs4/dt-1.10.18/r-2.2.2
8
8
  *
9
9
  * Included libraries:
10
- * DataTables 1.10.16
10
+ * DataTables 1.10.18, Responsive 2.2.2
11
11
  */
12
12
 
13
- /*! DataTables 1.10.16
14
- * ©2008-2017 SpryMedia Ltd - datatables.net/license
13
+ /*! DataTables 1.10.18
14
+ * ©2008-2018 SpryMedia Ltd - datatables.net/license
15
15
  */
16
16
 
17
17
  /**
18
18
  * @summary DataTables
19
19
  * @description Paginate, search and order HTML tables
20
- * @version 1.10.16
20
+ * @version 1.10.18
21
21
  * @file jquery.dataTables.js
22
22
  * @author SpryMedia Ltd
23
23
  * @contact www.datatables.net
24
- * @copyright Copyright 2008-2017 SpryMedia Ltd.
24
+ * @copyright Copyright 2008-2018 SpryMedia Ltd.
25
25
  *
26
26
  * This source file is free software, available under the following license:
27
27
  * MIT license - http://datatables.net/license
@@ -921,8 +921,11 @@
921
921
  var s = allSettings[i];
922
922
 
923
923
  /* Base check on table node */
924
- if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
925
- {
924
+ if (
925
+ s.nTable == this ||
926
+ (s.nTHead && s.nTHead.parentNode == this) ||
927
+ (s.nTFoot && s.nTFoot.parentNode == this)
928
+ ) {
926
929
  var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
927
930
  var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
928
931
 
@@ -979,11 +982,7 @@
979
982
 
980
983
  // Backwards compatibility, before we apply all the defaults
981
984
  _fnCompatOpts( oInit );
982
-
983
- if ( oInit.oLanguage )
984
- {
985
- _fnLanguageCompat( oInit.oLanguage );
986
- }
985
+ _fnLanguageCompat( oInit.oLanguage );
987
986
 
988
987
  // If the length menu is given, but the init display length is not, use the length menu
989
988
  if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
@@ -1366,8 +1365,10 @@
1366
1365
  // - fr - Swiss Franc
1367
1366
  // - kr - Swedish krona, Norwegian krone and Danish krone
1368
1367
  // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1368
+ // - Ƀ - Bitcoin
1369
+ // - Ξ - Ethereum
1369
1370
  // standards as thousands separators.
1370
- var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
1371
+ var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
1371
1372
 
1372
1373
 
1373
1374
  var _empty = function ( d ) {
@@ -1742,33 +1743,43 @@
1742
1743
  */
1743
1744
  function _fnLanguageCompat( lang )
1744
1745
  {
1746
+ // Note the use of the Hungarian notation for the parameters in this method as
1747
+ // this is called after the mapping of camelCase to Hungarian
1745
1748
  var defaults = DataTable.defaults.oLanguage;
1746
- var zeroRecords = lang.sZeroRecords;
1747
1749
 
1748
- /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
1749
- * sZeroRecords - assuming that is given.
1750
- */
1751
- if ( ! lang.sEmptyTable && zeroRecords &&
1752
- defaults.sEmptyTable === "No data available in table" )
1753
- {
1754
- _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
1750
+ // Default mapping
1751
+ var defaultDecimal = defaults.sDecimal;
1752
+ if ( defaultDecimal ) {
1753
+ _addNumericSort( defaultDecimal );
1755
1754
  }
1756
1755
 
1757
- /* Likewise with loading records */
1758
- if ( ! lang.sLoadingRecords && zeroRecords &&
1759
- defaults.sLoadingRecords === "Loading..." )
1760
- {
1761
- _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
1762
- }
1756
+ if ( lang ) {
1757
+ var zeroRecords = lang.sZeroRecords;
1763
1758
 
1764
- // Old parameter name of the thousands separator mapped onto the new
1765
- if ( lang.sInfoThousands ) {
1766
- lang.sThousands = lang.sInfoThousands;
1767
- }
1759
+ // Backwards compatibility - if there is no sEmptyTable given, then use the same as
1760
+ // sZeroRecords - assuming that is given.
1761
+ if ( ! lang.sEmptyTable && zeroRecords &&
1762
+ defaults.sEmptyTable === "No data available in table" )
1763
+ {
1764
+ _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
1765
+ }
1766
+
1767
+ // Likewise with loading records
1768
+ if ( ! lang.sLoadingRecords && zeroRecords &&
1769
+ defaults.sLoadingRecords === "Loading..." )
1770
+ {
1771
+ _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
1772
+ }
1773
+
1774
+ // Old parameter name of the thousands separator mapped onto the new
1775
+ if ( lang.sInfoThousands ) {
1776
+ lang.sThousands = lang.sInfoThousands;
1777
+ }
1768
1778
 
1769
- var decimal = lang.sDecimal;
1770
- if ( decimal ) {
1771
- _addNumericSort( decimal );
1779
+ var decimal = lang.sDecimal;
1780
+ if ( decimal && defaultDecimal !== decimal ) {
1781
+ _addNumericSort( decimal );
1782
+ }
1772
1783
  }
1773
1784
  }
1774
1785
 
@@ -3140,7 +3151,7 @@
3140
3151
  }
3141
3152
  }
3142
3153
 
3143
- _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
3154
+ _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
3144
3155
  }
3145
3156
 
3146
3157
  // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
@@ -3465,7 +3476,7 @@
3465
3476
  // iRowCount and j are not currently documented. Are they at all
3466
3477
  // useful?
3467
3478
  _fnCallbackFire( oSettings, 'aoRowCallback', null,
3468
- [nRow, aoData._aData, iRowCount, j] );
3479
+ [nRow, aoData._aData, iRowCount, j, iDataIndex] );
3469
3480
 
3470
3481
  anRows.push( nRow );
3471
3482
  iRowCount++;
@@ -3869,12 +3880,12 @@
3869
3880
  {
3870
3881
  ajaxData = ajax.data;
3871
3882
 
3872
- var newData = $.isFunction( ajaxData ) ?
3883
+ var newData = typeof ajaxData === 'function' ?
3873
3884
  ajaxData( data, oSettings ) : // fn can manipulate data or return
3874
3885
  ajaxData; // an object object or array to merge
3875
3886
 
3876
3887
  // If the function returned something, use that alone
3877
- data = $.isFunction( ajaxData ) && newData ?
3888
+ data = typeof ajaxData === 'function' && newData ?
3878
3889
  newData :
3879
3890
  $.extend( true, data, newData );
3880
3891
 
@@ -3938,7 +3949,7 @@
3938
3949
  url: ajax || oSettings.sAjaxSource
3939
3950
  } ) );
3940
3951
  }
3941
- else if ( $.isFunction( ajax ) )
3952
+ else if ( typeof ajax === 'function' )
3942
3953
  {
3943
3954
  // Is a function - let the caller define what needs to be done
3944
3955
  oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
@@ -5372,14 +5383,18 @@
5372
5383
  // both match, but we want to hide it completely. We want to also fix their
5373
5384
  // width to what they currently are
5374
5385
  _fnApplyToChildren( function(nSizer, i) {
5375
- nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
5386
+ nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
5387
+ nSizer.childNodes[0].style.height = "0";
5388
+ nSizer.childNodes[0].style.overflow = "hidden";
5376
5389
  nSizer.style.width = headerWidths[i];
5377
5390
  }, headerSrcEls );
5378
5391
 
5379
5392
  if ( footer )
5380
5393
  {
5381
5394
  _fnApplyToChildren( function(nSizer, i) {
5382
- nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
5395
+ nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
5396
+ nSizer.childNodes[0].style.height = "0";
5397
+ nSizer.childNodes[0].style.overflow = "hidden";
5383
5398
  nSizer.style.width = footerWidths[i];
5384
5399
  }, footerSrcEls );
5385
5400
  }
@@ -6573,7 +6588,7 @@
6573
6588
  {
6574
6589
  $(n)
6575
6590
  .on( 'click.DT', oData, function (e) {
6576
- n.blur(); // Remove focus outline for mouse users
6591
+ $(n).blur(); // Remove focus outline for mouse users
6577
6592
  fn(e);
6578
6593
  } )
6579
6594
  .on( 'keypress.DT', oData, function (e){
@@ -7813,13 +7828,26 @@
7813
7828
  }
7814
7829
  }
7815
7830
  else if ( order == 'current' || order == 'applied' ) {
7816
- a = search == 'none' ?
7817
- displayMaster.slice() : // no search
7818
- search == 'applied' ?
7819
- displayFiltered.slice() : // applied search
7820
- $.map( displayMaster, function (el, i) { // removed search
7821
- return $.inArray( el, displayFiltered ) === -1 ? el : null;
7822
- } );
7831
+ if ( search == 'none') {
7832
+ a = displayMaster.slice();
7833
+ }
7834
+ else if ( search == 'applied' ) {
7835
+ a = displayFiltered.slice();
7836
+ }
7837
+ else if ( search == 'removed' ) {
7838
+ // O(n+m) solution by creating a hash map
7839
+ var displayFilteredMap = {};
7840
+
7841
+ for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
7842
+ displayFilteredMap[displayFiltered[i]] = null;
7843
+ }
7844
+
7845
+ a = $.map( displayMaster, function (el) {
7846
+ return ! displayFilteredMap.hasOwnProperty(el) ?
7847
+ el :
7848
+ null;
7849
+ } );
7850
+ }
7823
7851
  }
7824
7852
  else if ( order == 'index' || order == 'original' ) {
7825
7853
  for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
@@ -7852,14 +7880,13 @@
7852
7880
  * {array} - jQuery array of nodes, or simply an array of TR nodes
7853
7881
  *
7854
7882
  */
7855
-
7856
-
7857
7883
  var __row_selector = function ( settings, selector, opts )
7858
7884
  {
7859
7885
  var rows;
7860
7886
  var run = function ( sel ) {
7861
7887
  var selInt = _intVal( sel );
7862
7888
  var i, ien;
7889
+ var aoData = settings.aoData;
7863
7890
 
7864
7891
  // Short cut - selector is a number and no options provided (default is
7865
7892
  // all records, so no need to check if the index is in there, since it
@@ -7884,23 +7911,26 @@
7884
7911
  // Selector - function
7885
7912
  if ( typeof sel === 'function' ) {
7886
7913
  return $.map( rows, function (idx) {
7887
- var row = settings.aoData[ idx ];
7914
+ var row = aoData[ idx ];
7888
7915
  return sel( idx, row._aData, row.nTr ) ? idx : null;
7889
7916
  } );
7890
7917
  }
7891
7918
 
7892
- // Get nodes in the order from the `rows` array with null values removed
7893
- var nodes = _removeEmpty(
7894
- _pluck_order( settings.aoData, rows, 'nTr' )
7895
- );
7896
-
7897
7919
  // Selector - node
7898
7920
  if ( sel.nodeName ) {
7899
- if ( sel._DT_RowIndex !== undefined ) {
7900
- return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
7921
+ var rowIdx = sel._DT_RowIndex; // Property added by DT for fast lookup
7922
+ var cellIdx = sel._DT_CellIndex;
7923
+
7924
+ if ( rowIdx !== undefined ) {
7925
+ // Make sure that the row is actually still present in the table
7926
+ return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
7927
+ [ rowIdx ] :
7928
+ [];
7901
7929
  }
7902
- else if ( sel._DT_CellIndex ) {
7903
- return [ sel._DT_CellIndex.row ];
7930
+ else if ( cellIdx ) {
7931
+ return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel ?
7932
+ [ cellIdx.row ] :
7933
+ [];
7904
7934
  }
7905
7935
  else {
7906
7936
  var host = $(sel).closest('*[data-dt-row]');
@@ -7929,6 +7959,11 @@
7929
7959
  // need to fall through to jQuery in case there is DOM id that
7930
7960
  // matches
7931
7961
  }
7962
+
7963
+ // Get nodes in the order from the `rows` array with null values removed
7964
+ var nodes = _removeEmpty(
7965
+ _pluck_order( settings.aoData, rows, 'nTr' )
7966
+ );
7932
7967
 
7933
7968
  // Selector - jQuery selector string, array of nodes or jQuery object/
7934
7969
  // As jQuery's .filter() allows jQuery objects to be passed in filter,
@@ -8123,7 +8158,13 @@
8123
8158
  }
8124
8159
 
8125
8160
  // Set
8126
- ctx[0].aoData[ this[0] ]._aData = data;
8161
+ var row = ctx[0].aoData[ this[0] ];
8162
+ row._aData = data;
8163
+
8164
+ // If the DOM has an id, and the data source is an array
8165
+ if ( $.isArray( data ) && row.nTr.id ) {
8166
+ _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
8167
+ }
8127
8168
 
8128
8169
  // Automatically invalidate
8129
8170
  _fnInvalidate( ctx[0], this[0], 'data' );
@@ -8549,6 +8590,12 @@
8549
8590
  _fnDrawHead( settings, settings.aoHeader );
8550
8591
  _fnDrawHead( settings, settings.aoFooter );
8551
8592
 
8593
+ // Update colspan for no records display. Child rows and extensions will use their own
8594
+ // listeners to do this - only need to update the empty table item here
8595
+ if ( ! settings.aiDisplay.length ) {
8596
+ $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
8597
+ }
8598
+
8552
8599
  _fnSaveState( settings );
8553
8600
  };
8554
8601
 
@@ -8714,7 +8761,10 @@
8714
8761
 
8715
8762
  // Selector - index
8716
8763
  if ( $.isPlainObject( s ) ) {
8717
- return [s];
8764
+ // Valid cell index and its in the array of selectable rows
8765
+ return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
8766
+ [s] :
8767
+ [];
8718
8768
  }
8719
8769
 
8720
8770
  // Selector - jQuery filtered cells
@@ -8778,11 +8828,11 @@
8778
8828
  }
8779
8829
 
8780
8830
  // Row + column selector
8781
- var columns = this.columns( columnSelector, opts );
8782
- var rows = this.rows( rowSelector, opts );
8831
+ var columns = this.columns( columnSelector );
8832
+ var rows = this.rows( rowSelector );
8783
8833
  var a, i, ien, j, jen;
8784
8834
 
8785
- var cells = this.iterator( 'table', function ( settings, idx ) {
8835
+ this.iterator( 'table', function ( settings, idx ) {
8786
8836
  a = [];
8787
8837
 
8788
8838
  for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
@@ -8793,10 +8843,11 @@
8793
8843
  } );
8794
8844
  }
8795
8845
  }
8796
-
8797
- return a;
8798
8846
  }, 1 );
8799
8847
 
8848
+ // Now pass through the cell selector for options
8849
+ var cells = this.cells( a, opts );
8850
+
8800
8851
  $.extend( cells.selector, {
8801
8852
  cols: columnSelector,
8802
8853
  rows: rowSelector,
@@ -9425,7 +9476,7 @@
9425
9476
  * @type string
9426
9477
  * @default Version number
9427
9478
  */
9428
- DataTable.version = "1.10.16";
9479
+ DataTable.version = "1.10.18";
9429
9480
 
9430
9481
  /**
9431
9482
  * Private data store, containing all of the settings objects that are
@@ -12363,8 +12414,8 @@
12363
12414
  * { "data": "engine" },
12364
12415
  * { "data": "browser" },
12365
12416
  * { "data": "platform.inner" },
12366
- * { "data": "platform.details.0" },
12367
- * { "data": "platform.details.1" }
12417
+ * { "data": "details.0" },
12418
+ * { "data": "details.1" }
12368
12419
  * ]
12369
12420
  * } );
12370
12421
  * } );
@@ -13847,7 +13898,7 @@
13847
13898
  *
13848
13899
  * @type string
13849
13900
  */
13850
- build:"bs/dt-1.10.16",
13901
+ build:"bs4/dt-1.10.18/r-2.2.2",
13851
13902
 
13852
13903
 
13853
13904
  /**
@@ -14161,7 +14212,7 @@
14161
14212
  * $.fn.dataTable.ext.type.detect.push(
14162
14213
  * function ( data, settings ) {
14163
14214
  * // Check the numeric part
14164
- * if ( ! $.isNumeric( data.substring(1) ) ) {
14215
+ * if ( ! data.substring(1).match(/[0-9]/) ) {
14165
14216
  * return null;
14166
14217
  * }
14167
14218
  *
@@ -14744,7 +14795,8 @@
14744
14795
  $.extend( _ext.type.order, {
14745
14796
  // Dates
14746
14797
  "date-pre": function ( d ) {
14747
- return Date.parse( d ) || -Infinity;
14798
+ var ts = Date.parse( d );
14799
+ return isNaN(ts) ? -Infinity : ts;
14748
14800
  },
14749
14801
 
14750
14802
  // html
@@ -15060,6 +15112,7 @@
15060
15112
  _fnRenderer: _fnRenderer,
15061
15113
  _fnDataSource: _fnDataSource,
15062
15114
  _fnRowAttributes: _fnRowAttributes,
15115
+ _fnExtend: _fnExtend,
15063
15116
  _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
15064
15117
  // in 1.10, so this dead-end function is
15065
15118
  // added to prevent errors
@@ -15255,12 +15308,12 @@
15255
15308
  }));
15256
15309
 
15257
15310
 
15258
- /*! DataTables Bootstrap 3 integration
15259
- * ©2011-2015 SpryMedia Ltd - datatables.net/license
15311
+ /*! DataTables Bootstrap 4 integration
15312
+ * ©2011-2017 SpryMedia Ltd - datatables.net/license
15260
15313
  */
15261
15314
 
15262
15315
  /**
15263
- * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
15316
+ * DataTables integration for Bootstrap 4. This requires Bootstrap 4 and
15264
15317
  * DataTables 1.10 or newer.
15265
15318
  *
15266
15319
  * This file sets the defaults and adds options to DataTables to style its
@@ -15303,19 +15356,20 @@ var DataTable = $.fn.dataTable;
15303
15356
  /* Set the defaults for DataTables initialisation */
15304
15357
  $.extend( true, DataTable.defaults, {
15305
15358
  dom:
15306
- "<'row'<'col-sm-6'l><'col-sm-6'f>>" +
15359
+ "<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
15307
15360
  "<'row'<'col-sm-12'tr>>" +
15308
- "<'row'<'col-sm-5'i><'col-sm-7'p>>",
15361
+ "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
15309
15362
  renderer: 'bootstrap'
15310
15363
  } );
15311
15364
 
15312
15365
 
15313
15366
  /* Default class modification */
15314
15367
  $.extend( DataTable.ext.classes, {
15315
- sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
15316
- sFilterInput: "form-control input-sm",
15317
- sLengthSelect: "form-control input-sm",
15318
- sProcessing: "dataTables_processing panel panel-default"
15368
+ sWrapper: "dataTables_wrapper dt-bootstrap4",
15369
+ sFilterInput: "form-control form-control-sm",
15370
+ sLengthSelect: "custom-select custom-select-sm form-control form-control-sm",
15371
+ sProcessing: "dataTables_processing card",
15372
+ sPageButton: "paginate_button page-item"
15319
15373
  } );
15320
15374
 
15321
15375
 
@@ -15395,7 +15449,8 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
15395
15449
  'aria-controls': settings.sTableId,
15396
15450
  'aria-label': aria[ button ],
15397
15451
  'data-dt-idx': counter,
15398
- 'tabindex': settings.iTabIndex
15452
+ 'tabindex': settings.iTabIndex,
15453
+ 'class': 'page-link'
15399
15454
  } )
15400
15455
  .html( btnDisplay )
15401
15456
  )
@@ -15439,3 +15494,1398 @@ return DataTable;
15439
15494
  }));
15440
15495
 
15441
15496
 
15497
+ /*! Responsive 2.2.2
15498
+ * 2014-2018 SpryMedia Ltd - datatables.net/license
15499
+ */
15500
+
15501
+ /**
15502
+ * @summary Responsive
15503
+ * @description Responsive tables plug-in for DataTables
15504
+ * @version 2.2.2
15505
+ * @file dataTables.responsive.js
15506
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
15507
+ * @contact www.sprymedia.co.uk/contact
15508
+ * @copyright Copyright 2014-2018 SpryMedia Ltd.
15509
+ *
15510
+ * This source file is free software, available under the following license:
15511
+ * MIT license - http://datatables.net/license/mit
15512
+ *
15513
+ * This source file is distributed in the hope that it will be useful, but
15514
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15515
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
15516
+ *
15517
+ * For details please refer to: http://www.datatables.net
15518
+ */
15519
+ (function( factory ){
15520
+ if ( typeof define === 'function' && define.amd ) {
15521
+ // AMD
15522
+ define( ['jquery', 'datatables.net'], function ( $ ) {
15523
+ return factory( $, window, document );
15524
+ } );
15525
+ }
15526
+ else if ( typeof exports === 'object' ) {
15527
+ // CommonJS
15528
+ module.exports = function (root, $) {
15529
+ if ( ! root ) {
15530
+ root = window;
15531
+ }
15532
+
15533
+ if ( ! $ || ! $.fn.dataTable ) {
15534
+ $ = require('datatables.net')(root, $).$;
15535
+ }
15536
+
15537
+ return factory( $, root, root.document );
15538
+ };
15539
+ }
15540
+ else {
15541
+ // Browser
15542
+ factory( jQuery, window, document );
15543
+ }
15544
+ }(function( $, window, document, undefined ) {
15545
+ 'use strict';
15546
+ var DataTable = $.fn.dataTable;
15547
+
15548
+
15549
+ /**
15550
+ * Responsive is a plug-in for the DataTables library that makes use of
15551
+ * DataTables' ability to change the visibility of columns, changing the
15552
+ * visibility of columns so the displayed columns fit into the table container.
15553
+ * The end result is that complex tables will be dynamically adjusted to fit
15554
+ * into the viewport, be it on a desktop, tablet or mobile browser.
15555
+ *
15556
+ * Responsive for DataTables has two modes of operation, which can used
15557
+ * individually or combined:
15558
+ *
15559
+ * * Class name based control - columns assigned class names that match the
15560
+ * breakpoint logic can be shown / hidden as required for each breakpoint.
15561
+ * * Automatic control - columns are automatically hidden when there is no
15562
+ * room left to display them. Columns removed from the right.
15563
+ *
15564
+ * In additional to column visibility control, Responsive also has built into
15565
+ * options to use DataTables' child row display to show / hide the information
15566
+ * from the table that has been hidden. There are also two modes of operation
15567
+ * for this child row display:
15568
+ *
15569
+ * * Inline - when the control element that the user can use to show / hide
15570
+ * child rows is displayed inside the first column of the table.
15571
+ * * Column - where a whole column is dedicated to be the show / hide control.
15572
+ *
15573
+ * Initialisation of Responsive is performed by:
15574
+ *
15575
+ * * Adding the class `responsive` or `dt-responsive` to the table. In this case
15576
+ * Responsive will automatically be initialised with the default configuration
15577
+ * options when the DataTable is created.
15578
+ * * Using the `responsive` option in the DataTables configuration options. This
15579
+ * can also be used to specify the configuration options, or simply set to
15580
+ * `true` to use the defaults.
15581
+ *
15582
+ * @class
15583
+ * @param {object} settings DataTables settings object for the host table
15584
+ * @param {object} [opts] Configuration options
15585
+ * @requires jQuery 1.7+
15586
+ * @requires DataTables 1.10.3+
15587
+ *
15588
+ * @example
15589
+ * $('#example').DataTable( {
15590
+ * responsive: true
15591
+ * } );
15592
+ * } );
15593
+ */
15594
+ var Responsive = function ( settings, opts ) {
15595
+ // Sanity check that we are using DataTables 1.10 or newer
15596
+ if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.10' ) ) {
15597
+ throw 'DataTables Responsive requires DataTables 1.10.10 or newer';
15598
+ }
15599
+
15600
+ this.s = {
15601
+ dt: new DataTable.Api( settings ),
15602
+ columns: [],
15603
+ current: []
15604
+ };
15605
+
15606
+ // Check if responsive has already been initialised on this table
15607
+ if ( this.s.dt.settings()[0].responsive ) {
15608
+ return;
15609
+ }
15610
+
15611
+ // details is an object, but for simplicity the user can give it as a string
15612
+ // or a boolean
15613
+ if ( opts && typeof opts.details === 'string' ) {
15614
+ opts.details = { type: opts.details };
15615
+ }
15616
+ else if ( opts && opts.details === false ) {
15617
+ opts.details = { type: false };
15618
+ }
15619
+ else if ( opts && opts.details === true ) {
15620
+ opts.details = { type: 'inline' };
15621
+ }
15622
+
15623
+ this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
15624
+ settings.responsive = this;
15625
+ this._constructor();
15626
+ };
15627
+
15628
+ $.extend( Responsive.prototype, {
15629
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15630
+ * Constructor
15631
+ */
15632
+
15633
+ /**
15634
+ * Initialise the Responsive instance
15635
+ *
15636
+ * @private
15637
+ */
15638
+ _constructor: function ()
15639
+ {
15640
+ var that = this;
15641
+ var dt = this.s.dt;
15642
+ var dtPrivateSettings = dt.settings()[0];
15643
+ var oldWindowWidth = $(window).width();
15644
+
15645
+ dt.settings()[0]._responsive = this;
15646
+
15647
+ // Use DataTables' throttle function to avoid processor thrashing on
15648
+ // resize
15649
+ $(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
15650
+ // iOS has a bug whereby resize can fire when only scrolling
15651
+ // See: http://stackoverflow.com/questions/8898412
15652
+ var width = $(window).width();
15653
+
15654
+ if ( width !== oldWindowWidth ) {
15655
+ that._resize();
15656
+ oldWindowWidth = width;
15657
+ }
15658
+ } ) );
15659
+
15660
+ // DataTables doesn't currently trigger an event when a row is added, so
15661
+ // we need to hook into its private API to enforce the hidden rows when
15662
+ // new data is added
15663
+ dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
15664
+ if ( $.inArray( false, that.s.current ) !== -1 ) {
15665
+ $('>td, >th', tr).each( function ( i ) {
15666
+ var idx = dt.column.index( 'toData', i );
15667
+
15668
+ if ( that.s.current[idx] === false ) {
15669
+ $(this).css('display', 'none');
15670
+ }
15671
+ } );
15672
+ }
15673
+ } );
15674
+
15675
+ // Destroy event handler
15676
+ dt.on( 'destroy.dtr', function () {
15677
+ dt.off( '.dtr' );
15678
+ $( dt.table().body() ).off( '.dtr' );
15679
+ $(window).off( 'resize.dtr orientationchange.dtr' );
15680
+
15681
+ // Restore the columns that we've hidden
15682
+ $.each( that.s.current, function ( i, val ) {
15683
+ if ( val === false ) {
15684
+ that._setColumnVis( i, true );
15685
+ }
15686
+ } );
15687
+ } );
15688
+
15689
+ // Reorder the breakpoints array here in case they have been added out
15690
+ // of order
15691
+ this.c.breakpoints.sort( function (a, b) {
15692
+ return a.width < b.width ? 1 :
15693
+ a.width > b.width ? -1 : 0;
15694
+ } );
15695
+
15696
+ this._classLogic();
15697
+ this._resizeAuto();
15698
+
15699
+ // Details handler
15700
+ var details = this.c.details;
15701
+
15702
+ if ( details.type !== false ) {
15703
+ that._detailsInit();
15704
+
15705
+ // DataTables will trigger this event on every column it shows and
15706
+ // hides individually
15707
+ dt.on( 'column-visibility.dtr', function () {
15708
+ // Use a small debounce to allow multiple columns to be set together
15709
+ if ( that._timer ) {
15710
+ clearTimeout( that._timer );
15711
+ }
15712
+
15713
+ that._timer = setTimeout( function () {
15714
+ that._timer = null;
15715
+
15716
+ that._classLogic();
15717
+ that._resizeAuto();
15718
+ that._resize();
15719
+
15720
+ that._redrawChildren();
15721
+ }, 100 );
15722
+ } );
15723
+
15724
+ // Redraw the details box on each draw which will happen if the data
15725
+ // has changed. This is used until DataTables implements a native
15726
+ // `updated` event for rows
15727
+ dt.on( 'draw.dtr', function () {
15728
+ that._redrawChildren();
15729
+ } );
15730
+
15731
+ $(dt.table().node()).addClass( 'dtr-'+details.type );
15732
+ }
15733
+
15734
+ dt.on( 'column-reorder.dtr', function (e, settings, details) {
15735
+ that._classLogic();
15736
+ that._resizeAuto();
15737
+ that._resize();
15738
+ } );
15739
+
15740
+ // Change in column sizes means we need to calc
15741
+ dt.on( 'column-sizing.dtr', function () {
15742
+ that._resizeAuto();
15743
+ that._resize();
15744
+ });
15745
+
15746
+ // On Ajax reload we want to reopen any child rows which are displayed
15747
+ // by responsive
15748
+ dt.on( 'preXhr.dtr', function () {
15749
+ var rowIds = [];
15750
+ dt.rows().every( function () {
15751
+ if ( this.child.isShown() ) {
15752
+ rowIds.push( this.id(true) );
15753
+ }
15754
+ } );
15755
+
15756
+ dt.one( 'draw.dtr', function () {
15757
+ that._resizeAuto();
15758
+ that._resize();
15759
+
15760
+ dt.rows( rowIds ).every( function () {
15761
+ that._detailsDisplay( this, false );
15762
+ } );
15763
+ } );
15764
+ });
15765
+
15766
+ dt.on( 'init.dtr', function (e, settings, details) {
15767
+ that._resizeAuto();
15768
+ that._resize();
15769
+
15770
+ // If columns were hidden, then DataTables needs to adjust the
15771
+ // column sizing
15772
+ if ( $.inArray( false, that.s.current ) ) {
15773
+ dt.columns.adjust();
15774
+ }
15775
+ } );
15776
+
15777
+ // First pass - draw the table for the current viewport size
15778
+ this._resize();
15779
+ },
15780
+
15781
+
15782
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15783
+ * Private methods
15784
+ */
15785
+
15786
+ /**
15787
+ * Calculate the visibility for the columns in a table for a given
15788
+ * breakpoint. The result is pre-determined based on the class logic if
15789
+ * class names are used to control all columns, but the width of the table
15790
+ * is also used if there are columns which are to be automatically shown
15791
+ * and hidden.
15792
+ *
15793
+ * @param {string} breakpoint Breakpoint name to use for the calculation
15794
+ * @return {array} Array of boolean values initiating the visibility of each
15795
+ * column.
15796
+ * @private
15797
+ */
15798
+ _columnsVisiblity: function ( breakpoint )
15799
+ {
15800
+ var dt = this.s.dt;
15801
+ var columns = this.s.columns;
15802
+ var i, ien;
15803
+
15804
+ // Create an array that defines the column ordering based first on the
15805
+ // column's priority, and secondly the column index. This allows the
15806
+ // columns to be removed from the right if the priority matches
15807
+ var order = columns
15808
+ .map( function ( col, idx ) {
15809
+ return {
15810
+ columnIdx: idx,
15811
+ priority: col.priority
15812
+ };
15813
+ } )
15814
+ .sort( function ( a, b ) {
15815
+ if ( a.priority !== b.priority ) {
15816
+ return a.priority - b.priority;
15817
+ }
15818
+ return a.columnIdx - b.columnIdx;
15819
+ } );
15820
+
15821
+ // Class logic - determine which columns are in this breakpoint based
15822
+ // on the classes. If no class control (i.e. `auto`) then `-` is used
15823
+ // to indicate this to the rest of the function
15824
+ var display = $.map( columns, function ( col, i ) {
15825
+ if ( dt.column(i).visible() === false ) {
15826
+ return 'not-visible';
15827
+ }
15828
+ return col.auto && col.minWidth === null ?
15829
+ false :
15830
+ col.auto === true ?
15831
+ '-' :
15832
+ $.inArray( breakpoint, col.includeIn ) !== -1;
15833
+ } );
15834
+
15835
+ // Auto column control - first pass: how much width is taken by the
15836
+ // ones that must be included from the non-auto columns
15837
+ var requiredWidth = 0;
15838
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
15839
+ if ( display[i] === true ) {
15840
+ requiredWidth += columns[i].minWidth;
15841
+ }
15842
+ }
15843
+
15844
+ // Second pass, use up any remaining width for other columns. For
15845
+ // scrolling tables we need to subtract the width of the scrollbar. It
15846
+ // may not be requires which makes this sub-optimal, but it would
15847
+ // require another full redraw to make complete use of those extra few
15848
+ // pixels
15849
+ var scrolling = dt.settings()[0].oScroll;
15850
+ var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
15851
+ var widthAvailable = dt.table().container().offsetWidth - bar;
15852
+ var usedWidth = widthAvailable - requiredWidth;
15853
+
15854
+ // Control column needs to always be included. This makes it sub-
15855
+ // optimal in terms of using the available with, but to stop layout
15856
+ // thrashing or overflow. Also we need to account for the control column
15857
+ // width first so we know how much width is available for the other
15858
+ // columns, since the control column might not be the first one shown
15859
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
15860
+ if ( columns[i].control ) {
15861
+ usedWidth -= columns[i].minWidth;
15862
+ }
15863
+ }
15864
+
15865
+ // Allow columns to be shown (counting by priority and then right to
15866
+ // left) until we run out of room
15867
+ var empty = false;
15868
+ for ( i=0, ien=order.length ; i<ien ; i++ ) {
15869
+ var colIdx = order[i].columnIdx;
15870
+
15871
+ if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
15872
+ // Once we've found a column that won't fit we don't let any
15873
+ // others display either, or columns might disappear in the
15874
+ // middle of the table
15875
+ if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
15876
+ empty = true;
15877
+ display[colIdx] = false;
15878
+ }
15879
+ else {
15880
+ display[colIdx] = true;
15881
+ }
15882
+
15883
+ usedWidth -= columns[colIdx].minWidth;
15884
+ }
15885
+ }
15886
+
15887
+ // Determine if the 'control' column should be shown (if there is one).
15888
+ // This is the case when there is a hidden column (that is not the
15889
+ // control column). The two loops look inefficient here, but they are
15890
+ // trivial and will fly through. We need to know the outcome from the
15891
+ // first , before the action in the second can be taken
15892
+ var showControl = false;
15893
+
15894
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
15895
+ if ( ! columns[i].control && ! columns[i].never && display[i] === false ) {
15896
+ showControl = true;
15897
+ break;
15898
+ }
15899
+ }
15900
+
15901
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
15902
+ if ( columns[i].control ) {
15903
+ display[i] = showControl;
15904
+ }
15905
+
15906
+ // Replace not visible string with false from the control column detection above
15907
+ if ( display[i] === 'not-visible' ) {
15908
+ display[i] = false;
15909
+ }
15910
+ }
15911
+
15912
+ // Finally we need to make sure that there is at least one column that
15913
+ // is visible
15914
+ if ( $.inArray( true, display ) === -1 ) {
15915
+ display[0] = true;
15916
+ }
15917
+
15918
+ return display;
15919
+ },
15920
+
15921
+
15922
+ /**
15923
+ * Create the internal `columns` array with information about the columns
15924
+ * for the table. This includes determining which breakpoints the column
15925
+ * will appear in, based upon class names in the column, which makes up the
15926
+ * vast majority of this method.
15927
+ *
15928
+ * @private
15929
+ */
15930
+ _classLogic: function ()
15931
+ {
15932
+ var that = this;
15933
+ var calc = {};
15934
+ var breakpoints = this.c.breakpoints;
15935
+ var dt = this.s.dt;
15936
+ var columns = dt.columns().eq(0).map( function (i) {
15937
+ var column = this.column(i);
15938
+ var className = column.header().className;
15939
+ var priority = dt.settings()[0].aoColumns[i].responsivePriority;
15940
+
15941
+ if ( priority === undefined ) {
15942
+ var dataPriority = $(column.header()).data('priority');
15943
+
15944
+ priority = dataPriority !== undefined ?
15945
+ dataPriority * 1 :
15946
+ 10000;
15947
+ }
15948
+
15949
+ return {
15950
+ className: className,
15951
+ includeIn: [],
15952
+ auto: false,
15953
+ control: false,
15954
+ never: className.match(/\bnever\b/) ? true : false,
15955
+ priority: priority
15956
+ };
15957
+ } );
15958
+
15959
+ // Simply add a breakpoint to `includeIn` array, ensuring that there are
15960
+ // no duplicates
15961
+ var add = function ( colIdx, name ) {
15962
+ var includeIn = columns[ colIdx ].includeIn;
15963
+
15964
+ if ( $.inArray( name, includeIn ) === -1 ) {
15965
+ includeIn.push( name );
15966
+ }
15967
+ };
15968
+
15969
+ var column = function ( colIdx, name, operator, matched ) {
15970
+ var size, i, ien;
15971
+
15972
+ if ( ! operator ) {
15973
+ columns[ colIdx ].includeIn.push( name );
15974
+ }
15975
+ else if ( operator === 'max-' ) {
15976
+ // Add this breakpoint and all smaller
15977
+ size = that._find( name ).width;
15978
+
15979
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
15980
+ if ( breakpoints[i].width <= size ) {
15981
+ add( colIdx, breakpoints[i].name );
15982
+ }
15983
+ }
15984
+ }
15985
+ else if ( operator === 'min-' ) {
15986
+ // Add this breakpoint and all larger
15987
+ size = that._find( name ).width;
15988
+
15989
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
15990
+ if ( breakpoints[i].width >= size ) {
15991
+ add( colIdx, breakpoints[i].name );
15992
+ }
15993
+ }
15994
+ }
15995
+ else if ( operator === 'not-' ) {
15996
+ // Add all but this breakpoint
15997
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
15998
+ if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
15999
+ add( colIdx, breakpoints[i].name );
16000
+ }
16001
+ }
16002
+ }
16003
+ };
16004
+
16005
+ // Loop over each column and determine if it has a responsive control
16006
+ // class
16007
+ columns.each( function ( col, i ) {
16008
+ var classNames = col.className.split(' ');
16009
+ var hasClass = false;
16010
+
16011
+ // Split the class name up so multiple rules can be applied if needed
16012
+ for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
16013
+ var className = $.trim( classNames[k] );
16014
+
16015
+ if ( className === 'all' ) {
16016
+ // Include in all
16017
+ hasClass = true;
16018
+ col.includeIn = $.map( breakpoints, function (a) {
16019
+ return a.name;
16020
+ } );
16021
+ return;
16022
+ }
16023
+ else if ( className === 'none' || col.never ) {
16024
+ // Include in none (default) and no auto
16025
+ hasClass = true;
16026
+ return;
16027
+ }
16028
+ else if ( className === 'control' ) {
16029
+ // Special column that is only visible, when one of the other
16030
+ // columns is hidden. This is used for the details control
16031
+ hasClass = true;
16032
+ col.control = true;
16033
+ return;
16034
+ }
16035
+
16036
+ $.each( breakpoints, function ( j, breakpoint ) {
16037
+ // Does this column have a class that matches this breakpoint?
16038
+ var brokenPoint = breakpoint.name.split('-');
16039
+ var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
16040
+ var match = className.match( re );
16041
+
16042
+ if ( match ) {
16043
+ hasClass = true;
16044
+
16045
+ if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
16046
+ // Class name matches breakpoint name fully
16047
+ column( i, breakpoint.name, match[1], match[2]+match[3] );
16048
+ }
16049
+ else if ( match[2] === brokenPoint[0] && ! match[3] ) {
16050
+ // Class name matched primary breakpoint name with no qualifier
16051
+ column( i, breakpoint.name, match[1], match[2] );
16052
+ }
16053
+ }
16054
+ } );
16055
+ }
16056
+
16057
+ // If there was no control class, then automatic sizing is used
16058
+ if ( ! hasClass ) {
16059
+ col.auto = true;
16060
+ }
16061
+ } );
16062
+
16063
+ this.s.columns = columns;
16064
+ },
16065
+
16066
+
16067
+ /**
16068
+ * Show the details for the child row
16069
+ *
16070
+ * @param {DataTables.Api} row API instance for the row
16071
+ * @param {boolean} update Update flag
16072
+ * @private
16073
+ */
16074
+ _detailsDisplay: function ( row, update )
16075
+ {
16076
+ var that = this;
16077
+ var dt = this.s.dt;
16078
+ var details = this.c.details;
16079
+
16080
+ if ( details && details.type !== false ) {
16081
+ var res = details.display( row, update, function () {
16082
+ return details.renderer(
16083
+ dt, row[0], that._detailsObj(row[0])
16084
+ );
16085
+ } );
16086
+
16087
+ if ( res === true || res === false ) {
16088
+ $(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
16089
+ }
16090
+ }
16091
+ },
16092
+
16093
+
16094
+ /**
16095
+ * Initialisation for the details handler
16096
+ *
16097
+ * @private
16098
+ */
16099
+ _detailsInit: function ()
16100
+ {
16101
+ var that = this;
16102
+ var dt = this.s.dt;
16103
+ var details = this.c.details;
16104
+
16105
+ // The inline type always uses the first child as the target
16106
+ if ( details.type === 'inline' ) {
16107
+ details.target = 'td:first-child, th:first-child';
16108
+ }
16109
+
16110
+ // Keyboard accessibility
16111
+ dt.on( 'draw.dtr', function () {
16112
+ that._tabIndexes();
16113
+ } );
16114
+ that._tabIndexes(); // Initial draw has already happened
16115
+
16116
+ $( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
16117
+ if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
16118
+ $(this).click();
16119
+ }
16120
+ } );
16121
+
16122
+ // type.target can be a string jQuery selector or a column index
16123
+ var target = details.target;
16124
+ var selector = typeof target === 'string' ? target : 'td, th';
16125
+
16126
+ // Click handler to show / hide the details rows when they are available
16127
+ $( dt.table().body() )
16128
+ .on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
16129
+ // If the table is not collapsed (i.e. there is no hidden columns)
16130
+ // then take no action
16131
+ if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
16132
+ return;
16133
+ }
16134
+
16135
+ // Check that the row is actually a DataTable's controlled node
16136
+ if ( $.inArray( $(this).closest('tr').get(0), dt.rows().nodes().toArray() ) === -1 ) {
16137
+ return;
16138
+ }
16139
+
16140
+ // For column index, we determine if we should act or not in the
16141
+ // handler - otherwise it is already okay
16142
+ if ( typeof target === 'number' ) {
16143
+ var targetIdx = target < 0 ?
16144
+ dt.columns().eq(0).length + target :
16145
+ target;
16146
+
16147
+ if ( dt.cell( this ).index().column !== targetIdx ) {
16148
+ return;
16149
+ }
16150
+ }
16151
+
16152
+ // $().closest() includes itself in its check
16153
+ var row = dt.row( $(this).closest('tr') );
16154
+
16155
+ // Check event type to do an action
16156
+ if ( e.type === 'click' ) {
16157
+ // The renderer is given as a function so the caller can execute it
16158
+ // only when they need (i.e. if hiding there is no point is running
16159
+ // the renderer)
16160
+ that._detailsDisplay( row, false );
16161
+ }
16162
+ else if ( e.type === 'mousedown' ) {
16163
+ // For mouse users, prevent the focus ring from showing
16164
+ $(this).css('outline', 'none');
16165
+ }
16166
+ else if ( e.type === 'mouseup' ) {
16167
+ // And then re-allow at the end of the click
16168
+ $(this).blur().css('outline', '');
16169
+ }
16170
+ } );
16171
+ },
16172
+
16173
+
16174
+ /**
16175
+ * Get the details to pass to a renderer for a row
16176
+ * @param {int} rowIdx Row index
16177
+ * @private
16178
+ */
16179
+ _detailsObj: function ( rowIdx )
16180
+ {
16181
+ var that = this;
16182
+ var dt = this.s.dt;
16183
+
16184
+ return $.map( this.s.columns, function( col, i ) {
16185
+ // Never and control columns should not be passed to the renderer
16186
+ if ( col.never || col.control ) {
16187
+ return;
16188
+ }
16189
+
16190
+ return {
16191
+ title: dt.settings()[0].aoColumns[ i ].sTitle,
16192
+ data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
16193
+ hidden: dt.column( i ).visible() && !that.s.current[ i ],
16194
+ columnIndex: i,
16195
+ rowIndex: rowIdx
16196
+ };
16197
+ } );
16198
+ },
16199
+
16200
+
16201
+ /**
16202
+ * Find a breakpoint object from a name
16203
+ *
16204
+ * @param {string} name Breakpoint name to find
16205
+ * @return {object} Breakpoint description object
16206
+ * @private
16207
+ */
16208
+ _find: function ( name )
16209
+ {
16210
+ var breakpoints = this.c.breakpoints;
16211
+
16212
+ for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
16213
+ if ( breakpoints[i].name === name ) {
16214
+ return breakpoints[i];
16215
+ }
16216
+ }
16217
+ },
16218
+
16219
+
16220
+ /**
16221
+ * Re-create the contents of the child rows as the display has changed in
16222
+ * some way.
16223
+ *
16224
+ * @private
16225
+ */
16226
+ _redrawChildren: function ()
16227
+ {
16228
+ var that = this;
16229
+ var dt = this.s.dt;
16230
+
16231
+ dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
16232
+ var row = dt.row( idx );
16233
+
16234
+ that._detailsDisplay( dt.row( idx ), true );
16235
+ } );
16236
+ },
16237
+
16238
+
16239
+ /**
16240
+ * Alter the table display for a resized viewport. This involves first
16241
+ * determining what breakpoint the window currently is in, getting the
16242
+ * column visibilities to apply and then setting them.
16243
+ *
16244
+ * @private
16245
+ */
16246
+ _resize: function ()
16247
+ {
16248
+ var that = this;
16249
+ var dt = this.s.dt;
16250
+ var width = $(window).width();
16251
+ var breakpoints = this.c.breakpoints;
16252
+ var breakpoint = breakpoints[0].name;
16253
+ var columns = this.s.columns;
16254
+ var i, ien;
16255
+ var oldVis = this.s.current.slice();
16256
+
16257
+ // Determine what breakpoint we are currently at
16258
+ for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
16259
+ if ( width <= breakpoints[i].width ) {
16260
+ breakpoint = breakpoints[i].name;
16261
+ break;
16262
+ }
16263
+ }
16264
+
16265
+ // Show the columns for that break point
16266
+ var columnsVis = this._columnsVisiblity( breakpoint );
16267
+ this.s.current = columnsVis;
16268
+
16269
+ // Set the class before the column visibility is changed so event
16270
+ // listeners know what the state is. Need to determine if there are
16271
+ // any columns that are not visible but can be shown
16272
+ var collapsedClass = false;
16273
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
16274
+ if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control && ! dt.column(i).visible() === false ) {
16275
+ collapsedClass = true;
16276
+ break;
16277
+ }
16278
+ }
16279
+
16280
+ $( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
16281
+
16282
+ var changed = false;
16283
+ var visible = 0;
16284
+
16285
+ dt.columns().eq(0).each( function ( colIdx, i ) {
16286
+ if ( columnsVis[i] === true ) {
16287
+ visible++;
16288
+ }
16289
+
16290
+ if ( columnsVis[i] !== oldVis[i] ) {
16291
+ changed = true;
16292
+ that._setColumnVis( colIdx, columnsVis[i] );
16293
+ }
16294
+ } );
16295
+
16296
+ if ( changed ) {
16297
+ this._redrawChildren();
16298
+
16299
+ // Inform listeners of the change
16300
+ $(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
16301
+
16302
+ // If no records, update the "No records" display element
16303
+ if ( dt.page.info().recordsDisplay === 0 ) {
16304
+ $('td', dt.table().body()).eq(0).attr('colspan', visible);
16305
+ }
16306
+ }
16307
+ },
16308
+
16309
+
16310
+ /**
16311
+ * Determine the width of each column in the table so the auto column hiding
16312
+ * has that information to work with. This method is never going to be 100%
16313
+ * perfect since column widths can change slightly per page, but without
16314
+ * seriously compromising performance this is quite effective.
16315
+ *
16316
+ * @private
16317
+ */
16318
+ _resizeAuto: function ()
16319
+ {
16320
+ var dt = this.s.dt;
16321
+ var columns = this.s.columns;
16322
+
16323
+ // Are we allowed to do auto sizing?
16324
+ if ( ! this.c.auto ) {
16325
+ return;
16326
+ }
16327
+
16328
+ // Are there any columns that actually need auto-sizing, or do they all
16329
+ // have classes defined
16330
+ if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
16331
+ return;
16332
+ }
16333
+
16334
+ // Need to restore all children. They will be reinstated by a re-render
16335
+ if ( ! $.isEmptyObject( _childNodeStore ) ) {
16336
+ $.each( _childNodeStore, function ( key ) {
16337
+ var idx = key.split('-');
16338
+
16339
+ _childNodesRestore( dt, idx[0]*1, idx[1]*1 );
16340
+ } );
16341
+ }
16342
+
16343
+ // Clone the table with the current data in it
16344
+ var tableWidth = dt.table().node().offsetWidth;
16345
+ var columnWidths = dt.columns;
16346
+ var clonedTable = dt.table().node().cloneNode( false );
16347
+ var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
16348
+ var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
16349
+
16350
+ // Header
16351
+ var headerCells = dt.columns()
16352
+ .header()
16353
+ .filter( function (idx) {
16354
+ return dt.column(idx).visible();
16355
+ } )
16356
+ .to$()
16357
+ .clone( false )
16358
+ .css( 'display', 'table-cell' )
16359
+ .css( 'min-width', 0 );
16360
+
16361
+ // Body rows - we don't need to take account of DataTables' column
16362
+ // visibility since we implement our own here (hence the `display` set)
16363
+ $(clonedBody)
16364
+ .append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
16365
+ .find( 'th, td' ).css( 'display', '' );
16366
+
16367
+ // Footer
16368
+ var footer = dt.table().footer();
16369
+ if ( footer ) {
16370
+ var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
16371
+ var footerCells = dt.columns()
16372
+ .footer()
16373
+ .filter( function (idx) {
16374
+ return dt.column(idx).visible();
16375
+ } )
16376
+ .to$()
16377
+ .clone( false )
16378
+ .css( 'display', 'table-cell' );
16379
+
16380
+ $('<tr/>')
16381
+ .append( footerCells )
16382
+ .appendTo( clonedFooter );
16383
+ }
16384
+
16385
+ $('<tr/>')
16386
+ .append( headerCells )
16387
+ .appendTo( clonedHeader );
16388
+
16389
+ // In the inline case extra padding is applied to the first column to
16390
+ // give space for the show / hide icon. We need to use this in the
16391
+ // calculation
16392
+ if ( this.c.details.type === 'inline' ) {
16393
+ $(clonedTable).addClass( 'dtr-inline collapsed' );
16394
+ }
16395
+
16396
+ // It is unsafe to insert elements with the same name into the DOM
16397
+ // multiple times. For example, cloning and inserting a checked radio
16398
+ // clears the chcecked state of the original radio.
16399
+ $( clonedTable ).find( '[name]' ).removeAttr( 'name' );
16400
+
16401
+ // A position absolute table would take the table out of the flow of
16402
+ // our container element, bypassing the height and width (Scroller)
16403
+ $( clonedTable ).css( 'position', 'relative' )
16404
+
16405
+ var inserted = $('<div/>')
16406
+ .css( {
16407
+ width: 1,
16408
+ height: 1,
16409
+ overflow: 'hidden',
16410
+ clear: 'both'
16411
+ } )
16412
+ .append( clonedTable );
16413
+
16414
+ inserted.insertBefore( dt.table().node() );
16415
+
16416
+ // The cloned header now contains the smallest that each column can be
16417
+ headerCells.each( function (i) {
16418
+ var idx = dt.column.index( 'fromVisible', i );
16419
+ columns[ idx ].minWidth = this.offsetWidth || 0;
16420
+ } );
16421
+
16422
+ inserted.remove();
16423
+ },
16424
+
16425
+ /**
16426
+ * Set a column's visibility.
16427
+ *
16428
+ * We don't use DataTables' column visibility controls in order to ensure
16429
+ * that column visibility can Responsive can no-exist. Since only IE8+ is
16430
+ * supported (and all evergreen browsers of course) the control of the
16431
+ * display attribute works well.
16432
+ *
16433
+ * @param {integer} col Column index
16434
+ * @param {boolean} showHide Show or hide (true or false)
16435
+ * @private
16436
+ */
16437
+ _setColumnVis: function ( col, showHide )
16438
+ {
16439
+ var dt = this.s.dt;
16440
+ var display = showHide ? '' : 'none'; // empty string will remove the attr
16441
+
16442
+ $( dt.column( col ).header() ).css( 'display', display );
16443
+ $( dt.column( col ).footer() ).css( 'display', display );
16444
+ dt.column( col ).nodes().to$().css( 'display', display );
16445
+
16446
+ // If the are child nodes stored, we might need to reinsert them
16447
+ if ( ! $.isEmptyObject( _childNodeStore ) ) {
16448
+ dt.cells( null, col ).indexes().each( function (idx) {
16449
+ _childNodesRestore( dt, idx.row, idx.column );
16450
+ } );
16451
+ }
16452
+ },
16453
+
16454
+
16455
+ /**
16456
+ * Update the cell tab indexes for keyboard accessibility. This is called on
16457
+ * every table draw - that is potentially inefficient, but also the least
16458
+ * complex option given that column visibility can change on the fly. Its a
16459
+ * shame user-focus was removed from CSS 3 UI, as it would have solved this
16460
+ * issue with a single CSS statement.
16461
+ *
16462
+ * @private
16463
+ */
16464
+ _tabIndexes: function ()
16465
+ {
16466
+ var dt = this.s.dt;
16467
+ var cells = dt.cells( { page: 'current' } ).nodes().to$();
16468
+ var ctx = dt.settings()[0];
16469
+ var target = this.c.details.target;
16470
+
16471
+ cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
16472
+
16473
+ if ( typeof target === 'number' ) {
16474
+ dt.cells( null, target, { page: 'current' } ).nodes().to$()
16475
+ .attr( 'tabIndex', ctx.iTabIndex )
16476
+ .data( 'dtr-keyboard', 1 );
16477
+ }
16478
+ else {
16479
+ // This is a bit of a hack - we need to limit the selected nodes to just
16480
+ // those of this table
16481
+ if ( target === 'td:first-child, th:first-child' ) {
16482
+ target = '>td:first-child, >th:first-child';
16483
+ }
16484
+
16485
+ $( target, dt.rows( { page: 'current' } ).nodes() )
16486
+ .attr( 'tabIndex', ctx.iTabIndex )
16487
+ .data( 'dtr-keyboard', 1 );
16488
+ }
16489
+ }
16490
+ } );
16491
+
16492
+
16493
+ /**
16494
+ * List of default breakpoints. Each item in the array is an object with two
16495
+ * properties:
16496
+ *
16497
+ * * `name` - the breakpoint name.
16498
+ * * `width` - the breakpoint width
16499
+ *
16500
+ * @name Responsive.breakpoints
16501
+ * @static
16502
+ */
16503
+ Responsive.breakpoints = [
16504
+ { name: 'desktop', width: Infinity },
16505
+ { name: 'tablet-l', width: 1024 },
16506
+ { name: 'tablet-p', width: 768 },
16507
+ { name: 'mobile-l', width: 480 },
16508
+ { name: 'mobile-p', width: 320 }
16509
+ ];
16510
+
16511
+
16512
+ /**
16513
+ * Display methods - functions which define how the hidden data should be shown
16514
+ * in the table.
16515
+ *
16516
+ * @namespace
16517
+ * @name Responsive.defaults
16518
+ * @static
16519
+ */
16520
+ Responsive.display = {
16521
+ childRow: function ( row, update, render ) {
16522
+ if ( update ) {
16523
+ if ( $(row.node()).hasClass('parent') ) {
16524
+ row.child( render(), 'child' ).show();
16525
+
16526
+ return true;
16527
+ }
16528
+ }
16529
+ else {
16530
+ if ( ! row.child.isShown() ) {
16531
+ row.child( render(), 'child' ).show();
16532
+ $( row.node() ).addClass( 'parent' );
16533
+
16534
+ return true;
16535
+ }
16536
+ else {
16537
+ row.child( false );
16538
+ $( row.node() ).removeClass( 'parent' );
16539
+
16540
+ return false;
16541
+ }
16542
+ }
16543
+ },
16544
+
16545
+ childRowImmediate: function ( row, update, render ) {
16546
+ if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
16547
+ // User interaction and the row is show, or nothing to show
16548
+ row.child( false );
16549
+ $( row.node() ).removeClass( 'parent' );
16550
+
16551
+ return false;
16552
+ }
16553
+ else {
16554
+ // Display
16555
+ row.child( render(), 'child' ).show();
16556
+ $( row.node() ).addClass( 'parent' );
16557
+
16558
+ return true;
16559
+ }
16560
+ },
16561
+
16562
+ // This is a wrapper so the modal options for Bootstrap and jQuery UI can
16563
+ // have options passed into them. This specific one doesn't need to be a
16564
+ // function but it is for consistency in the `modal` name
16565
+ modal: function ( options ) {
16566
+ return function ( row, update, render ) {
16567
+ if ( ! update ) {
16568
+ // Show a modal
16569
+ var close = function () {
16570
+ modal.remove(); // will tidy events for us
16571
+ $(document).off( 'keypress.dtr' );
16572
+ };
16573
+
16574
+ var modal = $('<div class="dtr-modal"/>')
16575
+ .append( $('<div class="dtr-modal-display"/>')
16576
+ .append( $('<div class="dtr-modal-content"/>')
16577
+ .append( render() )
16578
+ )
16579
+ .append( $('<div class="dtr-modal-close">&times;</div>' )
16580
+ .click( function () {
16581
+ close();
16582
+ } )
16583
+ )
16584
+ )
16585
+ .append( $('<div class="dtr-modal-background"/>')
16586
+ .click( function () {
16587
+ close();
16588
+ } )
16589
+ )
16590
+ .appendTo( 'body' );
16591
+
16592
+ $(document).on( 'keyup.dtr', function (e) {
16593
+ if ( e.keyCode === 27 ) {
16594
+ e.stopPropagation();
16595
+
16596
+ close();
16597
+ }
16598
+ } );
16599
+ }
16600
+ else {
16601
+ $('div.dtr-modal-content')
16602
+ .empty()
16603
+ .append( render() );
16604
+ }
16605
+
16606
+ if ( options && options.header ) {
16607
+ $('div.dtr-modal-content').prepend(
16608
+ '<h2>'+options.header( row )+'</h2>'
16609
+ );
16610
+ }
16611
+ };
16612
+ }
16613
+ };
16614
+
16615
+
16616
+ var _childNodeStore = {};
16617
+
16618
+ function _childNodes( dt, row, col ) {
16619
+ var name = row+'-'+col;
16620
+
16621
+ if ( _childNodeStore[ name ] ) {
16622
+ return _childNodeStore[ name ];
16623
+ }
16624
+
16625
+ // https://jsperf.com/childnodes-array-slice-vs-loop
16626
+ var nodes = [];
16627
+ var children = dt.cell( row, col ).node().childNodes;
16628
+ for ( var i=0, ien=children.length ; i<ien ; i++ ) {
16629
+ nodes.push( children[i] );
16630
+ }
16631
+
16632
+ _childNodeStore[ name ] = nodes;
16633
+
16634
+ return nodes;
16635
+ }
16636
+
16637
+ function _childNodesRestore( dt, row, col ) {
16638
+ var name = row+'-'+col;
16639
+
16640
+ if ( ! _childNodeStore[ name ] ) {
16641
+ return;
16642
+ }
16643
+
16644
+ var node = dt.cell( row, col ).node();
16645
+ var store = _childNodeStore[ name ];
16646
+ var parent = store[0].parentNode;
16647
+ var parentChildren = parent.childNodes;
16648
+ var a = [];
16649
+
16650
+ for ( var i=0, ien=parentChildren.length ; i<ien ; i++ ) {
16651
+ a.push( parentChildren[i] );
16652
+ }
16653
+
16654
+ for ( var j=0, jen=a.length ; j<jen ; j++ ) {
16655
+ node.appendChild( a[j] );
16656
+ }
16657
+
16658
+ _childNodeStore[ name ] = undefined;
16659
+ }
16660
+
16661
+
16662
+ /**
16663
+ * Display methods - functions which define how the hidden data should be shown
16664
+ * in the table.
16665
+ *
16666
+ * @namespace
16667
+ * @name Responsive.defaults
16668
+ * @static
16669
+ */
16670
+ Responsive.renderer = {
16671
+ listHiddenNodes: function () {
16672
+ return function ( api, rowIdx, columns ) {
16673
+ var ul = $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>');
16674
+ var found = false;
16675
+
16676
+ var data = $.each( columns, function ( i, col ) {
16677
+ if ( col.hidden ) {
16678
+ $(
16679
+ '<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
16680
+ '<span class="dtr-title">'+
16681
+ col.title+
16682
+ '</span> '+
16683
+ '</li>'
16684
+ )
16685
+ .append( $('<span class="dtr-data"/>').append( _childNodes( api, col.rowIndex, col.columnIndex ) ) )// api.cell( col.rowIndex, col.columnIndex ).node().childNodes ) )
16686
+ .appendTo( ul );
16687
+
16688
+ found = true;
16689
+ }
16690
+ } );
16691
+
16692
+ return found ?
16693
+ ul :
16694
+ false;
16695
+ };
16696
+ },
16697
+
16698
+ listHidden: function () {
16699
+ return function ( api, rowIdx, columns ) {
16700
+ var data = $.map( columns, function ( col ) {
16701
+ return col.hidden ?
16702
+ '<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
16703
+ '<span class="dtr-title">'+
16704
+ col.title+
16705
+ '</span> '+
16706
+ '<span class="dtr-data">'+
16707
+ col.data+
16708
+ '</span>'+
16709
+ '</li>' :
16710
+ '';
16711
+ } ).join('');
16712
+
16713
+ return data ?
16714
+ $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>').append( data ) :
16715
+ false;
16716
+ }
16717
+ },
16718
+
16719
+ tableAll: function ( options ) {
16720
+ options = $.extend( {
16721
+ tableClass: ''
16722
+ }, options );
16723
+
16724
+ return function ( api, rowIdx, columns ) {
16725
+ var data = $.map( columns, function ( col ) {
16726
+ return '<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
16727
+ '<td>'+col.title+':'+'</td> '+
16728
+ '<td>'+col.data+'</td>'+
16729
+ '</tr>';
16730
+ } ).join('');
16731
+
16732
+ return $('<table class="'+options.tableClass+' dtr-details" width="100%"/>').append( data );
16733
+ }
16734
+ }
16735
+ };
16736
+
16737
+ /**
16738
+ * Responsive default settings for initialisation
16739
+ *
16740
+ * @namespace
16741
+ * @name Responsive.defaults
16742
+ * @static
16743
+ */
16744
+ Responsive.defaults = {
16745
+ /**
16746
+ * List of breakpoints for the instance. Note that this means that each
16747
+ * instance can have its own breakpoints. Additionally, the breakpoints
16748
+ * cannot be changed once an instance has been creased.
16749
+ *
16750
+ * @type {Array}
16751
+ * @default Takes the value of `Responsive.breakpoints`
16752
+ */
16753
+ breakpoints: Responsive.breakpoints,
16754
+
16755
+ /**
16756
+ * Enable / disable auto hiding calculations. It can help to increase
16757
+ * performance slightly if you disable this option, but all columns would
16758
+ * need to have breakpoint classes assigned to them
16759
+ *
16760
+ * @type {Boolean}
16761
+ * @default `true`
16762
+ */
16763
+ auto: true,
16764
+
16765
+ /**
16766
+ * Details control. If given as a string value, the `type` property of the
16767
+ * default object is set to that value, and the defaults used for the rest
16768
+ * of the object - this is for ease of implementation.
16769
+ *
16770
+ * The object consists of the following properties:
16771
+ *
16772
+ * * `display` - A function that is used to show and hide the hidden details
16773
+ * * `renderer` - function that is called for display of the child row data.
16774
+ * The default function will show the data from the hidden columns
16775
+ * * `target` - Used as the selector for what objects to attach the child
16776
+ * open / close to
16777
+ * * `type` - `false` to disable the details display, `inline` or `column`
16778
+ * for the two control types
16779
+ *
16780
+ * @type {Object|string}
16781
+ */
16782
+ details: {
16783
+ display: Responsive.display.childRow,
16784
+
16785
+ renderer: Responsive.renderer.listHidden(),
16786
+
16787
+ target: 0,
16788
+
16789
+ type: 'inline'
16790
+ },
16791
+
16792
+ /**
16793
+ * Orthogonal data request option. This is used to define the data type
16794
+ * requested when Responsive gets the data to show in the child row.
16795
+ *
16796
+ * @type {String}
16797
+ */
16798
+ orthogonal: 'display'
16799
+ };
16800
+
16801
+
16802
+ /*
16803
+ * API
16804
+ */
16805
+ var Api = $.fn.dataTable.Api;
16806
+
16807
+ // Doesn't do anything - work around for a bug in DT... Not documented
16808
+ Api.register( 'responsive()', function () {
16809
+ return this;
16810
+ } );
16811
+
16812
+ Api.register( 'responsive.index()', function ( li ) {
16813
+ li = $(li);
16814
+
16815
+ return {
16816
+ column: li.data('dtr-index'),
16817
+ row: li.parent().data('dtr-index')
16818
+ };
16819
+ } );
16820
+
16821
+ Api.register( 'responsive.rebuild()', function () {
16822
+ return this.iterator( 'table', function ( ctx ) {
16823
+ if ( ctx._responsive ) {
16824
+ ctx._responsive._classLogic();
16825
+ }
16826
+ } );
16827
+ } );
16828
+
16829
+ Api.register( 'responsive.recalc()', function () {
16830
+ return this.iterator( 'table', function ( ctx ) {
16831
+ if ( ctx._responsive ) {
16832
+ ctx._responsive._resizeAuto();
16833
+ ctx._responsive._resize();
16834
+ }
16835
+ } );
16836
+ } );
16837
+
16838
+ Api.register( 'responsive.hasHidden()', function () {
16839
+ var ctx = this.context[0];
16840
+
16841
+ return ctx._responsive ?
16842
+ $.inArray( false, ctx._responsive.s.current ) !== -1 :
16843
+ false;
16844
+ } );
16845
+
16846
+ Api.registerPlural( 'columns().responsiveHidden()', 'column().responsiveHidden()', function () {
16847
+ return this.iterator( 'column', function ( settings, column ) {
16848
+ return settings._responsive ?
16849
+ settings._responsive.s.current[ column ] :
16850
+ false;
16851
+ }, 1 );
16852
+ } );
16853
+
16854
+
16855
+ /**
16856
+ * Version information
16857
+ *
16858
+ * @name Responsive.version
16859
+ * @static
16860
+ */
16861
+ Responsive.version = '2.2.2';
16862
+
16863
+
16864
+ $.fn.dataTable.Responsive = Responsive;
16865
+ $.fn.DataTable.Responsive = Responsive;
16866
+
16867
+ // Attach a listener to the document which listens for DataTables initialisation
16868
+ // events so we can automatically initialise
16869
+ $(document).on( 'preInit.dt.dtr', function (e, settings, json) {
16870
+ if ( e.namespace !== 'dt' ) {
16871
+ return;
16872
+ }
16873
+
16874
+ if ( $(settings.nTable).hasClass( 'responsive' ) ||
16875
+ $(settings.nTable).hasClass( 'dt-responsive' ) ||
16876
+ settings.oInit.responsive ||
16877
+ DataTable.defaults.responsive
16878
+ ) {
16879
+ var init = settings.oInit.responsive;
16880
+
16881
+ if ( init !== false ) {
16882
+ new Responsive( settings, $.isPlainObject( init ) ? init : {} );
16883
+ }
16884
+ }
16885
+ } );
16886
+
16887
+
16888
+ return Responsive;
16889
+ }));
16890
+
16891
+