jquery-datatables 1.10.19.1 → 1.10.20

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/README.md +28 -1
  4. data/app/assets/javascripts/datatables/dataTables.uikit.js +2 -2
  5. data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +42 -29
  6. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap.js +1 -1
  7. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.bootstrap4.js +8 -2
  8. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +6 -3
  9. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.foundation.js +5 -4
  10. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +58 -6
  11. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +16 -5
  12. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.semanticui.js +1 -1
  13. data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +267 -152
  14. data/app/assets/javascripts/datatables/extensions/ColReorder/colReorder.foundation.js +1 -1
  15. data/app/assets/javascripts/datatables/extensions/ColReorder/dataTables.colReorder.js +121 -52
  16. data/app/assets/javascripts/datatables/extensions/FixedColumns/dataTables.fixedColumns.js +32 -5
  17. data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +166 -63
  18. data/app/assets/javascripts/datatables/extensions/KeyTable/keyTable.foundation.js +1 -1
  19. data/app/assets/javascripts/datatables/extensions/RowGroup/dataTables.rowGroup.js +105 -53
  20. data/app/assets/javascripts/datatables/extensions/RowGroup/rowGroup.foundation.js +1 -1
  21. data/app/assets/javascripts/datatables/extensions/RowGroup/{rowGroup.semanicui.js → rowGroup.semanticui.js} +0 -0
  22. data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +10 -9
  23. data/app/assets/javascripts/datatables/extensions/RowReorder/rowReorder.foundation.js +1 -1
  24. data/app/assets/javascripts/datatables/extensions/Scroller/dataTables.scroller.js +519 -636
  25. data/app/assets/javascripts/datatables/extensions/Scroller/scroller.foundation.js +1 -1
  26. data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +49 -18
  27. data/app/assets/javascripts/datatables/extensions/Select/select.foundation.js +1 -1
  28. data/app/assets/javascripts/datatables/jquery.dataTables.js +97 -60
  29. data/app/assets/javascripts/datatables/plugins/api/average.js +7 -6
  30. data/app/assets/javascripts/datatables/plugins/api/sum.js +7 -6
  31. data/app/assets/javascripts/datatables/plugins/pagination/ellipses.js +160 -0
  32. data/app/assets/javascripts/datatables/plugins/pagination/extjs.js +137 -0
  33. data/app/assets/javascripts/datatables/plugins/pagination/four_button.js +110 -0
  34. data/app/assets/javascripts/datatables/plugins/pagination/full_numbers_no_ellipses.js +59 -0
  35. data/app/assets/javascripts/datatables/plugins/pagination/input.js +22 -19
  36. data/app/assets/javascripts/datatables/plugins/pagination/scrolling.js +130 -0
  37. data/app/assets/javascripts/datatables/plugins/pagination/select.js +97 -0
  38. data/app/assets/javascripts/datatables/plugins/pagination/simple_incremental_bootstrap.js +154 -0
  39. data/app/assets/javascripts/datatables/plugins/pagination/simple_numbers_no_ellipses.js +59 -0
  40. data/app/assets/javascripts/datatables/plugins/search/dataTables.alphabetSearch.js +440 -399
  41. data/app/assets/javascripts/datatables/plugins/sorting/enum.js +51 -0
  42. data/app/assets/javascripts/datatables/plugins/type-detection/date-dd-MMM-yyyy.js +63 -0
  43. data/app/assets/javascripts/datatables/plugins/type-detection/date-de.js +125 -0
  44. data/app/assets/javascripts/datatables/plugins/type-detection/date-eu.js +64 -0
  45. data/app/assets/javascripts/datatables/plugins/type-detection/date-euro.js +48 -0
  46. data/app/assets/javascripts/datatables/plugins/type-detection/date-uk.js +35 -12
  47. data/app/assets/javascripts/datatables/plugins/type-detection/datetime-moment.js +74 -0
  48. data/app/assets/javascripts/datatables/plugins/type-detection/datetime-us.js +86 -0
  49. data/app/assets/javascripts/datatables/plugins/type-detection/file-size.js +37 -13
  50. data/app/assets/javascripts/datatables/plugins/type-detection/ip-address.js +113 -11
  51. data/app/assets/javascripts/datatables/plugins/type-detection/numString.js +63 -0
  52. data/app/assets/javascripts/datatables/plugins/type-detection/percent.js +34 -0
  53. data/app/assets/javascripts/datatables/plugins/type-detection/time-elapsed-dhms.js +42 -0
  54. data/app/assets/javascripts/datatables/plugins/type-detection/time.js +56 -0
  55. data/app/assets/javascripts/datatables/plugins/type-detection/title-numeric.js +40 -0
  56. data/app/assets/javascripts/datatables/plugins/type-detection/title-string.js +36 -0
  57. data/app/assets/stylesheets/datatables/extensions/AutoFill/autoFill.dataTables.scss +10 -3
  58. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap.scss +12 -3
  59. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.bootstrap4.scss +13 -6
  60. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.dataTables.scss +2 -0
  61. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.foundation.scss +5 -1
  62. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.jqueryui.scss +1 -0
  63. data/app/assets/stylesheets/datatables/extensions/Buttons/buttons.semanticui.scss +2 -1
  64. data/app/assets/stylesheets/datatables/extensions/Buttons/common.scss +10 -0
  65. data/app/assets/stylesheets/datatables/extensions/Buttons/mixins.scss +42 -30
  66. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.bootstrap.scss +11 -7
  67. data/app/assets/stylesheets/datatables/extensions/FixedColumns/fixedColumns.foundation.scss +1 -0
  68. data/app/assets/stylesheets/datatables/extensions/KeyTable/keyTable.dataTables.scss +13 -5
  69. data/app/assets/stylesheets/datatables/extensions/RowGroup/rowGroup.dataTables.scss +20 -2
  70. data/app/assets/stylesheets/datatables/extensions/Scroller/scroller.dataTables.scss +15 -2
  71. data/lib/jquery-datatables/version.rb +1 -1
  72. metadata +26 -12
  73. data/app/assets/javascripts/datatables/dataTables.bootstrap2.js +0 -162
  74. data/app/assets/javascripts/datatables/extensions/ColReorder/colReorder.semanicui.js +0 -38
  75. data/app/assets/javascripts/datatables/extensions/FixedColumns/fixedColumns.semanicui.js +0 -38
  76. data/app/assets/javascripts/datatables/extensions/FixedHeader/fixedHeader.semanicui.js +0 -38
  77. data/app/assets/javascripts/datatables/extensions/KeyTable/keyTable.semanicui.js +0 -38
  78. data/app/assets/javascripts/datatables/extensions/RowReorder/rowReorder.semanicui.js +0 -38
  79. data/app/assets/stylesheets/datatables/dataTables.bootstrap2.scss +0 -178
