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,1109 @@
1
+ /*! Select for DataTables 1.2.0
2
+ * 2015-2016 SpryMedia Ltd - datatables.net/license/mit
3
+ */
4
+
5
+ /**
6
+ * @summary Select for DataTables
7
+ * @description A collection of API methods, events and buttons for DataTables
8
+ * that provides selection options of the items in a DataTable
9
+ * @version 1.2.0
10
+ * @file dataTables.select.js
11
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
12
+ * @contact datatables.net/forums
13
+ * @copyright Copyright 2015-2016 SpryMedia Ltd.
14
+ *
15
+ * This source file is free software, available under the following license:
16
+ * MIT license - http://datatables.net/license/mit
17
+ *
18
+ * This source file is distributed in the hope that it will be useful, but
19
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
21
+ *
22
+ * For details please refer to: http://www.datatables.net/extensions/select
23
+ */
24
+ (function( factory ){
25
+ if ( typeof define === 'function' && define.amd ) {
26
+ // AMD
27
+ define( ['jquery', 'datatables.net'], function ( $ ) {
28
+ return factory( $, window, document );
29
+ } );
30
+ }
31
+ else if ( typeof exports === 'object' ) {
32
+ // CommonJS
33
+ module.exports = function (root, $) {
34
+ if ( ! root ) {
35
+ root = window;
36
+ }
37
+
38
+ if ( ! $ || ! $.fn.dataTable ) {
39
+ $ = require('datatables.net')(root, $).$;
40
+ }
41
+
42
+ return factory( $, root, root.document );
43
+ };
44
+ }
45
+ else {
46
+ // Browser
47
+ factory( jQuery, window, document );
48
+ }
49
+ }(function( $, window, document, undefined ) {
50
+ 'use strict';
51
+ var DataTable = $.fn.dataTable;
52
+
53
+
54
+ // Version information for debugger
55
+ DataTable.select = {};
56
+
57
+ DataTable.select.version = '1.2.0';
58
+
59
+ DataTable.select.init = function ( dt ) {
60
+ var ctx = dt.settings()[0];
61
+ var init = ctx.oInit.select;
62
+ var defaults = DataTable.defaults.select;
63
+ var opts = init === undefined ?
64
+ defaults :
65
+ init;
66
+
67
+ // Set defaults
68
+ var items = 'row';
69
+ var style = 'api';
70
+ var blurable = false;
71
+ var info = true;
72
+ var selector = 'td, th';
73
+ var className = 'selected';
74
+
75
+ ctx._select = {};
76
+
77
+ // Initialisation customisations
78
+ if ( opts === true ) {
79
+ style = 'os';
80
+ }
81
+ else if ( typeof opts === 'string' ) {
82
+ style = opts;
83
+ }
84
+ else if ( $.isPlainObject( opts ) ) {
85
+ if ( opts.blurable !== undefined ) {
86
+ blurable = opts.blurable;
87
+ }
88
+
89
+ if ( opts.info !== undefined ) {
90
+ info = opts.info;
91
+ }
92
+
93
+ if ( opts.items !== undefined ) {
94
+ items = opts.items;
95
+ }
96
+
97
+ if ( opts.style !== undefined ) {
98
+ style = opts.style;
99
+ }
100
+
101
+ if ( opts.selector !== undefined ) {
102
+ selector = opts.selector;
103
+ }
104
+
105
+ if ( opts.className !== undefined ) {
106
+ className = opts.className;
107
+ }
108
+ }
109
+
110
+ dt.select.selector( selector );
111
+ dt.select.items( items );
112
+ dt.select.style( style );
113
+ dt.select.blurable( blurable );
114
+ dt.select.info( info );
115
+ ctx._select.className = className;
116
+
117
+
118
+ // Sort table based on selected rows. Requires Select Datatables extension
119
+ $.fn.dataTable.ext.order['select-checkbox'] = function ( settings, col ) {
120
+ return this.api().column( col, {order: 'index'} ).nodes().map( function ( td ) {
121
+ if ( settings._select.items === 'row' ) {
122
+ return $( td ).parent().hasClass( settings._select.className );
123
+ } else if ( settings._select.items === 'cell' ) {
124
+ return $( td ).hasClass( settings._select.className );
125
+ }
126
+ return false;
127
+ });
128
+ };
129
+
130
+ // If the init options haven't enabled select, but there is a selectable
131
+ // class name, then enable
132
+ if ( $( dt.table().node() ).hasClass( 'selectable' ) ) {
133
+ dt.select.style( 'os' );
134
+ }
135
+ };
136
+
137
+ /*
138
+
139
+ Select is a collection of API methods, event handlers, event emitters and
140
+ buttons (for the `Buttons` extension) for DataTables. It provides the following
141
+ features, with an overview of how they are implemented:
142
+
143
+ ## Selection of rows, columns and cells. Whether an item is selected or not is
144
+ stored in:
145
+
146
+ * rows: a `_select_selected` property which contains a boolean value of the
147
+ DataTables' `aoData` object for each row
148
+ * columns: a `_select_selected` property which contains a boolean value of the
149
+ DataTables' `aoColumns` object for each column
150
+ * cells: a `_selected_cells` property which contains an array of boolean values
151
+ of the `aoData` object for each row. The array is the same length as the
152
+ columns array, with each element of it representing a cell.
153
+
154
+ This method of using boolean flags allows Select to operate when nodes have not
155
+ been created for rows / cells (DataTables' defer rendering feature).
156
+
157
+ ## API methods
158
+
159
+ A range of API methods are available for triggering selection and de-selection
160
+ of rows. Methods are also available to configure the selection events that can
161
+ be triggered by an end user (such as which items are to be selected). To a large
162
+ extent, these of API methods *is* Select. It is basically a collection of helper
163
+ functions that can be used to select items in a DataTable.
164
+
165
+ Configuration of select is held in the object `_select` which is attached to the
166
+ DataTables settings object on initialisation. Select being available on a table
167
+ is not optional when Select is loaded, but its default is for selection only to
168
+ be available via the API - so the end user wouldn't be able to select rows
169
+ without additional configuration.
170
+
171
+ The `_select` object contains the following properties:
172
+
173
+ ```
174
+ {
175
+ items:string - Can be `rows`, `columns` or `cells`. Defines what item
176
+ will be selected if the user is allowed to activate row
177
+ selection using the mouse.
178
+ style:string - Can be `none`, `single`, `multi` or `os`. Defines the
179
+ interaction style when selecting items
180
+ blurable:boolean - If row selection can be cleared by clicking outside of
181
+ the table
182
+ info:boolean - If the selection summary should be shown in the table
183
+ information elements
184
+ }
185
+ ```
186
+
187
+ In addition to the API methods, Select also extends the DataTables selector
188
+ options for rows, columns and cells adding a `selected` option to the selector
189
+ options object, allowing the developer to select only selected items or
190
+ unselected items.
191
+
192
+ ## Mouse selection of items
193
+
194
+ Clicking on items can be used to select items. This is done by a simple event
195
+ handler that will select the items using the API methods.
196
+
197
+ */
198
+
199
+
200
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
201
+ * Local functions
202
+ */
203
+
204
+ /**
205
+ * Add one or more cells to the selection when shift clicking in OS selection
206
+ * style cell selection.
207
+ *
208
+ * Cell range is more complicated than row and column as we want to select
209
+ * in the visible grid rather than by index in sequence. For example, if you
210
+ * click first in cell 1-1 and then shift click in 2-2 - cells 1-2 and 2-1
211
+ * should also be selected (and not 1-3, 1-4. etc)
212
+ *
213
+ * @param {DataTable.Api} dt DataTable
214
+ * @param {object} idx Cell index to select to
215
+ * @param {object} last Cell index to select from
216
+ * @private
217
+ */
218
+ function cellRange( dt, idx, last )
219
+ {
220
+ var indexes;
221
+ var columnIndexes;
222
+ var rowIndexes;
223
+ var selectColumns = function ( start, end ) {
224
+ if ( start > end ) {
225
+ var tmp = end;
226
+ end = start;
227
+ start = tmp;
228
+ }
229
+
230
+ var record = false;
231
+ return dt.columns( ':visible' ).indexes().filter( function (i) {
232
+ if ( i === start ) {
233
+ record = true;
234
+ }
235
+
236
+ if ( i === end ) { // not else if, as start might === end
237
+ record = false;
238
+ return true;
239
+ }
240
+
241
+ return record;
242
+ } );
243
+ };
244
+
245
+ var selectRows = function ( start, end ) {
246
+ var indexes = dt.rows( { search: 'applied' } ).indexes();
247
+
248
+ // Which comes first - might need to swap
249
+ if ( indexes.indexOf( start ) > indexes.indexOf( end ) ) {
250
+ var tmp = end;
251
+ end = start;
252
+ start = tmp;
253
+ }
254
+
255
+ var record = false;
256
+ return indexes.filter( function (i) {
257
+ if ( i === start ) {
258
+ record = true;
259
+ }
260
+
261
+ if ( i === end ) {
262
+ record = false;
263
+ return true;
264
+ }
265
+
266
+ return record;
267
+ } );
268
+ };
269
+
270
+ if ( ! dt.cells( { selected: true } ).any() && ! last ) {
271
+ // select from the top left cell to this one
272
+ columnIndexes = selectColumns( 0, idx.column );
273
+ rowIndexes = selectRows( 0 , idx.row );
274
+ }
275
+ else {
276
+ // Get column indexes between old and new
277
+ columnIndexes = selectColumns( last.column, idx.column );
278
+ rowIndexes = selectRows( last.row , idx.row );
279
+ }
280
+
281
+ indexes = dt.cells( rowIndexes, columnIndexes ).flatten();
282
+
283
+ if ( ! dt.cells( idx, { selected: true } ).any() ) {
284
+ // Select range
285
+ dt.cells( indexes ).select();
286
+ }
287
+ else {
288
+ // Deselect range
289
+ dt.cells( indexes ).deselect();
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Disable mouse selection by removing the selectors
295
+ *
296
+ * @param {DataTable.Api} dt DataTable to remove events from
297
+ * @private
298
+ */
299
+ function disableMouseSelection( dt )
300
+ {
301
+ var ctx = dt.settings()[0];
302
+ var selector = ctx._select.selector;
303
+
304
+ $( dt.table().body() )
305
+ .off( 'mousedown.dtSelect', selector )
306
+ .off( 'mouseup.dtSelect', selector )
307
+ .off( 'click.dtSelect', selector );
308
+
309
+ $('body').off( 'click.dtSelect' );
310
+ }
311
+
312
+ /**
313
+ * Attach mouse listeners to the table to allow mouse selection of items
314
+ *
315
+ * @param {DataTable.Api} dt DataTable to remove events from
316
+ * @private
317
+ */
318
+ function enableMouseSelection ( dt )
319
+ {
320
+ var body = $( dt.table().body() );
321
+ var ctx = dt.settings()[0];
322
+ var selector = ctx._select.selector;
323
+
324
+ body
325
+ .on( 'mousedown.dtSelect', selector, function(e) {
326
+ // Disallow text selection for shift clicking on the table so multi
327
+ // element selection doesn't look terrible!
328
+ if ( e.shiftKey || e.metaKey || e.ctrlKey ) {
329
+ body
330
+ .css( '-moz-user-select', 'none' )
331
+ .one('selectstart.dtSelect', selector, function () {
332
+ return false;
333
+ } );
334
+ }
335
+ } )
336
+ .on( 'mouseup.dtSelect', selector, function() {
337
+ // Allow text selection to occur again, Mozilla style (tested in FF
338
+ // 35.0.1 - still required)
339
+ body.css( '-moz-user-select', '' );
340
+ } )
341
+ .on( 'click.dtSelect', selector, function ( e ) {
342
+ var items = dt.select.items();
343
+ var idx;
344
+
345
+ // If text was selected (click and drag), then we shouldn't change
346
+ // the row's selected state
347
+ if ( window.getSelection && window.getSelection().toString() ) {
348
+ return;
349
+ }
350
+
351
+ var ctx = dt.settings()[0];
352
+
353
+ // Ignore clicks inside a sub-table
354
+ if ( $(e.target).closest('div.dataTables_wrapper')[0] != dt.table().container() ) {
355
+ return;
356
+ }
357
+
358
+ var cell = dt.cell( $(e.target).closest('td, th') );
359
+
360
+ // Check the cell actually belongs to the host DataTable (so child
361
+ // rows, etc, are ignored)
362
+ if ( ! cell.any() ) {
363
+ return;
364
+ }
365
+
366
+ var event = $.Event('user-select.dt');
367
+ eventTrigger( dt, event, [ items, cell, e ] );
368
+
369
+ if ( event.isDefaultPrevented() ) {
370
+ return;
371
+ }
372
+
373
+ var cellIndex = cell.index();
374
+ if ( items === 'row' ) {
375
+ idx = cellIndex.row;
376
+ typeSelect( e, dt, ctx, 'row', idx );
377
+ }
378
+ else if ( items === 'column' ) {
379
+ idx = cell.index().column;
380
+ typeSelect( e, dt, ctx, 'column', idx );
381
+ }
382
+ else if ( items === 'cell' ) {
383
+ idx = cell.index();
384
+ typeSelect( e, dt, ctx, 'cell', idx );
385
+ }
386
+
387
+ ctx._select_lastCell = cellIndex;
388
+ } );
389
+
390
+ // Blurable
391
+ $('body').on( 'click.dtSelect', function ( e ) {
392
+ if ( ctx._select.blurable ) {
393
+ // If the click was inside the DataTables container, don't blur
394
+ if ( $(e.target).parents().filter( dt.table().container() ).length ) {
395
+ return;
396
+ }
397
+
398
+ // Don't blur in Editor form
399
+ if ( $(e.target).parents('div.DTE').length ) {
400
+ return;
401
+ }
402
+
403
+ clear( ctx, true );
404
+ }
405
+ } );
406
+ }
407
+
408
+ /**
409
+ * Trigger an event on a DataTable
410
+ *
411
+ * @param {DataTable.Api} api DataTable to trigger events on
412
+ * @param {boolean} selected true if selected, false if deselected
413
+ * @param {string} type Item type acting on
414
+ * @param {boolean} any Require that there are values before
415
+ * triggering
416
+ * @private
417
+ */
418
+ function eventTrigger ( api, type, args, any )
419
+ {
420
+ if ( any && ! api.flatten().length ) {
421
+ return;
422
+ }
423
+
424
+ if ( typeof type === 'string' ) {
425
+ type = type +'.dt';
426
+ }
427
+
428
+ args.unshift( api );
429
+
430
+ $(api.table().node()).triggerHandler( type, args );
431
+ }
432
+
433
+ /**
434
+ * Update the information element of the DataTable showing information about the
435
+ * items selected. This is done by adding tags to the existing text
436
+ *
437
+ * @param {DataTable.Api} api DataTable to update
438
+ * @private
439
+ */
440
+ function info ( api )
441
+ {
442
+ var ctx = api.settings()[0];
443
+
444
+ if ( ! ctx._select.info || ! ctx.aanFeatures.i ) {
445
+ return;
446
+ }
447
+
448
+ var output = $('<span class="select-info"/>');
449
+ var add = function ( name, num ) {
450
+ output.append( $('<span class="select-item"/>').append( api.i18n(
451
+ 'select.'+name+'s',
452
+ { _: '%d '+name+'s selected', 0: '', 1: '1 '+name+' selected' },
453
+ num
454
+ ) ) );
455
+ };
456
+
457
+ add( 'row', api.rows( { selected: true } ).flatten().length );
458
+ add( 'column', api.columns( { selected: true } ).flatten().length );
459
+ add( 'cell', api.cells( { selected: true } ).flatten().length );
460
+
461
+ // Internal knowledge of DataTables to loop over all information elements
462
+ $.each( ctx.aanFeatures.i, function ( i, el ) {
463
+ el = $(el);
464
+
465
+ var exisiting = el.children('span.select-info');
466
+ if ( exisiting.length ) {
467
+ exisiting.remove();
468
+ }
469
+
470
+ if ( output.text() !== '' ) {
471
+ el.append( output );
472
+ }
473
+ } );
474
+ }
475
+
476
+ /**
477
+ * Initialisation of a new table. Attach event handlers and callbacks to allow
478
+ * Select to operate correctly.
479
+ *
480
+ * This will occur _after_ the initial DataTables initialisation, although
481
+ * before Ajax data is rendered, if there is ajax data
482
+ *
483
+ * @param {DataTable.settings} ctx Settings object to operate on
484
+ * @private
485
+ */
486
+ function init ( ctx ) {
487
+ var api = new DataTable.Api( ctx );
488
+
489
+ // Row callback so that classes can be added to rows and cells if the item
490
+ // was selected before the element was created. This will happen with the
491
+ // `deferRender` option enabled.
492
+ //
493
+ // This method of attaching to `aoRowCreatedCallback` is a hack until
494
+ // DataTables has proper events for row manipulation If you are reviewing
495
+ // this code to create your own plug-ins, please do not do this!
496
+ ctx.aoRowCreatedCallback.push( {
497
+ fn: function ( row, data, index ) {
498
+ var i, ien;
499
+ var d = ctx.aoData[ index ];
500
+
501
+ // Row
502
+ if ( d._select_selected ) {
503
+ $( row ).addClass( ctx._select.className );
504
+ }
505
+
506
+ // Cells and columns - if separated out, we would need to do two
507
+ // loops, so it makes sense to combine them into a single one
508
+ for ( i=0, ien=ctx.aoColumns.length ; i<ien ; i++ ) {
509
+ if ( ctx.aoColumns[i]._select_selected || (d._selected_cells && d._selected_cells[i]) ) {
510
+ $(d.anCells[i]).addClass( ctx._select.className );
511
+ }
512
+ }
513
+ },
514
+ sName: 'select-deferRender'
515
+ } );
516
+
517
+ // On Ajax reload we want to reselect all rows which are currently selected,
518
+ // if there is an rowId (i.e. a unique value to identify each row with)
519
+ api.on( 'preXhr.dt.dtSelect', function () {
520
+ // note that column selection doesn't need to be cached and then
521
+ // reselected, as they are already selected
522
+ var rows = api.rows( { selected: true } ).ids( true ).filter( function ( d ) {
523
+ return d !== undefined;
524
+ } );
525
+
526
+ var cells = api.cells( { selected: true } ).eq(0).map( function ( cellIdx ) {
527
+ var id = api.row( cellIdx.row ).id( true );
528
+ return id ?
529
+ { row: id, column: cellIdx.column } :
530
+ undefined;
531
+ } ).filter( function ( d ) {
532
+ return d !== undefined;
533
+ } );
534
+
535
+ // On the next draw, reselect the currently selected items
536
+ api.one( 'draw.dt.dtSelect', function () {
537
+ api.rows( rows ).select();
538
+
539
+ // `cells` is not a cell index selector, so it needs a loop
540
+ if ( cells.any() ) {
541
+ cells.each( function ( id ) {
542
+ api.cells( id.row, id.column ).select();
543
+ } );
544
+ }
545
+ } );
546
+ } );
547
+
548
+ // Update the table information element with selected item summary
549
+ api.on( 'draw.dtSelect.dt select.dtSelect.dt deselect.dtSelect.dt info.dt', function () {
550
+ info( api );
551
+ } );
552
+
553
+ // Clean up and release
554
+ api.on( 'destroy.dtSelect', function () {
555
+ disableMouseSelection( api );
556
+ api.off( '.dtSelect' );
557
+ } );
558
+ }
559
+
560
+ /**
561
+ * Add one or more items (rows or columns) to the selection when shift clicking
562
+ * in OS selection style
563
+ *
564
+ * @param {DataTable.Api} dt DataTable
565
+ * @param {string} type Row or column range selector
566
+ * @param {object} idx Item index to select to
567
+ * @param {object} last Item index to select from
568
+ * @private
569
+ */
570
+ function rowColumnRange( dt, type, idx, last )
571
+ {
572
+ // Add a range of rows from the last selected row to this one
573
+ var indexes = dt[type+'s']( { search: 'applied' } ).indexes();
574
+ var idx1 = $.inArray( last, indexes );
575
+ var idx2 = $.inArray( idx, indexes );
576
+
577
+ if ( ! dt[type+'s']( { selected: true } ).any() && idx1 === -1 ) {
578
+ // select from top to here - slightly odd, but both Windows and Mac OS
579
+ // do this
580
+ indexes.splice( $.inArray( idx, indexes )+1, indexes.length );
581
+ }
582
+ else {
583
+ // reverse so we can shift click 'up' as well as down
584
+ if ( idx1 > idx2 ) {
585
+ var tmp = idx2;
586
+ idx2 = idx1;
587
+ idx1 = tmp;
588
+ }
589
+
590
+ indexes.splice( idx2+1, indexes.length );
591
+ indexes.splice( 0, idx1 );
592
+ }
593
+
594
+ if ( ! dt[type]( idx, { selected: true } ).any() ) {
595
+ // Select range
596
+ dt[type+'s']( indexes ).select();
597
+ }
598
+ else {
599
+ // Deselect range - need to keep the clicked on row selected
600
+ indexes.splice( $.inArray( idx, indexes ), 1 );
601
+ dt[type+'s']( indexes ).deselect();
602
+ }
603
+ }
604
+
605
+ /**
606
+ * Clear all selected items
607
+ *
608
+ * @param {DataTable.settings} ctx Settings object of the host DataTable
609
+ * @param {boolean} [force=false] Force the de-selection to happen, regardless
610
+ * of selection style
611
+ * @private
612
+ */
613
+ function clear( ctx, force )
614
+ {
615
+ if ( force || ctx._select.style === 'single' ) {
616
+ var api = new DataTable.Api( ctx );
617
+
618
+ api.rows( { selected: true } ).deselect();
619
+ api.columns( { selected: true } ).deselect();
620
+ api.cells( { selected: true } ).deselect();
621
+ }
622
+ }
623
+
624
+ /**
625
+ * Select items based on the current configuration for style and items.
626
+ *
627
+ * @param {object} e Mouse event object
628
+ * @param {DataTables.Api} dt DataTable
629
+ * @param {DataTable.settings} ctx Settings object of the host DataTable
630
+ * @param {string} type Items to select
631
+ * @param {int|object} idx Index of the item to select
632
+ * @private
633
+ */
634
+ function typeSelect ( e, dt, ctx, type, idx )
635
+ {
636
+ var style = dt.select.style();
637
+ var isSelected = dt[type]( idx, { selected: true } ).any();
638
+
639
+ if ( style === 'os' ) {
640
+ if ( e.ctrlKey || e.metaKey ) {
641
+ // Add or remove from the selection
642
+ dt[type]( idx ).select( ! isSelected );
643
+ }
644
+ else if ( e.shiftKey ) {
645
+ if ( type === 'cell' ) {
646
+ cellRange( dt, idx, ctx._select_lastCell || null );
647
+ }
648
+ else {
649
+ rowColumnRange( dt, type, idx, ctx._select_lastCell ?
650
+ ctx._select_lastCell[type] :
651
+ null
652
+ );
653
+ }
654
+ }
655
+ else {
656
+ // No cmd or shift click - deselect if selected, or select
657
+ // this row only
658
+ var selected = dt[type+'s']( { selected: true } );
659
+
660
+ if ( isSelected && selected.flatten().length === 1 ) {
661
+ dt[type]( idx ).deselect();
662
+ }
663
+ else {
664
+ selected.deselect();
665
+ dt[type]( idx ).select();
666
+ }
667
+ }
668
+ } else if ( style == 'multi+shift' ) {
669
+ if ( e.shiftKey ) {
670
+ if ( type === 'cell' ) {
671
+ cellRange( dt, idx, ctx._select_lastCell || null );
672
+ }
673
+ else {
674
+ rowColumnRange( dt, type, idx, ctx._select_lastCell ?
675
+ ctx._select_lastCell[type] :
676
+ null
677
+ );
678
+ }
679
+ }
680
+ else {
681
+ dt[ type ]( idx ).select( ! isSelected );
682
+ }
683
+ }
684
+ else {
685
+ dt[ type ]( idx ).select( ! isSelected );
686
+ }
687
+ }
688
+
689
+
690
+
691
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
692
+ * DataTables selectors
693
+ */
694
+
695
+ // row and column are basically identical just assigned to different properties
696
+ // and checking a different array, so we can dynamically create the functions to
697
+ // reduce the code size
698
+ $.each( [
699
+ { type: 'row', prop: 'aoData' },
700
+ { type: 'column', prop: 'aoColumns' }
701
+ ], function ( i, o ) {
702
+ DataTable.ext.selector[ o.type ].push( function ( settings, opts, indexes ) {
703
+ var selected = opts.selected;
704
+ var data;
705
+ var out = [];
706
+
707
+ if ( selected === undefined ) {
708
+ return indexes;
709
+ }
710
+
711
+ for ( var i=0, ien=indexes.length ; i<ien ; i++ ) {
712
+ data = settings[ o.prop ][ indexes[i] ];
713
+
714
+ if ( (selected === true && data._select_selected === true) ||
715
+ (selected === false && ! data._select_selected )
716
+ ) {
717
+ out.push( indexes[i] );
718
+ }
719
+ }
720
+
721
+ return out;
722
+ } );
723
+ } );
724
+
725
+ DataTable.ext.selector.cell.push( function ( settings, opts, cells ) {
726
+ var selected = opts.selected;
727
+ var rowData;
728
+ var out = [];
729
+
730
+ if ( selected === undefined ) {
731
+ return cells;
732
+ }
733
+
734
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
735
+ rowData = settings.aoData[ cells[i].row ];
736
+
737
+ if ( (selected === true && rowData._selected_cells && rowData._selected_cells[ cells[i].column ] === true) ||
738
+ (selected === false && ( ! rowData._selected_cells || ! rowData._selected_cells[ cells[i].column ] ) )
739
+ ) {
740
+ out.push( cells[i] );
741
+ }
742
+ }
743
+
744
+ return out;
745
+ } );
746
+
747
+
748
+
749
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
750
+ * DataTables API
751
+ *
752
+ * For complete documentation, please refer to the docs/api directory or the
753
+ * DataTables site
754
+ */
755
+
756
+ // Local variables to improve compression
757
+ var apiRegister = DataTable.Api.register;
758
+ var apiRegisterPlural = DataTable.Api.registerPlural;
759
+
760
+ apiRegister( 'select()', function () {
761
+ return this.iterator( 'table', function ( ctx ) {
762
+ DataTable.select.init( new DataTable.Api( ctx ) );
763
+ } );
764
+ } );
765
+
766
+ apiRegister( 'select.blurable()', function ( flag ) {
767
+ if ( flag === undefined ) {
768
+ return this.context[0]._select.blurable;
769
+ }
770
+
771
+ return this.iterator( 'table', function ( ctx ) {
772
+ ctx._select.blurable = flag;
773
+ } );
774
+ } );
775
+
776
+ apiRegister( 'select.info()', function ( flag ) {
777
+ if ( info === undefined ) {
778
+ return this.context[0]._select.info;
779
+ }
780
+
781
+ return this.iterator( 'table', function ( ctx ) {
782
+ ctx._select.info = flag;
783
+ } );
784
+ } );
785
+
786
+ apiRegister( 'select.items()', function ( items ) {
787
+ if ( items === undefined ) {
788
+ return this.context[0]._select.items;
789
+ }
790
+
791
+ return this.iterator( 'table', function ( ctx ) {
792
+ ctx._select.items = items;
793
+
794
+ eventTrigger( new DataTable.Api( ctx ), 'selectItems', [ items ] );
795
+ } );
796
+ } );
797
+
798
+ // Takes effect from the _next_ selection. None disables future selection, but
799
+ // does not clear the current selection. Use the `deselect` methods for that
800
+ apiRegister( 'select.style()', function ( style ) {
801
+ if ( style === undefined ) {
802
+ return this.context[0]._select.style;
803
+ }
804
+
805
+ return this.iterator( 'table', function ( ctx ) {
806
+ ctx._select.style = style;
807
+
808
+ if ( ! ctx._select_init ) {
809
+ init( ctx );
810
+ }
811
+
812
+ // Add / remove mouse event handlers. They aren't required when only
813
+ // API selection is available
814
+ var dt = new DataTable.Api( ctx );
815
+ disableMouseSelection( dt );
816
+
817
+ if ( style !== 'api' ) {
818
+ enableMouseSelection( dt );
819
+ }
820
+
821
+ eventTrigger( new DataTable.Api( ctx ), 'selectStyle', [ style ] );
822
+ } );
823
+ } );
824
+
825
+ apiRegister( 'select.selector()', function ( selector ) {
826
+ if ( selector === undefined ) {
827
+ return this.context[0]._select.selector;
828
+ }
829
+
830
+ return this.iterator( 'table', function ( ctx ) {
831
+ disableMouseSelection( new DataTable.Api( ctx ) );
832
+
833
+ ctx._select.selector = selector;
834
+
835
+ if ( ctx._select.style !== 'api' ) {
836
+ enableMouseSelection( new DataTable.Api( ctx ) );
837
+ }
838
+ } );
839
+ } );
840
+
841
+
842
+
843
+ apiRegisterPlural( 'rows().select()', 'row().select()', function ( select ) {
844
+ var api = this;
845
+
846
+ if ( select === false ) {
847
+ return this.deselect();
848
+ }
849
+
850
+ this.iterator( 'row', function ( ctx, idx ) {
851
+ clear( ctx );
852
+
853
+ ctx.aoData[ idx ]._select_selected = true;
854
+ $( ctx.aoData[ idx ].nTr ).addClass( ctx._select.className );
855
+ } );
856
+
857
+ this.iterator( 'table', function ( ctx, i ) {
858
+ eventTrigger( api, 'select', [ 'row', api[i] ], true );
859
+ } );
860
+
861
+ return this;
862
+ } );
863
+
864
+ apiRegisterPlural( 'columns().select()', 'column().select()', function ( select ) {
865
+ var api = this;
866
+
867
+ if ( select === false ) {
868
+ return this.deselect();
869
+ }
870
+
871
+ this.iterator( 'column', function ( ctx, idx ) {
872
+ clear( ctx );
873
+
874
+ ctx.aoColumns[ idx ]._select_selected = true;
875
+
876
+ var column = new DataTable.Api( ctx ).column( idx );
877
+
878
+ $( column.header() ).addClass( ctx._select.className );
879
+ $( column.footer() ).addClass( ctx._select.className );
880
+
881
+ column.nodes().to$().addClass( ctx._select.className );
882
+ } );
883
+
884
+ this.iterator( 'table', function ( ctx, i ) {
885
+ eventTrigger( api, 'select', [ 'column', api[i] ], true );
886
+ } );
887
+
888
+ return this;
889
+ } );
890
+
891
+ apiRegisterPlural( 'cells().select()', 'cell().select()', function ( select ) {
892
+ var api = this;
893
+
894
+ if ( select === false ) {
895
+ return this.deselect();
896
+ }
897
+
898
+ this.iterator( 'cell', function ( ctx, rowIdx, colIdx ) {
899
+ clear( ctx );
900
+
901
+ var data = ctx.aoData[ rowIdx ];
902
+
903
+ if ( data._selected_cells === undefined ) {
904
+ data._selected_cells = [];
905
+ }
906
+
907
+ data._selected_cells[ colIdx ] = true;
908
+
909
+ if ( data.anCells ) {
910
+ $( data.anCells[ colIdx ] ).addClass( ctx._select.className );
911
+ }
912
+ } );
913
+
914
+ this.iterator( 'table', function ( ctx, i ) {
915
+ eventTrigger( api, 'select', [ 'cell', api[i] ], true );
916
+ } );
917
+
918
+ return this;
919
+ } );
920
+
921
+
922
+ apiRegisterPlural( 'rows().deselect()', 'row().deselect()', function () {
923
+ var api = this;
924
+
925
+ this.iterator( 'row', function ( ctx, idx ) {
926
+ ctx.aoData[ idx ]._select_selected = false;
927
+ $( ctx.aoData[ idx ].nTr ).removeClass( ctx._select.className );
928
+ } );
929
+
930
+ this.iterator( 'table', function ( ctx, i ) {
931
+ eventTrigger( api, 'deselect', [ 'row', api[i] ], true );
932
+ } );
933
+
934
+ return this;
935
+ } );
936
+
937
+ apiRegisterPlural( 'columns().deselect()', 'column().deselect()', function () {
938
+ var api = this;
939
+
940
+ this.iterator( 'column', function ( ctx, idx ) {
941
+ ctx.aoColumns[ idx ]._select_selected = false;
942
+
943
+ var api = new DataTable.Api( ctx );
944
+ var column = api.column( idx );
945
+
946
+ $( column.header() ).removeClass( ctx._select.className );
947
+ $( column.footer() ).removeClass( ctx._select.className );
948
+
949
+ // Need to loop over each cell, rather than just using
950
+ // `column().nodes()` as cells which are individually selected should
951
+ // not have the `selected` class removed from them
952
+ api.cells( null, idx ).indexes().each( function (cellIdx) {
953
+ var data = ctx.aoData[ cellIdx.row ];
954
+ var cellSelected = data._selected_cells;
955
+
956
+ if ( data.anCells && (! cellSelected || ! cellSelected[ cellIdx.column ]) ) {
957
+ $( data.anCells[ cellIdx.column ] ).removeClass( ctx._select.className );
958
+ }
959
+ } );
960
+ } );
961
+
962
+ this.iterator( 'table', function ( ctx, i ) {
963
+ eventTrigger( api, 'deselect', [ 'column', api[i] ], true );
964
+ } );
965
+
966
+ return this;
967
+ } );
968
+
969
+ apiRegisterPlural( 'cells().deselect()', 'cell().deselect()', function () {
970
+ var api = this;
971
+
972
+ this.iterator( 'cell', function ( ctx, rowIdx, colIdx ) {
973
+ var data = ctx.aoData[ rowIdx ];
974
+
975
+ data._selected_cells[ colIdx ] = false;
976
+
977
+ // Remove class only if the cells exist, and the cell is not column
978
+ // selected, in which case the class should remain (since it is selected
979
+ // in the column)
980
+ if ( data.anCells && ! ctx.aoColumns[ colIdx ]._select_selected ) {
981
+ $( data.anCells[ colIdx ] ).removeClass( ctx._select.className );
982
+ }
983
+ } );
984
+
985
+ this.iterator( 'table', function ( ctx, i ) {
986
+ eventTrigger( api, 'deselect', [ 'cell', api[i] ], true );
987
+ } );
988
+
989
+ return this;
990
+ } );
991
+
992
+
993
+
994
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
995
+ * Buttons
996
+ */
997
+ function i18n( label, def ) {
998
+ return function (dt) {
999
+ return dt.i18n( 'buttons.'+label, def );
1000
+ };
1001
+ }
1002
+
1003
+ $.extend( DataTable.ext.buttons, {
1004
+ selected: {
1005
+ text: i18n( 'selected', 'Selected' ),
1006
+ className: 'buttons-selected',
1007
+ init: function ( dt ) {
1008
+ var that = this;
1009
+
1010
+ // .DT namespace listeners are removed by DataTables automatically
1011
+ // on table destroy
1012
+ dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1013
+ var enable = that.rows( { selected: true } ).any() ||
1014
+ that.columns( { selected: true } ).any() ||
1015
+ that.cells( { selected: true } ).any();
1016
+
1017
+ that.enable( enable );
1018
+ } );
1019
+
1020
+ this.disable();
1021
+ }
1022
+ },
1023
+ selectedSingle: {
1024
+ text: i18n( 'selectedSingle', 'Selected single' ),
1025
+ className: 'buttons-selected-single',
1026
+ init: function ( dt ) {
1027
+ var that = this;
1028
+
1029
+ dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1030
+ var count = dt.rows( { selected: true } ).flatten().length +
1031
+ dt.columns( { selected: true } ).flatten().length +
1032
+ dt.cells( { selected: true } ).flatten().length;
1033
+
1034
+ that.enable( count === 1 );
1035
+ } );
1036
+
1037
+ this.disable();
1038
+ }
1039
+ },
1040
+ selectAll: {
1041
+ text: i18n( 'selectAll', 'Select all' ),
1042
+ className: 'buttons-select-all',
1043
+ action: function () {
1044
+ var items = this.select.items();
1045
+ this[ items+'s' ]().select();
1046
+ }
1047
+ },
1048
+ selectNone: {
1049
+ text: i18n( 'selectNone', 'Deselect all' ),
1050
+ className: 'buttons-select-none',
1051
+ action: function () {
1052
+ clear( this.settings()[0], true );
1053
+ },
1054
+ init: function ( dt ) {
1055
+ var that = this;
1056
+
1057
+ dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1058
+ var count = dt.rows( { selected: true } ).flatten().length +
1059
+ dt.columns( { selected: true } ).flatten().length +
1060
+ dt.cells( { selected: true } ).flatten().length;
1061
+
1062
+ that.enable( count > 0 );
1063
+ } );
1064
+
1065
+ this.disable();
1066
+ }
1067
+ }
1068
+ } );
1069
+
1070
+ $.each( [ 'Row', 'Column', 'Cell' ], function ( i, item ) {
1071
+ var lc = item.toLowerCase();
1072
+
1073
+ DataTable.ext.buttons[ 'select'+item+'s' ] = {
1074
+ text: i18n( 'select'+item+'s', 'Select '+lc+'s' ),
1075
+ className: 'buttons-select-'+lc+'s',
1076
+ action: function () {
1077
+ this.select.items( lc );
1078
+ },
1079
+ init: function ( dt ) {
1080
+ var that = this;
1081
+
1082
+ dt.on( 'selectItems.dt.DT', function ( e, ctx, items ) {
1083
+ that.active( items === lc );
1084
+ } );
1085
+ }
1086
+ };
1087
+ } );
1088
+
1089
+
1090
+
1091
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1092
+ * Initialisation
1093
+ */
1094
+
1095
+ // DataTables creation - check if select has been defined in the options. Note
1096
+ // this required that the table be in the document! If it isn't then something
1097
+ // needs to trigger this method unfortunately. The next major release of
1098
+ // DataTables will rework the events and address this.
1099
+ $(document).on( 'preInit.dt.dtSelect', function (e, ctx) {
1100
+ if ( e.namespace !== 'dt' ) {
1101
+ return;
1102
+ }
1103
+
1104
+ DataTable.select.init( new DataTable.Api( ctx ) );
1105
+ } );
1106
+
1107
+
1108
+ return DataTable.select;
1109
+ }));