jquery-datatables 1.10.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +27 -0
  5. data/README.md +118 -0
  6. data/Rakefile +166 -0
  7. data/app/assets/images/datatables/sort_asc.png +0 -0
  8. data/app/assets/images/datatables/sort_asc_disabled.png +0 -0
  9. data/app/assets/images/datatables/sort_both.png +0 -0
  10. data/app/assets/images/datatables/sort_desc.png +0 -0
  11. data/app/assets/images/datatables/sort_desc_disabled.png +0 -0
  12. data/app/assets/javascripts/datatables/dataTables.bootstrap.js +182 -0
  13. data/app/assets/javascripts/datatables/dataTables.bootstrap4.js +184 -0
  14. data/app/assets/javascripts/datatables/dataTables.foundation.js +174 -0
  15. data/app/assets/javascripts/datatables/dataTables.jqueryui.js +164 -0
  16. data/app/assets/javascripts/datatables/dataTables.material.js +191 -0
  17. data/app/assets/javascripts/datatables/dataTables.semanticui.js +208 -0
  18. data/app/assets/javascripts/datatables/dataTables.uikit.js +176 -0
  19. data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.bootstrap.js +43 -0
  20. data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.bootstrap4.js +43 -0
  21. data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.foundation.js +43 -0
  22. data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.jqueryui.js +43 -0
  23. data/app/assets/javascripts/datatables/extensions/AutoFill/autoFill.semanticui.js +43 -0
  24. data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +1036 -0
  25. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap.js +68 -0
  26. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap4.js +60 -0
  27. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +199 -0
  28. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.flash.js +1325 -0
  29. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.foundation.js +85 -0
  30. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +1322 -0
  31. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.jqueryui.js +62 -0
  32. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +172 -0
  33. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.semanticui.js +57 -0
  34. data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +1634 -0
  35. data/app/assets/javascripts/datatables/extensions/ColReorder/dataTables.colReorder.js +1335 -0
  36. data/app/assets/javascripts/datatables/extensions/FixedColumns/dataTables.fixedColumns.js +1623 -0
  37. data/app/assets/javascripts/datatables/extensions/FixedHeader/dataTables.fixedHeader.js +672 -0
  38. data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +883 -0
  39. data/app/assets/javascripts/datatables/extensions/Responsive/dataTables.responsive.js +1232 -0
  40. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap.js +81 -0
  41. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap4.js +81 -0
  42. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.foundation.js +62 -0
  43. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.jqueryui.js +63 -0
  44. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.semanticui.js +77 -0
  45. data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +709 -0
  46. data/app/assets/javascripts/datatables/extensions/Scroller/dataTables.scroller.js +1349 -0
  47. data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +1109 -0
  48. data/app/assets/javascripts/datatables/jquery.dataTables.js +15278 -0
  49. data/app/assets/media/swf/flashExport.swf +0 -0
  50. data/app/assets/stylesheets/datatables/dataTables.bootstrap.css +185 -0
  51. data/app/assets/stylesheets/datatables/dataTables.bootstrap4.css +193 -0
  52. data/app/assets/stylesheets/datatables/dataTables.foundation.css +116 -0
  53. data/app/assets/stylesheets/datatables/dataTables.jqueryui.css +481 -0
  54. data/app/assets/stylesheets/datatables/dataTables.material.css +87 -0
  55. data/app/assets/stylesheets/datatables/dataTables.semanticui.css +103 -0
  56. data/app/assets/stylesheets/datatables/dataTables.uikit.css +146 -0
  57. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.bootstrap.css +81 -0
  58. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.bootstrap4.css +81 -0
  59. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.dataTables.css +92 -0
  60. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.foundation.css +85 -0
  61. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.jqueryui.css +85 -0
  62. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.semanticui.css +81 -0
  63. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap.css +102 -0
  64. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap4.css +163 -0
  65. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.dataTables.css +298 -0
  66. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.foundation.css +129 -0
  67. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.jqueryui.css +162 -0
  68. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.semanticui.css +114 -0
  69. data/app/assets/stylesheets/datatables/extensions/Buttons/common.scss +27 -0
  70. data/app/assets/stylesheets/datatables/extensions/Buttons/mixins.scss +89 -0
  71. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.bootstrap.css +11 -0
  72. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.bootstrap4.css +11 -0
  73. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.dataTables.css +11 -0
  74. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.foundation.css +11 -0
  75. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.jqueryui.css +11 -0
  76. data/app/assets/stylesheets/datatables/extensions/ColReorder/colReorder.semanticui.css +11 -0
  77. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap.css +44 -0
  78. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap4.css +44 -0
  79. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.dataTables.css +18 -0
  80. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.foundation.css +27 -0
  81. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.jqueryui.css +8 -0
  82. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.semanticui.css +16 -0
  83. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.bootstrap.css +20 -0
  84. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.bootstrap4.css +20 -0
  85. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.dataTables.css +19 -0
  86. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.foundation.css +20 -0
  87. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.jqueryui.css +15 -0
  88. data/app/assets/stylesheets/datatables/extensions/FixedHeader/fixedHeader.semanticui.css +14 -0
  89. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.bootstrap.css +5 -0
  90. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.bootstrap4.css +5 -0
  91. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.dataTables.css +5 -0
  92. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.foundation.css +5 -0
  93. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.jqueryui.css +5 -0
  94. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.semanticui.css +5 -0
  95. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap.css +181 -0
  96. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap4.css +181 -0
  97. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.dataTables.css +178 -0
  98. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.foundation.css +181 -0
  99. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.jqueryui.css +178 -0
  100. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.semanticui.css +181 -0
  101. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.bootstrap.css +22 -0
  102. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.bootstrap4.css +22 -0
  103. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.dataTables.css +22 -0
  104. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.foundation.css +22 -0
  105. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.jqueryui.css +22 -0
  106. data/app/assets/stylesheets/datatables/extensions/RowReorder/rowReorder.semanticui.css +22 -0
  107. data/app/assets/stylesheets/datatables/extensions/RowReorder/semanticui.scss +5 -0
  108. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.bootstrap.css +24 -0
  109. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.bootstrap4.css +24 -0
  110. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.dataTables.css +20 -0
  111. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.foundation.css +17 -0
  112. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.jqueryui.css +20 -0
  113. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.semanticui.css +20 -0
  114. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap.css +110 -0
  115. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap4.css +110 -0
  116. data/app/assets/stylesheets/datatables/extensions/Select/select.dataTables.css +100 -0
  117. data/app/assets/stylesheets/datatables/extensions/Select/select.foundation.css +112 -0
  118. data/app/assets/stylesheets/datatables/extensions/Select/select.jqueryui.css +100 -0
  119. data/app/assets/stylesheets/datatables/extensions/Select/select.semanticui.css +105 -0
  120. data/app/assets/stylesheets/datatables/jquery.dataTables.css +452 -0
  121. data/app/assets/stylesheets/datatables/jquery.dataTables_themeroller.css +416 -0
  122. data/jquery-datatables.gemspec +27 -0
  123. data/lib/generators/jquery/datatables/install_generator.rb +63 -0
  124. data/lib/generators/jquery/datatables/templates/bootstrap.css.tt +15 -0
  125. data/lib/generators/jquery/datatables/templates/bootstrap.js.tt +22 -0
  126. data/lib/generators/jquery/datatables/templates/bootstrap4.css.tt +15 -0
  127. data/lib/generators/jquery/datatables/templates/bootstrap4.js.tt +22 -0
  128. data/lib/generators/jquery/datatables/templates/foundation.css.tt +15 -0
  129. data/lib/generators/jquery/datatables/templates/foundation.js.tt +24 -0
  130. data/lib/generators/jquery/datatables/templates/jqueryui.css.tt +15 -0
  131. data/lib/generators/jquery/datatables/templates/jqueryui.js.tt +18 -0
  132. data/lib/generators/jquery/datatables/templates/material.css.tt +15 -0
  133. data/lib/generators/jquery/datatables/templates/material.js.tt +19 -0
  134. data/lib/generators/jquery/datatables/templates/regular.css.tt +15 -0
  135. data/lib/generators/jquery/datatables/templates/regular.js.tt +18 -0
  136. data/lib/generators/jquery/datatables/templates/semanticui.css.tt +16 -0
  137. data/lib/generators/jquery/datatables/templates/semanticui.js.tt +22 -0
  138. data/lib/generators/jquery/datatables/templates/uikit.css.tt +15 -0
  139. data/lib/generators/jquery/datatables/templates/uikit.js.tt +19 -0
  140. data/lib/jquery-datatables.rb +26 -0
  141. data/lib/jquery-datatables/engine.rb +11 -0
  142. data/lib/jquery-datatables/version.rb +6 -0
  143. metadata +269 -0
