jquery-datatables 1.10.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,43 @@
1
+ /*! Bootstrap integration for DataTables' AutoFill
2
+ * ©2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ (function( factory ){
6
+ if ( typeof define === 'function' && define.amd ) {
7
+ // AMD
8
+ define( ['jquery', 'datatables.net-bs', 'datatables.net-autofill'], function ( $ ) {
9
+ return factory( $, window, document );
10
+ } );
11
+ }
12
+ else if ( typeof exports === 'object' ) {
13
+ // CommonJS
14
+ module.exports = function (root, $) {
15
+ if ( ! root ) {
16
+ root = window;
17
+ }
18
+
19
+ if ( ! $ || ! $.fn.dataTable ) {
20
+ $ = require('datatables.net-bs')(root, $).$;
21
+ }
22
+
23
+ if ( ! $.fn.dataTable.AutoFill ) {
24
+ require('datatables.net-autofill')(root, $);
25
+ }
26
+
27
+ return factory( $, root, root.document );
28
+ };
29
+ }
30
+ else {
31
+ // Browser
32
+ factory( jQuery, window, document );
33
+ }
34
+ }(function( $, window, document, undefined ) {
35
+ 'use strict';
36
+ var DataTable = $.fn.dataTable;
37
+
38
+
39
+ DataTable.AutoFill.classes.btn = 'btn btn-primary';
40
+
41
+
42
+ return DataTable;
43
+ }));
@@ -0,0 +1,43 @@
1
+ /*! Bootstrap integration for DataTables' AutoFill
2
+ * ©2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ (function( factory ){
6
+ if ( typeof define === 'function' && define.amd ) {
7
+ // AMD
8
+ define( ['jquery', 'datatables.net-bs4', 'datatables.net-autofill'], function ( $ ) {
9
+ return factory( $, window, document );
10
+ } );
11
+ }
12
+ else if ( typeof exports === 'object' ) {
13
+ // CommonJS
14
+ module.exports = function (root, $) {
15
+ if ( ! root ) {
16
+ root = window;
17
+ }
18
+
19
+ if ( ! $ || ! $.fn.dataTable ) {
20
+ $ = require('datatables.net-bs4')(root, $).$;
21
+ }
22
+
23
+ if ( ! $.fn.dataTable.AutoFill ) {
24
+ require('datatables.net-autofill')(root, $);
25
+ }
26
+
27
+ return factory( $, root, root.document );
28
+ };
29
+ }
30
+ else {
31
+ // Browser
32
+ factory( jQuery, window, document );
33
+ }
34
+ }(function( $, window, document, undefined ) {
35
+ 'use strict';
36
+ var DataTable = $.fn.dataTable;
37
+
38
+
39
+ DataTable.AutoFill.classes.btn = 'btn btn-primary';
40
+
41
+
42
+ return DataTable;
43
+ }));
@@ -0,0 +1,43 @@
1
+ /*! Foundation integration for DataTables' AutoFill
2
+ * ©2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ (function( factory ){
6
+ if ( typeof define === 'function' && define.amd ) {
7
+ // AMD
8
+ define( ['jquery', 'datatables.net-zf', 'datatables.net-autofill'], function ( $ ) {
9
+ return factory( $, window, document );
10
+ } );
11
+ }
12
+ else if ( typeof exports === 'object' ) {
13
+ // CommonJS
14
+ module.exports = function (root, $) {
15
+ if ( ! root ) {
16
+ root = window;
17
+ }
18
+
19
+ if ( ! $ || ! $.fn.dataTable ) {
20
+ $ = require('datatables.net-zf')(root, $).$;
21
+ }
22
+
23
+ if ( ! $.fn.dataTable.AutoFill ) {
24
+ require('datatables.net-autofill')(root, $);
25
+ }
26
+
27
+ return factory( $, root, root.document );
28
+ };
29
+ }
30
+ else {
31
+ // Browser
32
+ factory( jQuery, window, document );
33
+ }
34
+ }(function( $, window, document, undefined ) {
35
+ 'use strict';
36
+ var DataTable = $.fn.dataTable;
37
+
38
+
39
+ DataTable.AutoFill.classes.btn = 'button tiny';
40
+
41
+
42
+ return DataTable;
43
+ }));
@@ -0,0 +1,43 @@
1
+ /*! jQuery UI integration for DataTables' AutoFill
2
+ * ©2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ (function( factory ){
6
+ if ( typeof define === 'function' && define.amd ) {
7
+ // AMD
8
+ define( ['jquery', 'datatables.net-jqui', 'datatables.net-autofill'], function ( $ ) {
9
+ return factory( $, window, document );
10
+ } );
11
+ }
12
+ else if ( typeof exports === 'object' ) {
13
+ // CommonJS
14
+ module.exports = function (root, $) {
15
+ if ( ! root ) {
16
+ root = window;
17
+ }
18
+
19
+ if ( ! $ || ! $.fn.dataTable ) {
20
+ $ = require('datatables.net-jqui')(root, $).$;
21
+ }
22
+
23
+ if ( ! $.fn.dataTable.AutoFill ) {
24
+ require('datatables.net-autofill')(root, $);
25
+ }
26
+
27
+ return factory( $, root, root.document );
28
+ };
29
+ }
30
+ else {
31
+ // Browser
32
+ factory( jQuery, window, document );
33
+ }
34
+ }(function( $, window, document, undefined ) {
35
+ 'use strict';
36
+ var DataTable = $.fn.dataTable;
37
+
38
+
39
+ DataTable.AutoFill.classes.btn = 'ui-button ui-state-default ui-corner-all';
40
+
41
+
42
+ return DataTable;
43
+ }));
@@ -0,0 +1,43 @@
1
+ /*! Bootstrap integration for DataTables' AutoFill
2
+ * ©2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ (function( factory ){
6
+ if ( typeof define === 'function' && define.amd ) {
7
+ // AMD
8
+ define( ['jquery', 'datatables.net-se', 'datatables.net-autofill'], function ( $ ) {
9
+ return factory( $, window, document );
10
+ } );
11
+ }
12
+ else if ( typeof exports === 'object' ) {
13
+ // CommonJS
14
+ module.exports = function (root, $) {
15
+ if ( ! root ) {
16
+ root = window;
17
+ }
18
+
19
+ if ( ! $ || ! $.fn.dataTable ) {
20
+ $ = require('datatables.net-se')(root, $).$;
21
+ }
22
+
23
+ if ( ! $.fn.dataTable.AutoFill ) {
24
+ require('datatables.net-autofill')(root, $);
25
+ }
26
+
27
+ return factory( $, root, root.document );
28
+ };
29
+ }
30
+ else {
31
+ // Browser
32
+ factory( jQuery, window, document );
33
+ }
34
+ }(function( $, window, document, undefined ) {
35
+ 'use strict';
36
+ var DataTable = $.fn.dataTable;
37
+
38
+
39
+ DataTable.AutoFill.classes.btn = 'ui button';
40
+
41
+
42
+ return DataTable;
43
+ }));
@@ -0,0 +1,1036 @@
1
+ /*! AutoFill 2.1.2
2
+ * ©2008-2015 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary AutoFill
7
+ * @description Add Excel like click and drag auto-fill options to DataTables
8
+ * @version 2.1.2
9
+ * @file dataTables.autoFill.js
10
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
+ * @contact www.sprymedia.co.uk/contact
12
+ * @copyright Copyright 2010-2015 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
+ var _instance = 0;
54
+
55
+ /**
56
+ * AutoFill provides Excel like auto-fill features for a DataTable
57
+ *
58
+ * @class AutoFill
59
+ * @constructor
60
+ * @param {object} oTD DataTables settings object
61
+ * @param {object} oConfig Configuration object for AutoFill
62
+ */
63
+ var AutoFill = function( dt, opts )
64
+ {
65
+ if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.8' ) ) {
66
+ throw( "Warning: AutoFill requires DataTables 1.10.8 or greater");
67
+ }
68
+
69
+ // User and defaults configuration object
70
+ this.c = $.extend( true, {},
71
+ DataTable.defaults.autoFill,
72
+ AutoFill.defaults,
73
+ opts
74
+ );
75
+
76
+ /**
77
+ * @namespace Settings object which contains customisable information for AutoFill instance
78
+ */
79
+ this.s = {
80
+ /** @type {DataTable.Api} DataTables' API instance */
81
+ dt: new DataTable.Api( dt ),
82
+
83
+ /** @type {String} Unique namespace for events attached to the document */
84
+ namespace: '.autoFill'+(_instance++),
85
+
86
+ /** @type {Object} Cached dimension information for use in the mouse move event handler */
87
+ scroll: {},
88
+
89
+ /** @type {integer} Interval object used for smooth scrolling */
90
+ scrollInterval: null,
91
+
92
+ handle: {
93
+ height: 0,
94
+ width: 0
95
+ }
96
+ };
97
+
98
+
99
+ /**
100
+ * @namespace Common and useful DOM elements for the class instance
101
+ */
102
+ this.dom = {
103
+ /** @type {jQuery} AutoFill handle */
104
+ handle: $('<div class="dt-autofill-handle"/>'),
105
+
106
+ /**
107
+ * @type {Object} Selected cells outline - Need to use 4 elements,
108
+ * otherwise the mouse over if you back into the selected rectangle
109
+ * will be over that element, rather than the cells!
110
+ */
111
+ select: {
112
+ top: $('<div class="dt-autofill-select top"/>'),
113
+ right: $('<div class="dt-autofill-select right"/>'),
114
+ bottom: $('<div class="dt-autofill-select bottom"/>'),
115
+ left: $('<div class="dt-autofill-select left"/>')
116
+ },
117
+
118
+ /** @type {jQuery} Fill type chooser background */
119
+ background: $('<div class="dt-autofill-background"/>'),
120
+
121
+ /** @type {jQuery} Fill type chooser */
122
+ list: $('<div class="dt-autofill-list">'+this.s.dt.i18n('autoFill.info', '')+'<ul/></div>'),
123
+
124
+ /** @type {jQuery} DataTables scrolling container */
125
+ dtScroll: null,
126
+
127
+ /** @type {jQuery} Offset parent element */
128
+ offsetParent: null
129
+ };
130
+
131
+
132
+ /* Constructor logic */
133
+ this._constructor();
134
+ };
135
+
136
+
137
+
138
+ $.extend( AutoFill.prototype, {
139
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
140
+ * Constructor
141
+ */
142
+
143
+ /**
144
+ * Initialise the RowReorder instance
145
+ *
146
+ * @private
147
+ */
148
+ _constructor: function ()
149
+ {
150
+ var that = this;
151
+ var dt = this.s.dt;
152
+ var dtScroll = $('div.dataTables_scrollBody', this.s.dt.table().container());
153
+
154
+ if ( dtScroll.length ) {
155
+ this.dom.dtScroll = dtScroll;
156
+
157
+ // Need to scroll container to be the offset parent
158
+ if ( dtScroll.css('position') === 'static' ) {
159
+ dtScroll.css( 'position', 'relative' );
160
+ }
161
+ }
162
+
163
+ this._focusListener();
164
+
165
+ this.dom.handle.on( 'mousedown', function (e) {
166
+ that._mousedown( e );
167
+ return false;
168
+ } );
169
+
170
+ dt.on( 'destroy.autoFill', function () {
171
+ dt.off( '.autoFill' );
172
+ $(dt.table().body()).off( that.s.namespace );
173
+ $(document.body).off( that.s.namespace );
174
+ } );
175
+ },
176
+
177
+
178
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
179
+ * Private methods
180
+ */
181
+
182
+ /**
183
+ * Display the AutoFill drag handle by appending it to a table cell. This
184
+ * is the opposite of the _detach method.
185
+ *
186
+ * @param {node} node TD/TH cell to insert the handle into
187
+ * @private
188
+ */
189
+ _attach: function ( node )
190
+ {
191
+ var dt = this.s.dt;
192
+ var idx = dt.cell( node ).index();
193
+ var handle = this.dom.handle;
194
+ var handleDim = this.s.handle;
195
+ var dtScroll = $('div.dataTables_scrollBody', this.s.dt.table().container() );
196
+ var scrollOffsetX=0, scrollOffsetY=0;
197
+
198
+ if ( ! idx || dt.columns( this.c.columns ).indexes().indexOf( idx.column ) === -1 ) {
199
+ this._detach();
200
+ return;
201
+ }
202
+
203
+ if ( ! this.dom.offsetParent ) {
204
+ this.dom.offsetParent = $(node).offsetParent();
205
+ }
206
+
207
+ if ( ! handleDim.height || ! handleDim.width ) {
208
+ // Append to document so we can get its size. Not expecting it to
209
+ // change during the life time of the page
210
+ handle.appendTo( 'body' );
211
+ handleDim.height = handle.outerHeight();
212
+ handleDim.width = handle.outerWidth();
213
+ }
214
+
215
+ var offset = $(node).position();
216
+
217
+ // If scrolling, and the table is not itself the offset parent, need to
218
+ // offset for the scrolling position
219
+ if ( dtScroll.length && this.dom.offsetParent[0] !== dt.table().node() ) {
220
+ scrollOffsetY = dtScroll.scrollTop();
221
+ scrollOffsetX = dtScroll.scrollLeft();
222
+ }
223
+
224
+ this.dom.attachedTo = node;
225
+ handle
226
+ .css( {
227
+ top: offset.top + node.offsetHeight - handleDim.height + scrollOffsetY,
228
+ left: offset.left + node.offsetWidth - handleDim.width + scrollOffsetX
229
+ } )
230
+ .appendTo( this.dom.offsetParent );
231
+ },
232
+
233
+
234
+ /**
235
+ * Determine can the fill type should be. This can be automatic, or ask the
236
+ * end user.
237
+ *
238
+ * @param {array} cells Information about the selected cells from the key
239
+ * up function
240
+ * @private
241
+ */
242
+ _actionSelector: function ( cells )
243
+ {
244
+ var that = this;
245
+ var dt = this.s.dt;
246
+ var actions = AutoFill.actions;
247
+ var available = [];
248
+
249
+ // "Ask" each plug-in if it wants to handle this data
250
+ $.each( actions, function ( key, action ) {
251
+ if ( action.available( dt, cells ) ) {
252
+ available.push( key );
253
+ }
254
+ } );
255
+
256
+ if ( available.length === 1 && this.c.alwaysAsk === false ) {
257
+ // Only one action available - enact it immediately
258
+ var result = actions[ available[0] ].execute( dt, cells );
259
+ this._update( result, cells );
260
+ }
261
+ else {
262
+ // Multiple actions available - ask the end user what they want to do
263
+ var list = this.dom.list.children('ul').empty();
264
+
265
+ // Add a cancel option
266
+ available.push( 'cancel' );
267
+
268
+ $.each( available, function ( i, name ) {
269
+ list.append( $('<li/>')
270
+ .append(
271
+ '<div class="dt-autofill-question">'+
272
+ actions[ name ].option( dt, cells )+
273
+ '<div>'
274
+ )
275
+ .append( $('<div class="dt-autofill-button">' )
276
+ .append( $('<button class="'+AutoFill.classes.btn+'">'+dt.i18n('autoFill.button', '&gt;')+'</button>')
277
+ .on( 'click', function () {
278
+ var result = actions[ name ].execute(
279
+ dt, cells, $(this).closest('li')
280
+ );
281
+ that._update( result, cells );
282
+
283
+ that.dom.background.remove();
284
+ that.dom.list.remove();
285
+ } )
286
+ )
287
+ )
288
+ );
289
+ } );
290
+
291
+ this.dom.background.appendTo( 'body' );
292
+ this.dom.list.appendTo( 'body' );
293
+
294
+ this.dom.list.css( 'margin-top', this.dom.list.outerHeight()/2 * -1 );
295
+ }
296
+ },
297
+
298
+
299
+ /**
300
+ * Remove the AutoFill handle from the document
301
+ *
302
+ * @private
303
+ */
304
+ _detach: function ()
305
+ {
306
+ this.dom.attachedTo = null;
307
+ this.dom.handle.detach();
308
+ },
309
+
310
+
311
+ /**
312
+ * Draw the selection outline by calculating the range between the start
313
+ * and end cells, then placing the highlighting elements to draw a rectangle
314
+ *
315
+ * @param {node} target End cell
316
+ * @param {object} e Originating event
317
+ * @private
318
+ */
319
+ _drawSelection: function ( target, e )
320
+ {
321
+ // Calculate boundary for start cell to this one
322
+ var dt = this.s.dt;
323
+ var start = this.s.start;
324
+ var startCell = $(this.dom.start);
325
+ var endCell = $(target);
326
+ var end = {
327
+ row: dt.rows( { page: 'current' } ).nodes().indexOf( endCell.parent()[0] ),
328
+ column: endCell.index()
329
+ };
330
+
331
+ // Be sure that is a DataTables controlled cell
332
+ if ( ! dt.cell( endCell ).any() ) {
333
+ return;
334
+ }
335
+
336
+ // if target is not in the columns available - do nothing
337
+ if ( dt.columns( this.c.columns ).indexes().indexOf( end.column ) === -1 ) {
338
+ return;
339
+ }
340
+
341
+ this.s.end = end;
342
+
343
+ var top, bottom, left, right, height, width;
344
+
345
+ top = start.row < end.row ? startCell : endCell;
346
+ bottom = start.row < end.row ? endCell : startCell;
347
+ left = start.column < end.column ? startCell : endCell;
348
+ right = start.column < end.column ? endCell : startCell;
349
+
350
+ top = top.position().top;
351
+ left = left.position().left;
352
+ height = bottom.position().top + bottom.outerHeight() - top;
353
+ width = right.position().left + right.outerWidth() - left;
354
+
355
+ var dtScroll = this.dom.dtScroll;
356
+ if ( dtScroll && this.dom.offsetParent[0] !== dt.table().node() ) {
357
+ top += dtScroll.scrollTop();
358
+ left += dtScroll.scrollLeft();
359
+ }
360
+
361
+ var select = this.dom.select;
362
+ select.top.css( {
363
+ top: top,
364
+ left: left,
365
+ width: width
366
+ } );
367
+
368
+ select.left.css( {
369
+ top: top,
370
+ left: left,
371
+ height: height
372
+ } );
373
+
374
+ select.bottom.css( {
375
+ top: top + height,
376
+ left: left,
377
+ width: width
378
+ } );
379
+
380
+ select.right.css( {
381
+ top: top,
382
+ left: left + width,
383
+ height: height
384
+ } );
385
+ },
386
+
387
+
388
+ /**
389
+ * Use the Editor API to perform an update based on the new data for the
390
+ * cells
391
+ *
392
+ * @param {array} cells Information about the selected cells from the key
393
+ * up function
394
+ * @private
395
+ */
396
+ _editor: function ( cells )
397
+ {
398
+ var dt = this.s.dt;
399
+ var editor = this.c.editor;
400
+
401
+ if ( ! editor ) {
402
+ return;
403
+ }
404
+
405
+ // Build the object structure for Editor's multi-row editing
406
+ var idValues = {};
407
+ var nodes = [];
408
+ var fields = editor.fields();
409
+
410
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
411
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
412
+ var cell = cells[i][j];
413
+
414
+ // Determine the field name for the cell being edited
415
+ var col = dt.settings()[0].aoColumns[ cell.index.column ];
416
+ var fieldName = col.editField;
417
+
418
+ if ( fieldName === undefined ) {
419
+ var dataSrc = col.mData;
420
+
421
+ // dataSrc is the `field.data` property, but we need to set
422
+ // using the field name, so we need to translate from the
423
+ // data to the name
424
+ for ( var k=0, ken=fields.length ; k<ken ; k++ ) {
425
+ var field = editor.field( fields[k] );
426
+
427
+ if ( field.dataSrc() === dataSrc ) {
428
+ fieldName = field.name();
429
+ break;
430
+ }
431
+ }
432
+ }
433
+
434
+ if ( ! fieldName ) {
435
+ throw 'Could not automatically determine field data. '+
436
+ 'Please see https://datatables.net/tn/11';
437
+ }
438
+
439
+ if ( ! idValues[ fieldName ] ) {
440
+ idValues[ fieldName ] = {};
441
+ }
442
+
443
+ var id = dt.row( cell.index.row ).id();
444
+ idValues[ fieldName ][ id ] = cell.set;
445
+
446
+ // Keep a list of cells so we can activate the bubble editing
447
+ // with them
448
+ nodes.push( cell.index );
449
+ }
450
+ }
451
+
452
+ // Perform the edit using bubble editing as it allows us to specify
453
+ // the cells to be edited, rather than using full rows
454
+ editor
455
+ .bubble( nodes, false )
456
+ .multiSet( idValues )
457
+ .submit();
458
+ },
459
+
460
+
461
+ /**
462
+ * Emit an event on the DataTable for listeners
463
+ *
464
+ * @param {string} name Event name
465
+ * @param {array} args Event arguments
466
+ * @private
467
+ */
468
+ _emitEvent: function ( name, args )
469
+ {
470
+ this.s.dt.iterator( 'table', function ( ctx, i ) {
471
+ $(ctx.nTable).triggerHandler( name+'.dt', args );
472
+ } );
473
+ },
474
+
475
+
476
+ /**
477
+ * Attach suitable listeners (based on the configuration) that will attach
478
+ * and detach the AutoFill handle in the document.
479
+ *
480
+ * @private
481
+ */
482
+ _focusListener: function ()
483
+ {
484
+ var that = this;
485
+ var dt = this.s.dt;
486
+ var namespace = this.s.namespace;
487
+ var focus = this.c.focus !== null ?
488
+ this.c.focus :
489
+ dt.settings()[0].keytable ?
490
+ 'focus' :
491
+ 'hover';
492
+
493
+ // All event listeners attached here are removed in the `destroy`
494
+ // callback in the constructor
495
+ if ( focus === 'focus' ) {
496
+ dt
497
+ .on( 'key-focus.autoFill', function ( e, dt, cell ) {
498
+ that._attach( cell.node() );
499
+ } )
500
+ .on( 'key-blur.autoFill', function ( e, dt, cell ) {
501
+ that._detach();
502
+ } );
503
+ }
504
+ else if ( focus === 'click' ) {
505
+ $(dt.table().body()).on( 'click'+namespace, 'td, th', function (e) {
506
+ that._attach( this );
507
+ } );
508
+
509
+ $(document.body).on( 'click'+namespace, function (e) {
510
+ if ( ! $(e.target).parents().filter( dt.table().body() ).length ) {
511
+ that._detach();
512
+ }
513
+ } );
514
+ }
515
+ else {
516
+ $(dt.table().body())
517
+ .on( 'mouseenter'+namespace, 'td, th', function (e) {
518
+ that._attach( this );
519
+ } )
520
+ .on( 'mouseleave'+namespace, function (e) {
521
+ if ( $(e.relatedTarget).hasClass('dt-autofill-handle') ) {
522
+ return;
523
+ }
524
+
525
+ that._detach();
526
+ } );
527
+ }
528
+ },
529
+
530
+
531
+ /**
532
+ * Start mouse drag - selects the start cell
533
+ *
534
+ * @param {object} e Mouse down event
535
+ * @private
536
+ */
537
+ _mousedown: function ( e )
538
+ {
539
+ var that = this;
540
+ var dt = this.s.dt;
541
+
542
+ this.dom.start = this.dom.attachedTo;
543
+ this.s.start = {
544
+ row: dt.rows( { page: 'current' } ).nodes().indexOf( $(this.dom.start).parent()[0] ),
545
+ column: $(this.dom.start).index()
546
+ };
547
+
548
+ $(document.body)
549
+ .on( 'mousemove.autoFill', function (e) {
550
+ that._mousemove( e );
551
+ } )
552
+ .on( 'mouseup.autoFill', function (e) {
553
+ that._mouseup( e );
554
+ } );
555
+
556
+ var select = this.dom.select;
557
+ var offsetParent = $(this.s.dt.table().body()).offsetParent();
558
+ select.top.appendTo( offsetParent );
559
+ select.left.appendTo( offsetParent );
560
+ select.right.appendTo( offsetParent );
561
+ select.bottom.appendTo( offsetParent );
562
+
563
+ this._drawSelection( this.dom.start, e );
564
+
565
+ this.dom.handle.css( 'display', 'none' );
566
+
567
+ // Cache scrolling information so mouse move doesn't need to read.
568
+ // This assumes that the window and DT scroller will not change size
569
+ // during an AutoFill drag, which I think is a fair assumption
570
+ var scrollWrapper = this.dom.dtScroll;
571
+ this.s.scroll = {
572
+ windowHeight: $(window).height(),
573
+ windowWidth: $(window).width(),
574
+ dtTop: scrollWrapper ? scrollWrapper.offset().top : null,
575
+ dtLeft: scrollWrapper ? scrollWrapper.offset().left : null,
576
+ dtHeight: scrollWrapper ? scrollWrapper.outerHeight() : null,
577
+ dtWidth: scrollWrapper ? scrollWrapper.outerWidth() : null
578
+ };
579
+ },
580
+
581
+
582
+ /**
583
+ * Mouse drag - selects the end cell and update the selection display for
584
+ * the end user
585
+ *
586
+ * @param {object} e Mouse move event
587
+ * @private
588
+ */
589
+ _mousemove: function ( e )
590
+ {
591
+ var that = this;
592
+ var dt = this.s.dt;
593
+ var name = e.target.nodeName.toLowerCase();
594
+ if ( name !== 'td' && name !== 'th' ) {
595
+ return;
596
+ }
597
+
598
+ this._drawSelection( e.target, e );
599
+ this._shiftScroll( e );
600
+ },
601
+
602
+
603
+ /**
604
+ * End mouse drag - perform the update actions
605
+ *
606
+ * @param {object} e Mouse up event
607
+ * @private
608
+ */
609
+ _mouseup: function ( e )
610
+ {
611
+ $(document.body).off( '.autoFill' );
612
+
613
+ var dt = this.s.dt;
614
+ var select = this.dom.select;
615
+ select.top.remove();
616
+ select.left.remove();
617
+ select.right.remove();
618
+ select.bottom.remove();
619
+
620
+ this.dom.handle.css( 'display', 'block' );
621
+
622
+ // Display complete - now do something useful with the selection!
623
+ var start = this.s.start;
624
+ var end = this.s.end;
625
+
626
+ // Haven't selected multiple cells, so nothing to do
627
+ if ( start.row === end.row && start.column === end.column ) {
628
+ return;
629
+ }
630
+
631
+ // Build a matrix representation of the selected rows
632
+ var rows = this._range( start.row, end.row );
633
+ var columns = this._range( start.column, end.column );
634
+ var selected = [];
635
+ var dtSettings = dt.settings()[0];
636
+ var dtColumns = dtSettings.aoColumns;
637
+
638
+ // Can't use Array.prototype.map as IE8 doesn't support it
639
+ // Can't use $.map as jQuery flattens 2D arrays
640
+ // Need to use a good old fashioned for loop
641
+ for ( var rowIdx=0 ; rowIdx<rows.length ; rowIdx++ ) {
642
+ selected.push(
643
+ $.map( columns, function (column) {
644
+ var cell = dt.cell( ':eq('+rows[rowIdx]+')', column+':visible', {page:'current'} );
645
+ var data = cell.data();
646
+ var cellIndex = cell.index();
647
+ var editField = dtColumns[ cellIndex.column ].editField;
648
+
649
+ if ( editField !== undefined ) {
650
+ data = dtSettings.oApi._fnGetObjectDataFn( editField )( dt.row( cellIndex.row ).data() );
651
+ }
652
+
653
+ return {
654
+ cell: cell,
655
+ data: data,
656
+ label: cell.data(),
657
+ index: cellIndex
658
+ };
659
+ } )
660
+ );
661
+ }
662
+
663
+ this._actionSelector( selected );
664
+
665
+ // Stop shiftScroll
666
+ clearInterval( this.s.scrollInterval );
667
+ this.s.scrollInterval = null;
668
+ },
669
+
670
+
671
+ /**
672
+ * Create an array with a range of numbers defined by the start and end
673
+ * parameters passed in (inclusive!).
674
+ *
675
+ * @param {integer} start Start
676
+ * @param {integer} end End
677
+ * @private
678
+ */
679
+ _range: function ( start, end )
680
+ {
681
+ var out = [];
682
+ var i;
683
+
684
+ if ( start <= end ) {
685
+ for ( i=start ; i<=end ; i++ ) {
686
+ out.push( i );
687
+ }
688
+ }
689
+ else {
690
+ for ( i=start ; i>=end ; i-- ) {
691
+ out.push( i );
692
+ }
693
+ }
694
+
695
+ return out;
696
+ },
697
+
698
+
699
+ /**
700
+ * Move the window and DataTables scrolling during a drag to scroll new
701
+ * content into view. This is done by proximity to the edge of the scrolling
702
+ * container of the mouse - for example near the top edge of the window
703
+ * should scroll up. This is a little complicated as there are two elements
704
+ * that can be scrolled - the window and the DataTables scrolling view port
705
+ * (if scrollX and / or scrollY is enabled).
706
+ *
707
+ * @param {object} e Mouse move event object
708
+ * @private
709
+ */
710
+ _shiftScroll: function ( e )
711
+ {
712
+ var that = this;
713
+ var dt = this.s.dt;
714
+ var scroll = this.s.scroll;
715
+ var runInterval = false;
716
+ var scrollSpeed = 5;
717
+ var buffer = 65;
718
+ var
719
+ windowY = e.pageY - document.body.scrollTop,
720
+ windowX = e.pageX - document.body.scrollLeft,
721
+ windowVert, windowHoriz,
722
+ dtVert, dtHoriz;
723
+
724
+ // Window calculations - based on the mouse position in the window,
725
+ // regardless of scrolling
726
+ if ( windowY < buffer ) {
727
+ windowVert = scrollSpeed * -1;
728
+ }
729
+ else if ( windowY > scroll.windowHeight - buffer ) {
730
+ windowVert = scrollSpeed;
731
+ }
732
+
733
+ if ( windowX < buffer ) {
734
+ windowHoriz = scrollSpeed * -1;
735
+ }
736
+ else if ( windowX > scroll.windowWidth - buffer ) {
737
+ windowHoriz = scrollSpeed;
738
+ }
739
+
740
+ // DataTables scrolling calculations - based on the table's position in
741
+ // the document and the mouse position on the page
742
+ if ( scroll.dtTop !== null && e.pageY < scroll.dtTop + buffer ) {
743
+ dtVert = scrollSpeed * -1;
744
+ }
745
+ else if ( scroll.dtTop !== null && e.pageY > scroll.dtTop + scroll.dtHeight - buffer ) {
746
+ dtVert = scrollSpeed;
747
+ }
748
+
749
+ if ( scroll.dtLeft !== null && e.pageX < scroll.dtLeft + buffer ) {
750
+ dtHoriz = scrollSpeed * -1;
751
+ }
752
+ else if ( scroll.dtLeft !== null && e.pageX > scroll.dtLeft + scroll.dtWidth - buffer ) {
753
+ dtHoriz = scrollSpeed;
754
+ }
755
+
756
+ // This is where it gets interesting. We want to continue scrolling
757
+ // without requiring a mouse move, so we need an interval to be
758
+ // triggered. The interval should continue until it is no longer needed,
759
+ // but it must also use the latest scroll commands (for example consider
760
+ // that the mouse might move from scrolling up to scrolling left, all
761
+ // with the same interval running. We use the `scroll` object to "pass"
762
+ // this information to the interval. Can't use local variables as they
763
+ // wouldn't be the ones that are used by an already existing interval!
764
+ if ( windowVert || windowHoriz || dtVert || dtHoriz ) {
765
+ scroll.windowVert = windowVert;
766
+ scroll.windowHoriz = windowHoriz;
767
+ scroll.dtVert = dtVert;
768
+ scroll.dtHoriz = dtHoriz;
769
+ runInterval = true;
770
+ }
771
+ else if ( this.s.scrollInterval ) {
772
+ // Don't need to scroll - remove any existing timer
773
+ clearInterval( this.s.scrollInterval );
774
+ this.s.scrollInterval = null;
775
+ }
776
+
777
+ // If we need to run the interval to scroll and there is no existing
778
+ // interval (if there is an existing one, it will continue to run)
779
+ if ( ! this.s.scrollInterval && runInterval ) {
780
+ this.s.scrollInterval = setInterval( function () {
781
+ // Don't need to worry about setting scroll <0 or beyond the
782
+ // scroll bound as the browser will just reject that.
783
+ if ( scroll.windowVert ) {
784
+ document.body.scrollTop += scroll.windowVert;
785
+ }
786
+ if ( scroll.windowHoriz ) {
787
+ document.body.scrollLeft += scroll.windowHoriz;
788
+ }
789
+
790
+ // DataTables scrolling
791
+ if ( scroll.dtVert || scroll.dtHoriz ) {
792
+ var scroller = that.dom.dtScroll[0];
793
+
794
+ if ( scroll.dtVert ) {
795
+ scroller.scrollTop += scroll.dtVert;
796
+ }
797
+ if ( scroll.dtHoriz ) {
798
+ scroller.scrollLeft += scroll.dtHoriz;
799
+ }
800
+ }
801
+ }, 20 );
802
+ }
803
+ },
804
+
805
+
806
+ /**
807
+ * Update the DataTable after the user has selected what they want to do
808
+ *
809
+ * @param {false|undefined} result Return from the `execute` method - can
810
+ * be false internally to do nothing. This is not documented for plug-ins
811
+ * and is used only by the cancel option.
812
+ * @param {array} cells Information about the selected cells from the key
813
+ * up function, argumented with the set values
814
+ * @private
815
+ */
816
+ _update: function ( result, cells )
817
+ {
818
+ // Do nothing on `false` return from an execute function
819
+ if ( result === false ) {
820
+ return;
821
+ }
822
+
823
+ var dt = this.s.dt;
824
+ var cell;
825
+
826
+ // Potentially allow modifications to the cells matrix
827
+ this._emitEvent( 'preAutoFill', [ dt, cells ] );
828
+
829
+ this._editor( cells );
830
+
831
+ // Automatic updates are not performed if `update` is null and the
832
+ // `editor` parameter is passed in - the reason being that Editor will
833
+ // update the data once submitted
834
+ var update = this.c.update !== null ?
835
+ this.c.update :
836
+ this.c.editor ?
837
+ false :
838
+ true;
839
+
840
+ if ( update ) {
841
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
842
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
843
+ cell = cells[i][j];
844
+
845
+ cell.cell.data( cell.set );
846
+ }
847
+ }
848
+
849
+ dt.draw(false);
850
+ }
851
+
852
+ this._emitEvent( 'autoFill', [ dt, cells ] );
853
+ }
854
+ } );
855
+
856
+
857
+ /**
858
+ * AutoFill actions. The options here determine how AutoFill will fill the data
859
+ * in the table when the user has selected a range of cells. Please see the
860
+ * documentation on the DataTables site for full details on how to create plug-
861
+ * ins.
862
+ *
863
+ * @type {Object}
864
+ */
865
+ AutoFill.actions = {
866
+ increment: {
867
+ available: function ( dt, cells ) {
868
+ return $.isNumeric( cells[0][0].label );
869
+ },
870
+
871
+ option: function ( dt, cells ) {
872
+ return dt.i18n(
873
+ 'autoFill.increment',
874
+ 'Increment / decrement each cell by: <input type="number" value="1">'
875
+ );
876
+ },
877
+
878
+ execute: function ( dt, cells, node ) {
879
+ var value = cells[0][0].data * 1;
880
+ var increment = $('input', node).val() * 1;
881
+
882
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
883
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
884
+ cells[i][j].set = value;
885
+
886
+ value += increment;
887
+ }
888
+ }
889
+ }
890
+ },
891
+
892
+ fill: {
893
+ available: function ( dt, cells ) {
894
+ return true;
895
+ },
896
+
897
+ option: function ( dt, cells ) {
898
+ return dt.i18n('autoFill.fill', 'Fill all cells with <i>'+cells[0][0].label+'</i>' );
899
+ },
900
+
901
+ execute: function ( dt, cells, node ) {
902
+ var value = cells[0][0].data;
903
+
904
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
905
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
906
+ cells[i][j].set = value;
907
+ }
908
+ }
909
+ }
910
+ },
911
+
912
+ fillHorizontal: {
913
+ available: function ( dt, cells ) {
914
+ return cells.length > 1 && cells[0].length > 1;
915
+ },
916
+
917
+ option: function ( dt, cells ) {
918
+ return dt.i18n('autoFill.fillHorizontal', 'Fill cells horizontally' );
919
+ },
920
+
921
+ execute: function ( dt, cells, node ) {
922
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
923
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
924
+ cells[i][j].set = cells[i][0].data;
925
+ }
926
+ }
927
+ }
928
+ },
929
+
930
+ fillVertical: {
931
+ available: function ( dt, cells ) {
932
+ return cells.length > 1 && cells[0].length > 1;
933
+ },
934
+
935
+ option: function ( dt, cells ) {
936
+ return dt.i18n('autoFill.fillVertical', 'Fill cells vertically' );
937
+ },
938
+
939
+ execute: function ( dt, cells, node ) {
940
+ for ( var i=0, ien=cells.length ; i<ien ; i++ ) {
941
+ for ( var j=0, jen=cells[i].length ; j<jen ; j++ ) {
942
+ cells[i][j].set = cells[0][j].data;
943
+ }
944
+ }
945
+ }
946
+ },
947
+
948
+ // Special type that does not make itself available, but is added
949
+ // automatically by AutoFill if a multi-choice list is shown. This allows
950
+ // sensible code reuse
951
+ cancel: {
952
+ available: function () {
953
+ return false;
954
+ },
955
+
956
+ option: function ( dt ) {
957
+ return dt.i18n('autoFill.cancel', 'Cancel' );
958
+ },
959
+
960
+ execute: function () {
961
+ return false;
962
+ }
963
+ }
964
+ };
965
+
966
+
967
+ /**
968
+ * AutoFill version
969
+ *
970
+ * @static
971
+ * @type String
972
+ */
973
+ AutoFill.version = '2.1.2';
974
+
975
+
976
+ /**
977
+ * AutoFill defaults
978
+ *
979
+ * @namespace
980
+ */
981
+ AutoFill.defaults = {
982
+ /** @type {Boolean} Ask user what they want to do, even for a single option */
983
+ alwaysAsk: false,
984
+
985
+ /** @type {string|null} What will trigger a focus */
986
+ focus: null, // focus, click, hover
987
+
988
+ /** @type {column-selector} Columns to provide auto fill for */
989
+ columns: '', // all
990
+
991
+ /** @type {boolean|null} Update the cells after a drag */
992
+ update: null, // false is editor given, true otherwise
993
+
994
+ /** @type {DataTable.Editor} Editor instance for automatic submission */
995
+ editor: null
996
+ };
997
+
998
+
999
+ /**
1000
+ * Classes used by AutoFill that are configurable
1001
+ *
1002
+ * @namespace
1003
+ */
1004
+ AutoFill.classes = {
1005
+ /** @type {String} Class used by the selection button */
1006
+ btn: 'btn'
1007
+ };
1008
+
1009
+
1010
+ // Attach a listener to the document which listens for DataTables initialisation
1011
+ // events so we can automatically initialise
1012
+ $(document).on( 'preInit.dt.autofill', function (e, settings, json) {
1013
+ if ( e.namespace !== 'dt' ) {
1014
+ return;
1015
+ }
1016
+
1017
+ var init = settings.oInit.autoFill;
1018
+ var defaults = DataTable.defaults.autoFill;
1019
+
1020
+ if ( init || defaults ) {
1021
+ var opts = $.extend( {}, init, defaults );
1022
+
1023
+ if ( init !== false ) {
1024
+ new AutoFill( settings, opts );
1025
+ }
1026
+ }
1027
+ } );
1028
+
1029
+
1030
+ // Alias for access
1031
+ DataTable.AutoFill = AutoFill;
1032
+ DataTable.AutoFill = AutoFill;
1033
+
1034
+
1035
+ return AutoFill;
1036
+ }));