jquery-datatables 1.10.19.1 → 1.10.20

Sign up to get free protection for your applications and to get access to all the features.
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;