@@ -1,4 +1,4 @@
1
- /*! Bootstrap 4 styling wrapper for ColReorder
1
+ /*! Foundation styling wrapper for ColReorder
2
2
  * ©2018 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -1,15 +1,15 @@
1
- /*! ColReorder 1.5.1
2
- * ©2010-2018 SpryMedia Ltd - datatables.net/license
1
+ /*! ColReorder 1.5.2
2
+ * ©2010-2019 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary ColReorder
7
7
  * @description Provide the ability to reorder columns in a DataTable
8
- * @version 1.5.1
8
+ * @version 1.5.2
9
9
  * @file dataTables.colReorder.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2010-2018 SpryMedia Ltd.
12
+ * @copyright Copyright 2010-2019 SpryMedia Ltd.
13
13
  *
14
14
  * This source file is free software, available under the following license:
15
15
  * MIT license - http://datatables.net/license/mit
@@ -917,7 +917,7 @@ $.extend( ColReorder.prototype, {
917
917
  var that = this;
918
918
  $(nTh)
919
919
  .on( 'mousedown.ColReorder', function (e) {
920
- if ( that.s.enable ) {
920
+ if ( that.s.enable && e.which === 1 ) {
921
921
  that._fnMouseDown.call( that, e, nTh );
922
922
  }
923
923
  } )
@@ -1004,26 +1004,68 @@ $.extend( ColReorder.prototype, {
1004
1004
  } );
1005
1005
 
1006
1006
  /* Based on the current mouse position, calculate where the insert should go */
1007
- var bSet = false;
1007
+ var target;
1008
1008
  var lastToIndex = this.s.mouse.toIndex;
