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,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
+ }));