@@ -0,0 +1,1232 @@
1
+ /*! Responsive 2.1.0
2
+ * 2014-2016 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary Responsive
7
+ * @description Responsive tables plug-in for DataTables
8
+ * @version 2.1.0
9
+ * @file dataTables.responsive.js
10
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
+ * @contact www.sprymedia.co.uk/contact
12
+ * @copyright Copyright 2014-2016 SpryMedia Ltd.
13
+ *
14
+ * This source file is free software, available under the following license:
15
+ * MIT license - http://datatables.net/license/mit
16
+ *
17
+ * This source file is distributed in the hope that it will be useful, but
18
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20
+ *
21
+ * For details please refer to: http://www.datatables.net
22
+ */
23
+ (function( factory ){
24
+ if ( typeof define === 'function' && define.amd ) {
25
+ // AMD
26
+ define( ['jquery', 'datatables.net'], function ( $ ) {
27
+ return factory( $, window, document );
28
+ } );
29
+ }
30
+ else if ( typeof exports === 'object' ) {
31
+ // CommonJS
32
+ module.exports = function (root, $) {
33
+ if ( ! root ) {
34
+ root = window;
35
+ }
36
+
37
+ if ( ! $ || ! $.fn.dataTable ) {
38
+ $ = require('datatables.net')(root, $).$;
39
+ }
40
+
41
+ return factory( $, root, root.document );
42
+ };
43
+ }
44
+ else {
45
+ // Browser
46
+ factory( jQuery, window, document );
47
+ }
48
+ }(function( $, window, document, undefined ) {
49
+ 'use strict';
50
+ var DataTable = $.fn.dataTable;
51
+
52
+
53
+ /**
54
+ * Responsive is a plug-in for the DataTables library that makes use of
55
+ * DataTables' ability to change the visibility of columns, changing the
56
+ * visibility of columns so the displayed columns fit into the table container.
57
+ * The end result is that complex tables will be dynamically adjusted to fit
58
+ * into the viewport, be it on a desktop, tablet or mobile browser.
59
+ *
60
+ * Responsive for DataTables has two modes of operation, which can used
61
+ * individually or combined:
62
+ *
63
+ * * Class name based control - columns assigned class names that match the
64
+ * breakpoint logic can be shown / hidden as required for each breakpoint.
65
+ * * Automatic control - columns are automatically hidden when there is no
66
+ * room left to display them. Columns removed from the right.
67
+ *
68
+ * In additional to column visibility control, Responsive also has built into
69
+ * options to use DataTables' child row display to show / hide the information
70
+ * from the table that has been hidden. There are also two modes of operation
71
+ * for this child row display:
72
+ *
73
+ * * Inline - when the control element that the user can use to show / hide
74
+ * child rows is displayed inside the first column of the table.
75
+ * * Column - where a whole column is dedicated to be the show / hide control.
76
+ *
77
+ * Initialisation of Responsive is performed by:
78
+ *
79
+ * * Adding the class `responsive` or `dt-responsive` to the table. In this case
80
+ * Responsive will automatically be initialised with the default configuration
81
+ * options when the DataTable is created.
82
+ * * Using the `responsive` option in the DataTables configuration options. This
83
+ * can also be used to specify the configuration options, or simply set to
84
+ * `true` to use the defaults.
85
+ *
86
+ * @class
87
+ * @param {object} settings DataTables settings object for the host table
88
+ * @param {object} [opts] Configuration options
89
+ * @requires jQuery 1.7+
90
+ * @requires DataTables 1.10.3+
91
+ *
92
+ * @example
93
+ * $('#example').DataTable( {
94
+ * responsive: true
95
+ * } );
96
+ * } );
97
+ */
98
+ var Responsive = function ( settings, opts ) {
99
+ // Sanity check that we are using DataTables 1.10 or newer
100
+ if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.3' ) ) {
101
+ throw 'DataTables Responsive requires DataTables 1.10.3 or newer';
102
+ }
103
+
104
+ this.s = {
105
+ dt: new DataTable.Api( settings ),
106
+ columns: [],
107
+ current: []
108
+ };
109
+
110
+ // Check if responsive has already been initialised on this table
111
+ if ( this.s.dt.settings()[0].responsive ) {
112
+ return;
113
+ }
114
+
115
+ // details is an object, but for simplicity the user can give it as a string
116
+ // or a boolean
117
+ if ( opts && typeof opts.details === 'string' ) {
118
+ opts.details = { type: opts.details };
119
+ }
120
+ else if ( opts && opts.details === false ) {
121
+ opts.details = { type: false };
122
+ }
123
+ else if ( opts && opts.details === true ) {
124
+ opts.details = { type: 'inline' };
125
+ }
126
+
127
+ this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
128
+ settings.responsive = this;
129
+ this._constructor();
130
+ };
131
+
132
+ $.extend( Responsive.prototype, {
133
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
134
+ * Constructor
135
+ */
136
+
137
+ /**
138
+ * Initialise the Responsive instance
139
+ *
140
+ * @private
141
+ */
142
+ _constructor: function ()
143
+ {
144
+ var that = this;
145
+ var dt = this.s.dt;
146
+ var dtPrivateSettings = dt.settings()[0];
147
+ var oldWindowWidth = $(window).width();
148
+
149
+ dt.settings()[0]._responsive = this;
150
+
151
+ // Use DataTables' throttle function to avoid processor thrashing on
152
+ // resize
153
+ $(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
154
+ // iOS has a bug whereby resize can fire when only scrolling
155
+ // See: http://stackoverflow.com/questions/8898412
156
+ var width = $(window).width();
157
+
158
+ if ( width !== oldWindowWidth ) {
159
+ that._resize();
160
+ oldWindowWidth = width;
161
+ }
162
+ } ) );
163
+
164
+ // DataTables doesn't currently trigger an event when a row is added, so
165
+ // we need to hook into its private API to enforce the hidden rows when
166
+ // new data is added
167
+ dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
168
+ if ( $.inArray( false, that.s.current ) !== -1 ) {
169
+ $('td, th', tr).each( function ( i ) {
170
+ var idx = dt.column.index( 'toData', i );
171
+
172
+ if ( that.s.current[idx] === false ) {
173
+ $(this).css('display', 'none');
174
+ }
175
+ } );
176
+ }
177
+ } );
178
+
179
+ // Destroy event handler
180
+ dt.on( 'destroy.dtr', function () {
181
+ dt.off( '.dtr' );
182
+ $( dt.table().body() ).off( '.dtr' );
183
+ $(window).off( 'resize.dtr orientationchange.dtr' );
184
+
185
+ // Restore the columns that we've hidden
186
+ $.each( that.s.current, function ( i, val ) {
187
+ if ( val === false ) {
188
+ that._setColumnVis( i, true );
189
+ }
190
+ } );
191
+ } );
192
+
193
+ // Reorder the breakpoints array here in case they have been added out
194
+ // of order
195
+ this.c.breakpoints.sort( function (a, b) {
196
+ return a.width < b.width ? 1 :
197
+ a.width > b.width ? -1 : 0;
198
+ } );
199
+
200
+ this._classLogic();
201
+ this._resizeAuto();
202
+
203
+ // Details handler
204
+ var details = this.c.details;
205
+
206
+ if ( details.type !== false ) {
207
+ that._detailsInit();
208
+
209
+ // DataTables will trigger this event on every column it shows and
210
+ // hides individually
211
+ dt.on( 'column-visibility.dtr', function (e, ctx, col, vis) {
212
+ that._classLogic();
213
+ that._resizeAuto();
214
+ that._resize();
215
+ } );
216
+
217
+ // Redraw the details box on each draw which will happen if the data
218
+ // has changed. This is used until DataTables implements a native
219
+ // `updated` event for rows
220
+ dt.on( 'draw.dtr', function () {
221
+ that._redrawChildren();
222
+ } );
223
+
224
+ $(dt.table().node()).addClass( 'dtr-'+details.type );
225
+ }
226
+
227
+ dt.on( 'column-reorder.dtr', function (e, settings, details) {
228
+ that._classLogic();
229
+ that._resizeAuto();
230
+ that._resize();
231
+ } );
232
+
233
+ // Change in column sizes means we need to calc
234
+ dt.on( 'column-sizing.dtr', function () {
235
+ that._resizeAuto();
236
+ that._resize();
237
+ });
238
+
239
+ dt.on( 'init.dtr', function (e, settings, details) {
240
+ that._resizeAuto();
241
+ that._resize();
242
+
243
+ // If columns were hidden, then DataTables needs to adjust the
244
+ // column sizing
245
+ if ( $.inArray( false, that.s.current ) ) {
246
+ dt.columns.adjust();
247
+ }
248
+ } );
249
+
250
+ // First pass - draw the table for the current viewport size
251
+ this._resize();
252
+ },
253
+
254
+
255
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
256
+ * Private methods
257
+ */
258
+
259
+ /**
260
+ * Calculate the visibility for the columns in a table for a given
261
+ * breakpoint. The result is pre-determined based on the class logic if
262
+ * class names are used to control all columns, but the width of the table
263
+ * is also used if there are columns which are to be automatically shown
264
+ * and hidden.
265
+ *
266
+ * @param {string} breakpoint Breakpoint name to use for the calculation
267
+ * @return {array} Array of boolean values initiating the visibility of each
268
+ * column.
269
+ * @private
270
+ */
271
+ _columnsVisiblity: function ( breakpoint )
272
+ {
273
+ var dt = this.s.dt;
274
+ var columns = this.s.columns;
275
+ var i, ien;
276
+
277
+ // Create an array that defines the column ordering based first on the
278
+ // column's priority, and secondly the column index. This allows the
279
+ // columns to be removed from the right if the priority matches
280
+ var order = columns
281
+ .map( function ( col, idx ) {
282
+ return {
283
+ columnIdx: idx,
284
+ priority: col.priority
285
+ };
286
+ } )
287
+ .sort( function ( a, b ) {
288
+ if ( a.priority !== b.priority ) {
289
+ return a.priority - b.priority;
290
+ }
291
+ return a.columnIdx - b.columnIdx;
292
+ } );
293
+
294
+ // Class logic - determine which columns are in this breakpoint based
295
+ // on the classes. If no class control (i.e. `auto`) then `-` is used
296
+ // to indicate this to the rest of the function
297
+ var display = $.map( columns, function ( col ) {
298
+ return col.auto && col.minWidth === null ?
299
+ false :
300
+ col.auto === true ?
301
+ '-' :
302
+ $.inArray( breakpoint, col.includeIn ) !== -1;
303
+ } );
304
+
305
+ // Auto column control - first pass: how much width is taken by the
306
+ // ones that must be included from the non-auto columns
307
+ var requiredWidth = 0;
308
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
309
+ if ( display[i] === true ) {
310
+ requiredWidth += columns[i].minWidth;
311
+ }
312
+ }
313
+
314
+ // Second pass, use up any remaining width for other columns. For
315
+ // scrolling tables we need to subtract the width of the scrollbar. It
316
+ // may not be requires which makes this sub-optimal, but it would
317
+ // require another full redraw to make complete use of those extra few
318
+ // pixels
319
+ var scrolling = dt.settings()[0].oScroll;
320
+ var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
321
+ var widthAvailable = dt.table().container().offsetWidth - bar;
322
+ var usedWidth = widthAvailable - requiredWidth;
323
+
324
+ // Control column needs to always be included. This makes it sub-
325
+ // optimal in terms of using the available with, but to stop layout
326
+ // thrashing or overflow. Also we need to account for the control column
327
+ // width first so we know how much width is available for the other
328
+ // columns, since the control column might not be the first one shown
329
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
330
+ if ( columns[i].control ) {
331
+ usedWidth -= columns[i].minWidth;
332
+ }
333
+ }
334
+
335
+ // Allow columns to be shown (counting by priority and then right to
336
+ // left) until we run out of room
337
+ var empty = false;
338
+ for ( i=0, ien=order.length ; i<ien ; i++ ) {
339
+ var colIdx = order[i].columnIdx;
340
+
341
+ if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
342
+ // Once we've found a column that won't fit we don't let any
343
+ // others display either, or columns might disappear in the
344
+ // middle of the table
345
+ if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
346
+ empty = true;
347
+ display[colIdx] = false;
348
+ }
349
+ else {
350
+ display[colIdx] = true;
351
+ }
352
+
353
+ usedWidth -= columns[colIdx].minWidth;
354
+ }
355
+ }
356
+
357
+ // Determine if the 'control' column should be shown (if there is one).
358
+ // This is the case when there is a hidden column (that is not the
359
+ // control column). The two loops look inefficient here, but they are
360
+ // trivial and will fly through. We need to know the outcome from the
361
+ // first , before the action in the second can be taken
362
+ var showControl = false;
363
+
364
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
365
+ if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
366
+ showControl = true;
367
+ break;
368
+ }
369
+ }
370
+
371
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
372
+ if ( columns[i].control ) {
373
+ display[i] = showControl;
374
+ }
375
+ }
376
+
377
+ // Finally we need to make sure that there is at least one column that
378
+ // is visible
379
+ if ( $.inArray( true, display ) === -1 ) {
380
+ display[0] = true;
381
+ }
382
+
383
+ return display;
384
+ },
385
+
386
+
387
+ /**
388
+ * Create the internal `columns` array with information about the columns
389
+ * for the table. This includes determining which breakpoints the column
390
+ * will appear in, based upon class names in the column, which makes up the
391
+ * vast majority of this method.
392
+ *
393
+ * @private
394
+ */
395
+ _classLogic: function ()
396
+ {
397
+ var that = this;
398
+ var calc = {};
399
+ var breakpoints = this.c.breakpoints;
400
+ var dt = this.s.dt;
401
+ var columns = dt.columns().eq(0).map( function (i) {
402
+ var column = this.column(i);
403
+ var className = column.header().className;
404
+ var priority = dt.settings()[0].aoColumns[i].responsivePriority;
405
+
406
+ if ( priority === undefined ) {
407
+ var dataPriority = $(column.header()).data('priority');
408
+
409
+ priority = dataPriority !== undefined ?
410
+ dataPriority * 1 :
411
+ 10000;
412
+ }
413
+
414
+ return {
415
+ className: className,
416
+ includeIn: [],
417
+ auto: false,
418
+ control: false,
419
+ never: className.match(/\bnever\b/) ? true : false,
420
+ priority: priority
421
+ };
422
+ } );
423
+
424
+ // Simply add a breakpoint to `includeIn` array, ensuring that there are
425
+ // no duplicates
426
+ var add = function ( colIdx, name ) {
427
+ var includeIn = columns[ colIdx ].includeIn;
428
+
429
+ if ( $.inArray( name, includeIn ) === -1 ) {
430
+ includeIn.push( name );
431
+ }
432
+ };
433
+
434
+ var column = function ( colIdx, name, operator, matched ) {
435
+ var size, i, ien;
436
+
437
+ if ( ! operator ) {
438
+ columns[ colIdx ].includeIn.push( name );
439
+ }
440
+ else if ( operator === 'max-' ) {
441
+ // Add this breakpoint and all smaller
442
+ size = that._find( name ).width;
443
+
444
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
445
+ if ( breakpoints[i].width <= size ) {
446
+ add( colIdx, breakpoints[i].name );
447
+ }
448
+ }
449
+ }
450
+ else if ( operator === 'min-' ) {
451
+ // Add this breakpoint and all larger
452
+ size = that._find( name ).width;
453
+
454
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
455
+ if ( breakpoints[i].width >= size ) {
456
+ add( colIdx, breakpoints[i].name );
457
+ }
458
+ }
459
+ }
460
+ else if ( operator === 'not-' ) {
461
+ // Add all but this breakpoint
462
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
463
+ if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
464
+ add( colIdx, breakpoints[i].name );
465
+ }
466
+ }
467
+ }
468
+ };
469
+
470
+ // Loop over each column and determine if it has a responsive control
471
+ // class
472
+ columns.each( function ( col, i ) {
473
+ var classNames = col.className.split(' ');
474
+ var hasClass = false;
475
+
476
+ // Split the class name up so multiple rules can be applied if needed
477
+ for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
478
+ var className = $.trim( classNames[k] );
479
+
480
+ if ( className === 'all' ) {
481
+ // Include in all
482
+ hasClass = true;
483
+ col.includeIn = $.map( breakpoints, function (a) {
484
+ return a.name;
485
+ } );
486
+ return;
487
+ }
488
+ else if ( className === 'none' || col.never ) {
489
+ // Include in none (default) and no auto
490
+ hasClass = true;
491
+ return;
492
+ }
493
+ else if ( className === 'control' ) {
494
+ // Special column that is only visible, when one of the other
495
+ // columns is hidden. This is used for the details control
496
+ hasClass = true;
497
+ col.control = true;
498
+ return;
499
+ }
500
+
501
+ $.each( breakpoints, function ( j, breakpoint ) {
502
+ // Does this column have a class that matches this breakpoint?
503
+ var brokenPoint = breakpoint.name.split('-');
504
+ var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
505
+ var match = className.match( re );
506
+
507
+ if ( match ) {
508
+ hasClass = true;
509
+
510
+ if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
511
+ // Class name matches breakpoint name fully
512
+ column( i, breakpoint.name, match[1], match[2]+match[3] );
513
+ }
514
+ else if ( match[2] === brokenPoint[0] && ! match[3] ) {
515
+ // Class name matched primary breakpoint name with no qualifier
516
+ column( i, breakpoint.name, match[1], match[2] );
517
+ }
518
+ }
519
+ } );
520
+ }
521
+
522
+ // If there was no control class, then automatic sizing is used
523
+ if ( ! hasClass ) {
524
+ col.auto = true;
525
+ }
526
+ } );
527
+
528
+ this.s.columns = columns;
529
+ },
530
+
531
+
532
+ /**
533
+ * Show the details for the child row
534
+ *
535
+ * @param {DataTables.Api} row API instance for the row
536
+ * @param {boolean} update Update flag
537
+ * @private
538
+ */
539
+ _detailsDisplay: function ( row, update )
540
+ {
541
+ var that = this;
542
+ var dt = this.s.dt;
543
+ var details = this.c.details;
544
+
545
+ if ( details && details.type !== false ) {
546
+ var res = details.display( row, update, function () {
547
+ return details.renderer(
548
+ dt, row[0], that._detailsObj(row[0])
549
+ );
550
+ } );
551
+
552
+ if ( res === true || res === false ) {
553
+ $(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
554
+ }
555
+ }
556
+ },
557
+
558
+
559
+ /**
560
+ * Initialisation for the details handler
561
+ *
562
+ * @private
563
+ */
564
+ _detailsInit: function ()
565
+ {
566
+ var that = this;
567
+ var dt = this.s.dt;
568
+ var details = this.c.details;
569
+
570
+ // The inline type always uses the first child as the target
571
+ if ( details.type === 'inline' ) {
572
+ details.target = 'td:first-child, th:first-child';
573
+ }
574
+
575
+ // Keyboard accessibility
576
+ dt.on( 'draw.dtr', function () {
577
+ that._tabIndexes();
578
+ } );
579
+ that._tabIndexes(); // Initial draw has already happened
580
+
581
+ $( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
582
+ if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
583
+ $(this).click();
584
+ }
585
+ } );
586
+
587
+ // type.target can be a string jQuery selector or a column index
588
+ var target = details.target;
589
+ var selector = typeof target === 'string' ? target : 'td, th';
590
+
591
+ // Click handler to show / hide the details rows when they are available
592
+ $( dt.table().body() )
593
+ .on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
594
+ // If the table is not collapsed (i.e. there is no hidden columns)
595
+ // then take no action
596
+ if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
597
+ return;
598
+ }
599
+
600
+ // Check that the row is actually a DataTable's controlled node
601
+ if ( ! dt.row( $(this).closest('tr') ).length ) {
602
+ return;
603
+ }
604
+
605
+ // For column index, we determine if we should act or not in the
606
+ // handler - otherwise it is already okay
607
+ if ( typeof target === 'number' ) {
608
+ var targetIdx = target < 0 ?
609
+ dt.columns().eq(0).length + target :
610
+ target;
611
+
612
+ if ( dt.cell( this ).index().column !== targetIdx ) {
613
+ return;
614
+ }
615
+ }
616
+
617
+ // $().closest() includes itself in its check
618
+ var row = dt.row( $(this).closest('tr') );
619
+
620
+ // Check event type to do an action
621
+ if ( e.type === 'click' ) {
622
+ // The renderer is given as a function so the caller can execute it
623
+ // only when they need (i.e. if hiding there is no point is running
624
+ // the renderer)
625
+ that._detailsDisplay( row, false );
626
+ }
627
+ else if ( e.type === 'mousedown' ) {
628
+ // For mouse users, prevent the focus ring from showing
629
+ $(this).css('outline', 'none');
630
+ }
631
+ else if ( e.type === 'mouseup' ) {
632
+ // And then re-allow at the end of the click
633
+ $(this).blur().css('outline', '');
634
+ }
635
+ } );
636
+ },
637
+
638
+
639
+ /**
640
+ * Get the details to pass to a renderer for a row
641
+ * @param {int} rowIdx Row index
642
+ * @private
643
+ */
644
+ _detailsObj: function ( rowIdx )
645
+ {
646
+ var that = this;
647
+ var dt = this.s.dt;
648
+
649
+ return $.map( this.s.columns, function( col, i ) {
650
+ // Never and control columns should not be passed to the renderer
651
+ if ( col.never || col.control ) {
652
+ return;
653
+ }
654
+
655
+ return {
656
+ title: dt.settings()[0].aoColumns[ i ].sTitle,
657
+ data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
658
+ hidden: dt.column( i ).visible() && !that.s.current[ i ],
659
+ columnIndex: i,
660
+ rowIndex: rowIdx
661
+ };
662
+ } );
663
+ },
664
+
665
+
666
+ /**
667
+ * Find a breakpoint object from a name
668
+ *
669
+ * @param {string} name Breakpoint name to find
670
+ * @return {object} Breakpoint description object
671
+ * @private
672
+ */
673
+ _find: function ( name )
674
+ {
675
+ var breakpoints = this.c.breakpoints;
676
+
677
+ for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
678
+ if ( breakpoints[i].name === name ) {
679
+ return breakpoints[i];
680
+ }
681
+ }
682
+ },
683
+
684
+
685
+ /**
686
+ * Re-create the contents of the child rows as the display has changed in
687
+ * some way.
688
+ *
689
+ * @private
690
+ */
691
+ _redrawChildren: function ()
692
+ {
693
+ var that = this;
694
+ var dt = this.s.dt;
695
+
696
+ dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
697
+ var row = dt.row( idx );
698
+
699
+ that._detailsDisplay( dt.row( idx ), true );
700
+ } );
701
+ },
702
+
703
+
704
+ /**
705
+ * Alter the table display for a resized viewport. This involves first
706
+ * determining what breakpoint the window currently is in, getting the
707
+ * column visibilities to apply and then setting them.
708
+ *
709
+ * @private
710
+ */
711
+ _resize: function ()
712
+ {
713
+ var that = this;
714
+ var dt = this.s.dt;
715
+ var width = $(window).width();
716
+ var breakpoints = this.c.breakpoints;
717
+ var breakpoint = breakpoints[0].name;
718
+ var columns = this.s.columns;
719
+ var i, ien;
720
+ var oldVis = this.s.current.slice();
721
+
722
+ // Determine what breakpoint we are currently at
723
+ for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
724
+ if ( width <= breakpoints[i].width ) {
725
+ breakpoint = breakpoints[i].name;
726
+ break;
727
+ }
728
+ }
729
+
730
+ // Show the columns for that break point
731
+ var columnsVis = this._columnsVisiblity( breakpoint );
732
+ this.s.current = columnsVis;
733
+
734
+ // Set the class before the column visibility is changed so event
735
+ // listeners know what the state is. Need to determine if there are
736
+ // any columns that are not visible but can be shown
737
+ var collapsedClass = false;
738
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
739
+ if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control ) {
740
+ collapsedClass = true;
741
+ break;
742
+ }
743
+ }
744
+
745
+ $( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
746
+
747
+ var changed = false;
748
+
749
+ dt.columns().eq(0).each( function ( colIdx, i ) {
750
+ if ( columnsVis[i] !== oldVis[i] ) {
751
+ changed = true;
752
+ that._setColumnVis( colIdx, columnsVis[i] );
753
+ }
754
+ } );
755
+
756
+ if ( changed ) {
757
+ this._redrawChildren();
758
+
759
+ // Inform listeners of the change
760
+ $(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
761
+ }
762
+ },
763
+
764
+
765
+ /**
766
+ * Determine the width of each column in the table so the auto column hiding
767
+ * has that information to work with. This method is never going to be 100%
768
+ * perfect since column widths can change slightly per page, but without
769
+ * seriously compromising performance this is quite effective.
770
+ *
771
+ * @private
772
+ */
773
+ _resizeAuto: function ()
774
+ {
775
+ var dt = this.s.dt;
776
+ var columns = this.s.columns;
777
+
778
+ // Are we allowed to do auto sizing?
779
+ if ( ! this.c.auto ) {
780
+ return;
781
+ }
782
+
783
+ // Are there any columns that actually need auto-sizing, or do they all
784
+ // have classes defined
785
+ if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
786
+ return;
787
+ }
788
+
789
+ // Clone the table with the current data in it
790
+ var tableWidth = dt.table().node().offsetWidth;
791
+ var columnWidths = dt.columns;
792
+ var clonedTable = dt.table().node().cloneNode( false );
793
+ var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
794
+ var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
795
+
796
+ // Header
797
+ var headerCells = dt.columns()
798
+ .header()
799
+ .filter( function (idx) {
800
+ return dt.column(idx).visible();
801
+ } )
802
+ .to$()
803
+ .clone( false )
804
+ .css( 'display', 'table-cell' );
805
+
806
+ // Body rows - we don't need to take account of DataTables' column
807
+ // visibility since we implement our own here (hence the `display` set)
808
+ $(clonedBody)
809
+ .append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
810
+ .find( 'th, td' ).css( 'display', '' );
811
+
812
+ // Footer
813
+ var footer = dt.table().footer();
814
+ if ( footer ) {
815
+ var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
816
+ var footerCells = dt.columns()
817
+ .footer()
818
+ .filter( function (idx) {
819
+ return dt.column(idx).visible();
820
+ } )
821
+ .to$()
822
+ .clone( false )
823
+ .css( 'display', 'table-cell' );
824
+
825
+ $('<tr/>')
826
+ .append( footerCells )
827
+ .appendTo( clonedFooter );
828
+ }
829
+
830
+ $('<tr/>')
831
+ .append( headerCells )
832
+ .appendTo( clonedHeader );
833
+
834
+ // In the inline case extra padding is applied to the first column to
835
+ // give space for the show / hide icon. We need to use this in the
836
+ // calculation
837
+ if ( this.c.details.type === 'inline' ) {
838
+ $(clonedTable).addClass( 'dtr-inline collapsed' );
839
+ }
840
+
841
+ // It is unsafe to insert elements with the same name into the DOM
842
+ // multiple times. For example, cloning and inserting a checked radio
843
+ // clears the chcecked state of the original radio.
844
+ $( clonedTable ).find( '[name]' ).removeAttr( 'name' );
845
+
846
+ var inserted = $('<div/>')
847
+ .css( {
848
+ width: 1,
849
+ height: 1,
850
+ overflow: 'hidden'
851
+ } )
852
+ .append( clonedTable );
853
+
854
+ inserted.insertBefore( dt.table().node() );
855
+
856
+ // The cloned header now contains the smallest that each column can be
857
+ headerCells.each( function (i) {
858
+ var idx = dt.column.index( 'fromVisible', i );
859
+ columns[ idx ].minWidth = this.offsetWidth || 0;
860
+ } );
861
+
862
+ inserted.remove();
863
+ },
864
+
865
+ /**
866
+ * Set a column's visibility.
867
+ *
868
+ * We don't use DataTables' column visibility controls in order to ensure
869
+ * that column visibility can Responsive can no-exist. Since only IE8+ is
870
+ * supported (and all evergreen browsers of course) the control of the
871
+ * display attribute works well.
872
+ *
873
+ * @param {integer} col Column index
874
+ * @param {boolean} showHide Show or hide (true or false)
875
+ * @private
876
+ */
877
+ _setColumnVis: function ( col, showHide )
878
+ {
879
+ var dt = this.s.dt;
880
+ var display = showHide ? '' : 'none'; // empty string will remove the attr
881
+
882
+ $( dt.column( col ).header() ).css( 'display', display );
883
+ $( dt.column( col ).footer() ).css( 'display', display );
884
+ dt.column( col ).nodes().to$().css( 'display', display );
885
+ },
886
+
887
+
888
+ /**
889
+ * Update the cell tab indexes for keyboard accessibility. This is called on
890
+ * every table draw - that is potentially inefficient, but also the least
891
+ * complex option given that column visibility can change on the fly. Its a
892
+ * shame user-focus was removed from CSS 3 UI, as it would have solved this
893
+ * issue with a single CSS statement.
894
+ *
895
+ * @private
896
+ */
897
+ _tabIndexes: function ()
898
+ {
899
+ var dt = this.s.dt;
900
+ var cells = dt.cells( { page: 'current' } ).nodes().to$();
901
+ var ctx = dt.settings()[0];
902
+ var target = this.c.details.target;
903
+
904
+ cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
905
+
906
+ var selector = typeof target === 'number' ?
907
+ ':eq('+target+')' :
908
+ target;
909
+
910
+ $( selector, dt.rows( { page: 'current' } ).nodes() )
911
+ .attr( 'tabIndex', ctx.iTabIndex )
912
+ .data( 'dtr-keyboard', 1 );
913
+ }
914
+ } );
915
+
916
+
917
+ /**
918
+ * List of default breakpoints. Each item in the array is an object with two
919
+ * properties:
920
+ *
921
+ * * `name` - the breakpoint name.
922
+ * * `width` - the breakpoint width
923
+ *
924
+ * @name Responsive.breakpoints
925
+ * @static
926
+ */
927
+ Responsive.breakpoints = [
928
+ { name: 'desktop', width: Infinity },
929
+ { name: 'tablet-l', width: 1024 },
930
+ { name: 'tablet-p', width: 768 },
931
+ { name: 'mobile-l', width: 480 },
932
+ { name: 'mobile-p', width: 320 }
933
+ ];
934
+
935
+
936
+ /**
937
+ * Display methods - functions which define how the hidden data should be shown
938
+ * in the table.
939
+ *
940
+ * @namespace
941
+ * @name Responsive.defaults
942
+ * @static
943
+ */
944
+ Responsive.display = {
945
+ childRow: function ( row, update, render ) {
946
+ if ( update ) {
947
+ if ( $(row.node()).hasClass('parent') ) {
948
+ row.child( render(), 'child' ).show();
949
+
950
+ return true;
951
+ }
952
+ }
953
+ else {
954
+ if ( ! row.child.isShown() ) {
955
+ row.child( render(), 'child' ).show();
956
+ $( row.node() ).addClass( 'parent' );
957
+
958
+ return true;
959
+ }
960
+ else {
961
+ row.child( false );
962
+ $( row.node() ).removeClass( 'parent' );
963
+
964
+ return false;
965
+ }
966
+ }
967
+ },
968
+
969
+ childRowImmediate: function ( row, update, render ) {
970
+ if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
971
+ // User interaction and the row is show, or nothing to show
972
+ row.child( false );
973
+ $( row.node() ).removeClass( 'parent' );
974
+
975
+ return false;
976
+ }
977
+ else {
978
+ // Display
979
+ row.child( render(), 'child' ).show();
980
+ $( row.node() ).addClass( 'parent' );
981
+
982
+ return true;
983
+ }
984
+ },
985
+
986
+ // This is a wrapper so the modal options for Bootstrap and jQuery UI can
987
+ // have options passed into them. This specific one doesn't need to be a
988
+ // function but it is for consistency in the `modal` name
989
+ modal: function ( options ) {
990
+ return function ( row, update, render ) {
991
+ if ( ! update ) {
992
+ // Show a modal
993
+ var close = function () {
994
+ modal.remove(); // will tidy events for us
995
+ $(document).off( 'keypress.dtr' );
996
+ };
997
+
998
+ var modal = $('<div class="dtr-modal"/>')
999
+ .append( $('<div class="dtr-modal-display"/>')
1000
+ .append( $('<div class="dtr-modal-content"/>')
1001
+ .append( render() )
1002
+ )
1003
+ .append( $('<div class="dtr-modal-close">&times;</div>' )
1004
+ .click( function () {
1005
+ close();
1006
+ } )
1007
+ )
1008
+ )
1009
+ .append( $('<div class="dtr-modal-background"/>')
1010
+ .click( function () {
1011
+ close();
1012
+ } )
1013
+ )
1014
+ .appendTo( 'body' );
1015
+
1016
+ $(document).on( 'keyup.dtr', function (e) {
1017
+ if ( e.keyCode === 27 ) {
1018
+ e.stopPropagation();
1019
+
1020
+ close();
1021
+ }
1022
+ } );
1023
+ }
1024
+ else {
1025
+ $('div.dtr-modal-content')
1026
+ .empty()
1027
+ .append( render() );
1028
+ }
1029
+
1030
+ if ( options && options.header ) {
1031
+ $('div.dtr-modal-content').prepend(
1032
+ '<h2>'+options.header( row )+'</h2>'
1033
+ );
1034
+ }
1035
+ };
1036
+ }
1037
+ };
1038
+
1039
+
1040
+ /**
1041
+ * Display methods - functions which define how the hidden data should be shown
1042
+ * in the table.
1043
+ *
1044
+ * @namespace
1045
+ * @name Responsive.defaults
1046
+ * @static
1047
+ */
1048
+ Responsive.renderer = {
1049
+ listHidden: function () {
1050
+ return function ( api, rowIdx, columns ) {
1051
+ var data = $.map( columns, function ( col ) {
1052
+ return col.hidden ?
1053
+ '<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
1054
+ '<span class="dtr-title">'+
1055
+ col.title+
1056
+ '</span> '+
1057
+ '<span class="dtr-data">'+
1058
+ col.data+
1059
+ '</span>'+
1060
+ '</li>' :
1061
+ '';
1062
+ } ).join('');
1063
+
1064
+ return data ?
1065
+ $('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
1066
+ false;
1067
+ }
1068
+ },
1069
+
1070
+ tableAll: function ( options ) {
1071
+ options = $.extend( {
1072
+ tableClass: ''
1073
+ }, options );
1074
+
1075
+ return function ( api, rowIdx, columns ) {
1076
+ var data = $.map( columns, function ( col ) {
1077
+ return '<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
1078
+ '<td>'+col.title+':'+'</td> '+
1079
+ '<td>'+col.data+'</td>'+
1080
+ '</tr>';
1081
+ } ).join('');
1082
+
1083
+ return $('<table class="'+options.tableClass+'" width="100%"/>').append( data );
1084
+ }
1085
+ }
1086
+ };
1087
+
1088
+ /**
1089
+ * Responsive default settings for initialisation
1090
+ *
1091
+ * @namespace
1092
+ * @name Responsive.defaults
1093
+ * @static
1094
+ */
1095
+ Responsive.defaults = {
1096
+ /**
1097
+ * List of breakpoints for the instance. Note that this means that each
1098
+ * instance can have its own breakpoints. Additionally, the breakpoints
1099
+ * cannot be changed once an instance has been creased.
1100
+ *
1101
+ * @type {Array}
1102
+ * @default Takes the value of `Responsive.breakpoints`
1103
+ */
1104
+ breakpoints: Responsive.breakpoints,
1105
+
1106
+ /**
1107
+ * Enable / disable auto hiding calculations. It can help to increase
1108
+ * performance slightly if you disable this option, but all columns would
1109
+ * need to have breakpoint classes assigned to them
1110
+ *
1111
+ * @type {Boolean}
1112
+ * @default `true`
1113
+ */
1114
+ auto: true,
1115
+
1116
+ /**
1117
+ * Details control. If given as a string value, the `type` property of the
1118
+ * default object is set to that value, and the defaults used for the rest
1119
+ * of the object - this is for ease of implementation.
1120
+ *
1121
+ * The object consists of the following properties:
1122
+ *
1123
+ * * `display` - A function that is used to show and hide the hidden details
1124
+ * * `renderer` - function that is called for display of the child row data.
1125
+ * The default function will show the data from the hidden columns
1126
+ * * `target` - Used as the selector for what objects to attach the child
1127
+ * open / close to
1128
+ * * `type` - `false` to disable the details display, `inline` or `column`
1129
+ * for the two control types
1130
+ *
1131
+ * @type {Object|string}
1132
+ */
1133
+ details: {
1134
+ display: Responsive.display.childRow,
1135
+
1136
+ renderer: Responsive.renderer.listHidden(),
1137
+
1138
+ target: 0,
1139
+
1140
+ type: 'inline'
1141
+ },
1142
+
1143
+ /**
1144
+ * Orthogonal data request option. This is used to define the data type
1145
+ * requested when Responsive gets the data to show in the child row.
1146
+ *
1147
+ * @type {String}
1148
+ */
1149
+ orthogonal: 'display'
1150
+ };
1151
+
1152
+
1153
+ /*
1154
+ * API
1155
+ */
1156
+ var Api = $.fn.dataTable.Api;
1157
+
1158
+ // Doesn't do anything - work around for a bug in DT... Not documented
1159
+ Api.register( 'responsive()', function () {
1160
+ return this;
1161
+ } );
1162
+
1163
+ Api.register( 'responsive.index()', function ( li ) {
1164
+ li = $(li);
1165
+
1166
+ return {
1167
+ column: li.data('dtr-index'),
1168
+ row: li.parent().data('dtr-index')
1169
+ };
1170
+ } );
1171
+
1172
+ Api.register( 'responsive.rebuild()', function () {
1173
+ return this.iterator( 'table', function ( ctx ) {
1174
+ if ( ctx._responsive ) {
1175
+ ctx._responsive._classLogic();
1176
+ }
1177
+ } );
1178
+ } );
1179
+
1180
+ Api.register( 'responsive.recalc()', function () {
1181
+ return this.iterator( 'table', function ( ctx ) {
1182
+ if ( ctx._responsive ) {
1183
+ ctx._responsive._resizeAuto();
1184
+ ctx._responsive._resize();
1185
+ }
1186
+ } );
1187
+ } );
1188
+
1189
+ Api.register( 'responsive.hasHidden()', function () {
1190
+ var ctx = this.context[0];
1191
+
1192
+ return ctx._responsive ?
1193
+ $.inArray( false, ctx._responsive.s.current ) !== -1 :
1194
+ false;
1195
+ } );
1196
+
1197
+
1198
+ /**
1199
+ * Version information
1200
+ *
1201
+ * @name Responsive.version
1202
+ * @static
1203
+ */
1204
+ Responsive.version = '2.1.0';
1205
+
1206
+
1207
+ $.fn.dataTable.Responsive = Responsive;
1208
+ $.fn.DataTable.Responsive = Responsive;
1209
+
1210
+ // Attach a listener to the document which listens for DataTables initialisation
1211
+ // events so we can automatically initialise
1212
+ $(document).on( 'preInit.dt.dtr', function (e, settings, json) {
1213
+ if ( e.namespace !== 'dt' ) {
1214
+ return;
1215
+ }
1216
+
1217
+ if ( $(settings.nTable).hasClass( 'responsive' ) ||
1218
+ $(settings.nTable).hasClass( 'dt-responsive' ) ||
1219
+ settings.oInit.responsive ||
1220
+ DataTable.defaults.responsive
1221
+ ) {
1222
+ var init = settings.oInit.responsive;
1223
+
1224
+ if ( init !== false ) {
1225
+ new Responsive( settings, $.isPlainObject( init ) ? init : {} );
1226
+ }
1227
+ }
1228
+ } );
1229
+
1230
+
1231
+ return Responsive;
1232
+ }));