1009
+ var cursorXPosiotion = this._fnCursorPosition(e, 'pageX');
1010
+ var targetsPrev = function (i) {
1011
+ while (i >= 0) {
1012
+ i--;
1009
1013
 
1010
- for ( var i=1, iLen=this.s.aoTargets.length ; i<iLen ; i++ )
1011
- {
1012
- if ( this._fnCursorPosition(e, 'pageX') < this.s.aoTargets[i-1].x + ((this.s.aoTargets[i].x-this.s.aoTargets[i-1].x)/2) )
1013
- {
1014
- this.dom.pointer.css( 'left', this.s.aoTargets[i-1].x );
1015
- this.s.mouse.toIndex = this.s.aoTargets[i-1].to;
1016
- bSet = true;
1017
- break;
1014
+ if (i <= 0) {
1015
+ return null;
1016
+ }
1017
+
1018
+ if (that.s.aoTargets[i+1].x !== that.s.aoTargets[i].x) {
1019
+ return that.s.aoTargets[i];
1020
+ }
1021
+ }
1022
+ };
1023
+ var firstNotHidden = function () {
1024
+ for (var i=0 ; i<that.s.aoTargets.length-1 ; i++) {
1025
+ if (that.s.aoTargets[i].x !== that.s.aoTargets[i+1].x) {
1026
+ return that.s.aoTargets[i];
1027
+ }
1018
1028
  }
1029
+ };
1030
+ var lastNotHidden = function () {
1031
+ for (var i=that.s.aoTargets.length-1 ; i>0 ; i--) {
1032
+ if (that.s.aoTargets[i].x !== that.s.aoTargets[i-1].x) {
1033
+ return that.s.aoTargets[i];
1034
+ }
1035
+ }
1036
+ };
1037
+
1038
+ for (var i = 1; i < this.s.aoTargets.length; i++) {
1039
+ var prevTarget = targetsPrev(i);
1040
+ if (! prevTarget) {
1041
+ prevTarget = firstNotHidden();
1042
+ }
1043
+
1044
+ var prevTargetMiddle = prevTarget.x + (this.s.aoTargets[i].x - prevTarget.x) / 2;
1045
+
1046
+ if (this._fnIsLtr()) {
1047
+ if (cursorXPosiotion < prevTargetMiddle ) {
1048
+ target = prevTarget;
1049
+ break;
1050
+ }
1051
+ }
1052
+ else {
1053
+ if (cursorXPosiotion > prevTargetMiddle) {
1054
+ target = prevTarget;
1055
+ break;
1056
+ }
1057
+ }
1019
1058
  }
1020
1059
 
1021
- // The insert element wasn't positioned in the array (less than
1022
- // operator), so we put it at the end
1023
- if ( !bSet )
1024
- {
1025
- this.dom.pointer.css( 'left', this.s.aoTargets[this.s.aoTargets.length-1].x );
1026
- this.s.mouse.toIndex = this.s.aoTargets[this.s.aoTargets.length-1].to;
1060
+ if (target) {
1061
+ this.dom.pointer.css('left', target.x);
1062
+ this.s.mouse.toIndex = target.to;
1063
+ }
1064
+ else {
1065
+ // The insert element wasn't positioned in the array (less than
1066
+ // operator), so we put it at the end
1067
+ this.dom.pointer.css( 'left', lastNotHidden().x );
1068
+ this.s.mouse.toIndex = lastNotHidden().to;
1027
1069
  }
1028
1070
 
1029
1071
  // Perform reordering if realtime updating is on and the column has moved
@@ -1094,38 +1136,60 @@ $.extend( ColReorder.prototype, {
1094
1136
  "_fnRegions": function ()
1095
1137
  {
1096
1138
  var aoColumns = this.s.dt.aoColumns;
1097
-
1098
- this.s.aoTargets.splice( 0, this.s.aoTargets.length );
1099
-
1100
- this.s.aoTargets.push( {
1101
- "x": $(this.s.dt.nTable).offset().left,
1102
- "to": 0
1103
- } );
1104
-
1105
- var iToPoint = 0;
1106
- var total = this.s.aoTargets[0].x;
1107
-
1108
- for ( var i=0, iLen=aoColumns.length ; i<iLen ; i++ )
1109
- {
1110
- /* For the column / header in question, we want it's position to remain the same if the
1111
- * position is just to it's immediate left or right, so we only increment the counter for
1112
- * other columns
1113
- */
1114
- if ( i != this.s.mouse.fromIndex )
1115
- {
1116
- iToPoint++;
1139
+ var isLTR = this._fnIsLtr();
1140
+ this.s.aoTargets.splice(0, this.s.aoTargets.length);
1141
+ var lastBound = $(this.s.dt.nTable).offset().left;
1142
+
1143
+ var aoColumnBounds = [];
1144
+ $.each(aoColumns, function (i, column) {
1145
+ if (column.bVisible && column.nTh.style.display !== 'none') {
1146
+ var nth = $(column.nTh);
1147
+ var bound = nth.offset().left;
1148
+
1149
+ if (isLTR) {
1150
+ bound += nth.outerWidth();
1151
+ }
1152
+
1153
+ aoColumnBounds.push({
1154
+ index: i,
1155
+ bound: bound
1156
+ });
1157
+
1158
+ lastBound = bound;
1117
1159
  }
1118
-
1119
- if ( aoColumns[i].bVisible && aoColumns[i].nTh.style.display !=='none' )
1120
- {
1121
- total += $(aoColumns[i].nTh).outerWidth();
1122
-
1123
- this.s.aoTargets.push( {
1124
- "x": total,
1125
- "to": iToPoint
1126
- } );
1160
+ else {
1161
+ aoColumnBounds.push({
1162
+ index: i,
1163
+ bound: lastBound
1164
+ });
1127
1165
  }
1128
- }
1166
+ });
1167
+
1168
+ var firstColumn = aoColumnBounds[0];
1169
+ var firstColumnWidth = $(aoColumns[firstColumn.index].nTh).outerWidth();
1170
+
1171
+ this.s.aoTargets.push({
1172
+ to: 0,
1173
+ x: firstColumn.bound - firstColumnWidth
1174
+ });
1175
+
1176
+ for (var i = 0; i < aoColumnBounds.length; i++) {
1177
+ var columnBound = aoColumnBounds[i];
1178
+ var iToPoint = columnBound.index;
1179
+
1180
+ /* For the column / header in question, we want it's position to remain the same if the
1181
+ * position is just to it's immediate left or right, so we only increment the counter for
1182
+ * other columns
1183
+ */
1184
+ if (columnBound.index < this.s.mouse.fromIndex) {
1185
+ iToPoint++;
1186
+ }
1187
+
1188
+ this.s.aoTargets.push({
1189
+ to: iToPoint,
1190
+ x: columnBound.bound
1191
+ });
1192
+ }
1129
1193
 
1130
1194
  /* Disallow columns for being reordered by drag and drop, counting right to left */
1131
1195
  if ( this.s.fixedRight !== 0 )
@@ -1219,7 +1283,11 @@ $.extend( ColReorder.prototype, {
1219
1283
  return e.originalEvent.touches[0][ prop ];
1220
1284
  }
1221
1285
  return e[ prop ];
1222
- }
1286
+ },
1287
+
1288
+ _fnIsLtr: function () {
1289
+ return $(this.s.dt.nTable).css('direction') !== "rtl";
1290
+ }
1223
1291
  } );
1224
1292
 
1225
1293
 
@@ -1306,7 +1374,7 @@ ColReorder.defaults = {
1306
1374
  * @type String
1307
1375
  * @default As code
1308
1376
  */
1309
- ColReorder.version = "1.5.1";
1377
+ ColReorder.version = "1.5.2";
1310
1378
 
1311
1379
 
1312
1380
 
@@ -1397,6 +1465,7 @@ $.fn.dataTable.Api.register( 'colReorder.transpose()', function ( idx, dir ) {
1397
1465
  $.fn.dataTable.Api.register( 'colReorder.move()', function( from, to, drop, invalidateRows ) {
1398
1466
  if (this.context.length) {
1399
1467
  this.context[0]._colReorder.s.dt.oInstance.fnColReorder( from, to, drop, invalidateRows );
1468
+ this.context[0]._colReorder._fnSetColumnIndexes();
1400
1469
  }
1401
1470
  return this;
1402
1471
  } );
@@ -1,11 +1,11 @@
1
- /*! FixedColumns 3.2.6
1
+ /*! FixedColumns 3.3.0
2
2
  * ©2010-2018 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary FixedColumns
7
7
  * @description Freeze columns in place on a scrolling DataTable
8
- * @version 3.2.6
8
+ * @version 3.3.0
9
9
  * @file dataTables.fixedColumns.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
@@ -449,6 +449,25 @@ $.extend( FixedColumns.prototype , {
449
449
  }
450
450
  },
451
451
 
452
+ fnToFixedNode: function ( rowIdx, colIdx )
453
+ {
454
+ var found;
455
+
456
+ if ( colIdx < this.s.iLeftColumns ) {
457
+ found = $(this.dom.clone.left.body).find('[data-dt-row='+rowIdx+'][data-dt-column='+colIdx+']');
458
+ }
459
+ else if ( colIdx >= this.s.iRightColumns ) {
460
+ found = $(this.dom.clone.right.body).find('[data-dt-row='+rowIdx+'][data-dt-column='+colIdx+']');
461
+ }
462
+
463
+ if ( found && found.length ) {
464
+ return found[0];
465
+ }
466
+
467
+ // Fallback - non-fixed node
468
+ var table = new $.fn.dataTable.Api(this.s.dt);
469
+ return table.cell(rowIdx, colIdx).node();
470
+ },
452
471
 
453
472
 
454
473
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -735,7 +754,7 @@ $.extend( FixedColumns.prototype , {
735
754
  $('<div class="DTFC_ScrollWrapper" style="position:relative; clear:both;">'+
736
755
  '<div class="DTFC_LeftWrapper" style="position:absolute; top:0; left:0;" aria-hidden="true">'+
737
756
  '<div class="DTFC_LeftHeadWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
738
- '<div class="DTFC_LeftBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
757
+ '<div class="DTFC_LeftBodyWrapper" style="position:relative; top:0; left:0; height:0; overflow:hidden;">'+
739
758
  '<div class="DTFC_LeftBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
740
759
  '</div>'+
741
760
  '<div class="DTFC_LeftFootWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
@@ -744,7 +763,7 @@ $.extend( FixedColumns.prototype , {
744
763
  '<div class="DTFC_RightHeadWrapper" style="position:relative; top:0; left:0;">'+
745
764
  '<div class="DTFC_RightHeadBlocker DTFC_Blocker" style="position:absolute; top:0; bottom:0;"></div>'+
746
765
  '</div>'+
747
- '<div class="DTFC_RightBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
766
+ '<div class="DTFC_RightBodyWrapper" style="position:relative; top:0; left:0; height:0; overflow:hidden;">'+
748
767
  '<div class="DTFC_RightBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
749
768
  '</div>'+
750
769
  '<div class="DTFC_RightFootWrapper" style="position:relative; top:0; left:0;">'+
@@ -1525,7 +1544,7 @@ FixedColumns.defaults = /** @lends FixedColumns.defaults */{
1525
1544
  * @default See code
1526
1545
  * @static
1527
1546
  */
1528
- FixedColumns.version = "3.2.6";
1547
+ FixedColumns.version = "3.3.0";
1529
1548
 
1530
1549
 
1531
1550
 
@@ -1596,6 +1615,14 @@ DataTable.Api.register( 'fixedColumns().cellIndex()', function ( cell ) {
1596
1615
  }
1597
1616
  } );
1598
1617
 
1618
+ DataTable.Api.registerPlural( 'cells().fixedNodes()', 'cell().fixedNode()', function () {
1619
+ return this.iterator( 'cell', function ( settings, row, column ) {
1620
+ return settings._oFixedColumns
1621
+ ? settings._oFixedColumns.fnToFixedNode( row, column )
1622
+ : this.node();
1623
+ }, 1 );
1624
+ } );
1625
+
1599
1626
 
1600
1627
 
1601
1628
 
@@ -1,15 +1,15 @@
1
- /*! KeyTable 2.4.1
2
- * ©2009-2018 SpryMedia Ltd - datatables.net/license
1
+ /*! KeyTable 2.5.1
2
+ * ©2009-2019 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary KeyTable
7
7
  * @description Spreadsheet like keyboard navigation for DataTables
8
- * @version 2.4.1
8
+ * @version 2.5.1
9
9
  * @file dataTables.keyTable.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2009-2018 SpryMedia Ltd.
12
+ * @copyright Copyright 2009-2019 SpryMedia Ltd.
13
13
  *
14
14
  * This source file is free software, available under the following license:
15
15
  * MIT license - http://datatables.net/license/mit
@@ -49,6 +49,7 @@
49
49
  }(function( $, window, document, undefined ) {
50
50
  'use strict';
51
51
  var DataTable = $.fn.dataTable;
52
+ var namespaceCounter = 0;
52
53
 
53
54
 
54
55
  var KeyTable = function ( dt, opts ) {
@@ -80,7 +81,10 @@ var KeyTable = function ( dt, opts ) {
80
81
  waitingForDraw: false,
81
82
 
82
83
  /** @type {object} Information about the last cell that was focused */
83
- lastFocus: null
84
+ lastFocus: null,
85
+
86
+ /** @type {string} Unique namespace per instance */
87
+ namespace: '.keyTable-'+(namespaceCounter++)
84
88
  };
85
89
 
86
90
  // DOM items
@@ -167,6 +171,8 @@ $.extend( KeyTable.prototype, {
167
171
  var that = this;
168
172
  var dt = this.s.dt;
169
173
  var table = $( dt.table().node() );
174
+ var namespace = this.s.namespace;
175
+ var editorBlock = false;
170
176
 
171
177
  // Need to be able to calculate the cell positions relative to the table
172
178
  if ( table.css('position') === 'static' ) {
@@ -174,7 +180,7 @@ $.extend( KeyTable.prototype, {
174
180
  }
175
181
 
176
182
  // Click to focus
177
- $( dt.table().body() ).on( 'click.keyTable', 'th, td', function (e) {
183
+ $( dt.table().body() ).on( 'click'+namespace, 'th, td', function (e) {
178
184
  if ( that.s.enable === false ) {
179
185
  return;
180
186
  }
@@ -189,13 +195,15 @@ $.extend( KeyTable.prototype, {
189
195
  } );
190
196
 
191
197
  // Key events
192
- $( document ).on( 'keydown.keyTable', function (e) {
193
- that._key( e );
198
+ $( document ).on( 'keydown'+namespace, function (e) {
199
+ if ( ! editorBlock ) {
200
+ that._key( e );
201
+ }
194
202
  } );
195
203
 
196
204
  // Click blur
197
205
  if ( this.c.blurable ) {
198
- $( document ).on( 'mousedown.keyTable', function ( e ) {
206
+ $( document ).on( 'mousedown'+namespace, function ( e ) {
199
207
  // Click on the search input will blur focus
200
208
  if ( $(e.target).parents( '.dataTables_filter' ).length ) {
201
209
  that._blur();
@@ -233,28 +241,56 @@ $.extend( KeyTable.prototype, {
233
241
  if ( mode !== 'inline' && that.s.enable ) {
234
242
  that.enable( false );
235
243
 
236
- editor.one( 'close.keyTable', function () {
244
+ editor.one( 'close'+namespace, function () {
237
245
  that.enable( true );
238
246
  } );
239
247
  }
240
248
  } );
241
249
 
242
250
  if ( this.c.editOnFocus ) {
243
- dt.on( 'key-focus.keyTable key-refocus.keyTable', function ( e, dt, cell, orig ) {
244
- that._editor( null, orig );
251
+ dt.on( 'key-focus'+namespace+' key-refocus'+namespace, function ( e, dt, cell, orig ) {
252
+ that._editor( null, orig, true );
245
253
  } );
246
254
  }
247
255
 
248
256
  // Activate Editor when a key is pressed (will be ignored, if
249
257
  // already active).
250
- dt.on( 'key.keyTable', function ( e, dt, key, cell, orig ) {
251
- that._editor( key, orig );
258
+ dt.on( 'key'+namespace, function ( e, dt, key, cell, orig ) {
259
+ that._editor( key, orig, false );
252
260
  } );
261
+
262
+ // Active editing on double click - it will already have focus from
263
+ // the click event handler above
264
+ $( dt.table().body() ).on( 'dblclick'+namespace, 'th, td', function (e) {
265
+ if ( that.s.enable === false ) {
266
+ return;
267
+ }
268
+
269
+ var cell = dt.cell( this );
270
+
271
+ if ( ! cell.any() ) {
272
+ return;
273
+ }
274
+
275
+ that._editor( null, e, true );
276
+ } );
277
+
278
+ // While Editor is busy processing, we don't want to process any key events
279
+ editor
280
+ .on('preSubmit', function () {
281
+ editorBlock = true;
282
+ } )
283
+ .on('preSubmitCancelled', function () {
284
+ editorBlock = false;
285
+ } )
286
+ .on('submitComplete', function () {
287
+ editorBlock = false;
288
+ } );
253
289
  }
254
290
 
255
291
  // Stave saving
256
292
  if ( dt.settings()[0].oFeatures.bStateSave ) {
257
- dt.on( 'stateSaveParams.keyTable', function (e, s, d) {
293
+ dt.on( 'stateSaveParams'+namespace, function (e, s, d) {
258
294
  d.keyTable = that.s.lastFocus ?
259
295
  that.s.lastFocus.cell.index() :
260
296
  null;
@@ -262,7 +298,7 @@ $.extend( KeyTable.prototype, {
262
298
  }
263
299
 
264
300
  // Redraw - retain focus on the current cell
265
- dt.on( 'draw.keyTable', function (e) {
301
+ dt.on( 'draw'+namespace, function (e) {
266
302
  if ( that.s.focusDraw ) {
267
303
  return;
268
304
  }
@@ -292,14 +328,21 @@ $.extend( KeyTable.prototype, {
292
328
  this._clipboard();
293
329
  }
294
330
 
295
- dt.on( 'destroy.keyTable', function () {
296
- dt.off( '.keyTable' );
297
- $( dt.table().body() ).off( 'click.keyTable', 'th, td' );
331
+ dt.on( 'destroy'+namespace, function () {
332
+ that._blur( true );
333
+
334
+ // Event tidy up
335
+ dt.off( namespace );
336
+
337
+ $( dt.table().body() )
338
+ .off( 'click'+namespace, 'th, td' )
339
+ .off( 'dblclick'+namespace, 'th, td' );
340
+
298
341
  $( document )
299
- .off( 'keydown.keyTable' )
300
- .off( 'click.keyTable' )
301
- .off( 'copy.keyTable' )
302
- .off( 'paste.keyTable' );
342
+ .off( 'mousedown'+namespace )
343
+ .off( 'keydown'+namespace )
344
+ .off( 'copy'+namespace )
345
+ .off( 'paste'+namespace );
303
346
  } );
304
347
 
305
348
  // Initial focus comes from state or options
@@ -329,9 +372,10 @@ $.extend( KeyTable.prototype, {
329
372
  /**
330
373
  * Blur the control
331
374
  *
375
+ * @param {boolean} [noEvents=false] Don't trigger updates / events (for destroying)
332
376
  * @private
333
377
  */
334
- _blur: function ()
378
+ _blur: function (noEvents)
335
379
  {
336
380
  if ( ! this.s.enable || ! this.s.lastFocus ) {
337
381
  return;
@@ -342,9 +386,11 @@ $.extend( KeyTable.prototype, {
342
386
  $( cell.node() ).removeClass( this.c.className );
343
387
  this.s.lastFocus = null;
344
388
 
345
- this._updateFixedColumns(cell.index().column);
389
+ if ( ! noEvents ) {
390
+ this._updateFixedColumns(cell.index().column);
346
391
 
347
- this._emitEvent( 'key-blur', [ this.s.dt, cell ] );
392
+ this._emitEvent( 'key-blur', [ this.s.dt, cell ] );
393
+ }
348
394
  },
349
395
 
350
396
 
@@ -356,13 +402,14 @@ $.extend( KeyTable.prototype, {
356
402
  _clipboard: function () {
357
403
  var dt = this.s.dt;
358
404
  var that = this;
405
+ var namespace = this.s.namespace;
359
406
 
360
407
  // IE8 doesn't support getting selected text
361
408
  if ( ! window.getSelection ) {
362
409
  return;
363
410
  }
364
411
 
365
- $(document).on( 'copy.keyTable', function (ejq) {
412
+ $(document).on( 'copy'+namespace, function (ejq) {
366
413
  var e = ejq.originalEvent;
367
414
  var selection = window.getSelection().toString();
368
415
  var focused = that.s.lastFocus;
@@ -378,7 +425,7 @@ $.extend( KeyTable.prototype, {
378
425
  }
379
426
  } );
380
427
 
381
- $(document).on( 'paste.keyTable', function (ejq) {
428
+ $(document).on( 'paste'+namespace, function (ejq) {
382
429
  var e = ejq.originalEvent;
383
430
  var focused = that.s.lastFocus;
384
431
  var activeEl = document.activeElement;
@@ -445,26 +492,28 @@ $.extend( KeyTable.prototype, {
445
492
  * @param {object} orig Original event
446
493
  * @private
447
494
  */
448
- _editor: function ( key, orig )
495
+ _editor: function ( key, orig, hardEdit )
449
496
  {
450
497
  var that = this;
451
498
  var dt = this.s.dt;
452
499
  var editor = this.c.editor;
500
+ var editCell = this.s.lastFocus.cell;
501
+ var namespace = this.s.namespace;
453
502
 
454
503
  // Do nothing if there is already an inline edit in this cell
455
- if ( $('div.DTE', this.s.lastFocus.cell.node()).length ) {
504
+ if ( $('div.DTE', editCell.node()).length ) {
456
505
  return;
457
506
  }
458
507
 
459
508
  // Don't activate Editor on control key presses
460
- if (
509
+ if ( key !== null && (
461
510
  (key >= 0x00 && key <= 0x09) ||
462
511
  key === 0x0b ||
463
512
  key === 0x0c ||
464
513
  (key >= 0x0e && key <= 0x1f) ||
465
514
  (key >= 0x70 && key <= 0x7b) ||
466
515
  (key >= 0x7f && key <= 0x9f)
467
- ) {
516
+ ) ) {
468
517
  return;
469
518
  }
470
519
 
@@ -478,43 +527,63 @@ $.extend( KeyTable.prototype, {
478
527
 
479
528
  var editInline = function () {
480
529
  editor
481
- .one( 'open.keyTable', function () {
530
+ .one( 'open'+namespace, function () {
482
531
  // Remove cancel open
483
- editor.off( 'cancelOpen.keyTable' );
532
+ editor.off( 'cancelOpen'+namespace );
484
533
 
485
534
  // Excel style - select all text
486
- if ( that.c.editAutoSelect ) {
535
+ if ( ! hardEdit ) {
487
536
  $('div.DTE_Field_InputControl input, div.DTE_Field_InputControl textarea').select();
488
537
  }
489
538
 
490
539
  // Reduce the keys the Keys listens for
491
- dt.keys.enable( that.c.editorKeys );
540
+ dt.keys.enable( hardEdit ? 'tab-only' : 'navigation-only' );
492
541
 
493
542
  // On blur of the navigation submit
494
- dt.one( 'key-blur.editor', function () {
495
- if ( editor.displayed() ) {
543
+ dt.on( 'key-blur.editor', function (e, dt, cell) {
544
+ if ( editor.displayed() && cell.node() === editCell.node() ) {
496
545
  editor.submit();
497
546
  }
498
547
  } );
499
548
 
549
+ // Highlight the cell a different colour on full edit
550
+ if ( hardEdit ) {
551
+ $( dt.table().container() ).addClass('dtk-focus-alt');
552
+ }
553
+
554
+ // If the dev cancels the submit, we need to return focus
555
+ editor.on( 'preSubmitCancelled'+namespace, function () {
556
+ setTimeout( function () {
557
+ that._focus( editCell, null, false );
558
+ }, 50 );
559
+ } );
560
+
561
+ editor.on( 'submitUnsuccessful'+namespace, function () {
562
+ that._focus( editCell, null, false );
563
+ } );
564
+
500
565
  // Restore full key navigation on close
501
566
  editor.one( 'close', function () {
502
567
  dt.keys.enable( true );
503
568
  dt.off( 'key-blur.editor' );
569
+ editor.off( namespace );
570
+ $( dt.table().container() ).removeClass('dtk-focus-alt');
504
571
  } );
505
572
  } )
506
- .one( 'cancelOpen.keyTable', function () {
573
+ .one( 'cancelOpen'+namespace, function () {
507
574
  // `preOpen` can cancel the display of the form, so it
508
575
  // might be that the open event handler isn't needed
509
- editor.off( 'open.keyTable' );
576
+ editor.off( namespace );
510
577
  } )
511
- .inline( that.s.lastFocus.cell.index() );
578
+ .inline( editCell.index() );
512
579
  };
513
580
 
514
581
  // Editor 1.7 listens for `return` on keyup, so if return is the trigger
515
582
  // key, we need to wait for `keyup` otherwise Editor would just submit
516
583
  // the content triggered by this keypress.
517
584
  if ( key === 13 ) {
585
+ hardEdit = true;
586
+
518
587
  $(document).one( 'keyup', function () { // immediately removed
519
588
  editInline();
520
589
  } );
@@ -580,6 +649,11 @@ $.extend( KeyTable.prototype, {
580
649
  .rows( { filter: 'applied', order: 'applied' } )
581
650
  .indexes()
582
651
  .indexOf( index.row );
652
+
653
+ // Don't focus rows that were filtered out.
654
+ if ( row < 0 ) {
655
+ return;
656
+ }
583
657
 
584
658
  // For server-side processing normalise the row by adding the start
585
659
  // point, since `rows().indexes()` includes only rows that are
@@ -634,6 +708,9 @@ $.extend( KeyTable.prototype, {
634
708
  this._blur();
635
709
  }
636
710
 
711
+ // Clear focus from other tables
712
+ this._removeOtherFocus();
713
+
637
714
  var node = $( cell.node() );
638
715
  node.addClass( this.c.className );
639
716
 
@@ -697,6 +774,12 @@ $.extend( KeyTable.prototype, {
697
774
  return;
698
775
  }
699
776
 
777
+ // And the last focus still exists!
778
+ if ( ! this.s.dt.cell(lastFocus.node).any() ) {
779
+ this.s.lastFocus = null;
780
+ return;
781
+ }
782
+
700
783
  var that = this;
701
784
  var dt = this.s.dt;
702
785
  var scrolling = this.s.dt.settings()[0].oScroll.sY ? true : false;
@@ -766,6 +849,13 @@ $.extend( KeyTable.prototype, {
766
849
  }
767
850
  break;
768
851
 
852
+ case 113: // F2 - Excel like hard edit
853
+ if ( this.c.editor ) {
854
+ this._editor(null, e, true);
855
+ break;
856
+ }
857
+ // else fallthrough
858
+
769
859
  default:
770
860
  // Everything else - pass through only when fully enabled
771
861
  if ( enable === true ) {
@@ -775,6 +865,19 @@ $.extend( KeyTable.prototype, {
775
865
  }
776
866
  },
777
867
 
868
+ /**
869
+ * Remove focus from all tables other than this one
870
+ */
871
+ _removeOtherFocus: function ()
872
+ {
873
+ var thisTable = this.s.dt.table().node();
874
+
875
+ $.fn.dataTable.tables({api:true}).iterator('table', function (settings) {
876
+ if (this.table().node() !== thisTable) {
877
+ this.cell.blur();
878
+ }
879
+ });
880
+ },
778
881
 
779
882
  /**
780
883
  * Scroll a container to make a cell visible in it. This can be used for
@@ -896,16 +999,19 @@ $.extend( KeyTable.prototype, {
896
999
  row++;
897
1000
  }
898
1001
 
899
- if ( row >= 0 && row < rows && $.inArray( column, columns ) !== -1
900
- ) {
901
- e.preventDefault();
1002
+ if ( row >= 0 && row < rows && $.inArray( column, columns ) !== -1 ) {
1003
+ if (e) {
1004
+ e.preventDefault();
1005
+ }
902
1006
 
903
1007
  this._focus( row, column, true, e );
904
1008
  }
905
1009
  else if ( ! keyBlurable || ! this.c.blurable ) {
906
1010
  // No new focus, but if the table isn't blurable, then don't loose
907
1011
  // focus
908
- e.preventDefault();
1012
+ if (e) {
1013
+ e.preventDefault();
1014
+ }
909
1015
  }
910
1016
  else {
911
1017
  this._blur();
@@ -941,8 +1047,10 @@ $.extend( KeyTable.prototype, {
941
1047
  .insertBefore( dt.table().node() );
942
1048
 
943
1049
  div.children().on( 'focus', function (e) {
944
- if ( dt.cell(':eq(0)', {page: 'current'}).any() ) {
945
- that._focus( dt.cell(':eq(0)', '0:visible', {page: 'current'}), null, true, e );
1050
+ var cell = dt.cell(':eq(0)', that._columns(), {page: 'current'});
1051
+
1052
+ if ( cell.any() ) {
1053
+ that._focus( cell, null, true, e );
946
1054
  }
947
1055
  } );
948
1056
  },
@@ -1016,21 +1124,8 @@ KeyTable.defaults = {
1016
1124
  editor: null,
1017
1125
 
1018
1126
  /**
1019
- * Option that defines what KeyTable's behaviour will be when used with
1020
- * Editor's inline editing. Can be `navigation-only` or `tab-only`.
1021
- * @type {String}
1022
- */
1023
- editorKeys: 'navigation-only',
1024
-
1025
- /**
1026
- * Set if Editor should automatically select the text in the input
1027
- * @type {Boolean}
1028
- */
1029
- editAutoSelect: true,
1030
-
1031
- /**
1032
- * Control if editing should be activated immediately upon focus
1033
- * @type {Boolean}
1127
+ * Trigger editing immediately on focus
1128
+ * @type {boolean}
1034
1129
  */
1035
1130
  editOnFocus: false,
1036
1131
 
@@ -1056,7 +1151,7 @@ KeyTable.defaults = {
1056
1151
 
1057
1152
 
1058
1153
 
1059
- KeyTable.version = "2.4.1";
1154
+ KeyTable.version = "2.5.1";
1060
1155
 
1061
1156
 
1062
1157
  $.fn.dataTable.KeyTable = KeyTable;
@@ -1095,6 +1190,14 @@ DataTable.Api.register( 'keys.enable()', function ( opts ) {
1095
1190
  } );
1096
1191
  } );
1097
1192
 
1193
+ DataTable.Api.register( 'keys.move()', function ( dir ) {
1194
+ return this.iterator( 'table', function (ctx) {
1195
+ if ( ctx.keytable ) {
1196
+ ctx.keytable._shift( null, dir, false );
1197
+ }
1198
+ } );
1199
+ } );
1200
+
1098
1201
  // Cell selector
1099
1202
  DataTable.ext.selector.cell.push( function ( settings, opts, cells ) {
1100
1203
  var focused = opts.focused;