jquery-datatables 1.10.12 → 1.10.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/app/assets/javascripts/datatables/dataTables.bootstrap.js +2 -2
  4. data/app/assets/javascripts/datatables/dataTables.bootstrap4.js +5 -5
  5. data/app/assets/javascripts/datatables/dataTables.foundation.js +1 -1
  6. data/app/assets/javascripts/datatables/dataTables.material.js +1 -1
  7. data/app/assets/javascripts/datatables/dataTables.semanticui.js +1 -1
  8. data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +63 -31
  9. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +2 -3
  10. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.flash.js +145 -55
  11. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +224 -206
  12. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +14 -8
  13. data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +54 -24
  14. data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +137 -68
  15. data/app/assets/javascripts/datatables/extensions/Responsive/dataTables.responsive.js +30 -7
  16. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap.js +6 -2
  17. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap4.js +6 -2
  18. data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +64 -6
  19. data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +40 -15
  20. data/app/assets/javascripts/datatables/jquery.dataTables.js +246 -217
  21. data/app/assets/javascripts/datatables/plugins/api/average.js +32 -0
  22. data/app/assets/javascripts/datatables/plugins/api/sum.js +51 -0
  23. data/app/assets/javascripts/datatables/plugins/pagination/input.js +224 -0
  24. data/app/assets/javascripts/datatables/plugins/search/alphabetSearch.js +368 -0
  25. data/app/assets/javascripts/datatables/plugins/sorting/file-size.js +43 -0
  26. data/app/assets/javascripts/datatables/plugins/sorting/ip-address.js +103 -0
  27. data/app/assets/stylesheets/datatables/dataTables.bootstrap.css +0 -1
  28. data/app/assets/stylesheets/datatables/dataTables.semanticui.css +0 -1
  29. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap.css +4 -4
  30. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap4.css +4 -4
  31. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.dataTables.css +4 -4
  32. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.foundation.css +4 -4
  33. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.jqueryui.css +4 -4
  34. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.semanticui.css +4 -4
  35. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap.css +9 -4
  36. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap4.css +9 -4
  37. data/app/assets/stylesheets/datatables/extensions/Select/select.dataTables.css +9 -4
  38. data/app/assets/stylesheets/datatables/extensions/Select/select.foundation.css +9 -4
  39. data/app/assets/stylesheets/datatables/extensions/Select/select.jqueryui.css +9 -4
  40. data/app/assets/stylesheets/datatables/extensions/Select/select.semanticui.css +9 -4
  41. data/app/assets/stylesheets/datatables/plugins/search/alphabetSearch.css +43 -0
  42. data/lib/jquery-datatables/version.rb +1 -1
  43. metadata +10 -3
@@ -126,19 +126,25 @@ DataTable.ext.buttons.print = {
126
126
  head += _relToAbs( this );
127
127
  } );
128
128
 
129
- //$(win.document.head).html( head );
130
- win.document.head.innerHTML = head; // Work around for Edge
129
+ try {
130
+ win.document.head.innerHTML = head; // Work around for Edge
131
+ }
132
+ catch (e) {
133
+ $(win.document.head).html( head ); // Old IE
134
+ }
131
135
 
132
136
  // Inject the table and other surrounding information
133
137
  win.document.body.innerHTML =
134
138
  '<h1>'+title+'</h1>'+
135
- '<div>'+config.message+'</div>'+
139
+ '<div>'+
140
+ (typeof config.message === 'function' ?
141
+ config.message( dt, button, config ) :
142
+ config.message
143
+ )+
144
+ '</div>'+
136
145
  html;
137
- // $(win.document.body).html(
138
- // '<h1>'+title+'</h1>'+
139
- // '<div>'+config.message+'</div>'+
140
- // html
141
- // );
146
+
147
+ $(win.document.body).addClass('dt-print-view');
142
148
 
143
149
  if ( config.customize ) {
144
150
  config.customize( win );
@@ -1,4 +1,4 @@
1
- /*! Buttons for DataTables 1.2.0
1
+ /*! Buttons for DataTables 1.2.3
2
2
  * ©2016 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
@@ -191,8 +191,8 @@ $.extend( Buttons.prototype, {
191
191
  $('body').off( 'keyup.'+this.s.namespace );
192
192
 
193
193
  // Individual button destroy (so they can remove their own events if
194
- // needed
195
- var buttons = this.s.buttons;
194
+ // needed). Take a copy as the array is modified by `remove`
195
+ var buttons = this.s.buttons.slice();
196
196
  var i, ien;
197
197
 
198
198
  for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
@@ -879,7 +879,9 @@ Buttons.background = function ( show, className, fade ) {
879
879
  else {
880
880
  $('body > div.'+className)
881
881
  .fadeOut( fade, function () {
882
- $(this).remove();
882
+ $(this)
883
+ .removeClass( className )
884
+ .remove();
883
885
  } );
884
886
  }
885
887
  };
@@ -1116,7 +1118,7 @@ Buttons.defaults = {
1116
1118
  * @type {string}
1117
1119
  * @static
1118
1120
  */
1119
- Buttons.version = '1.2.0';
1121
+ Buttons.version = '1.2.3';
1120
1122
 
1121
1123
 
1122
1124
  $.extend( _dtButtons, {
@@ -1133,7 +1135,7 @@ $.extend( _dtButtons, {
1133
1135
 
1134
1136
  // Remove any old collection
1135
1137
  if ( $('div.dt-button-background').length ) {
1136
- multiLevel = $('div.dt-button-collection').offset();
1138
+ multiLevel = $('.dt-button-collection').offset();
1137
1139
  $('body').trigger( 'click.dtb-collection' );
1138
1140
  }
1139
1141
 
@@ -1147,8 +1149,8 @@ $.extend( _dtButtons, {
1147
1149
 
1148
1150
  if ( multiLevel && position === 'absolute' ) {
1149
1151
  config._collection.css( {
1150
- top: multiLevel.top + 5, // magic numbers for a little offset
1151
- left: multiLevel.left + 5
1152
+ top: multiLevel.top,
1153
+ left: multiLevel.left
1152
1154
  } );
1153
1155
  }
1154
1156
  else if ( position === 'absolute' ) {
@@ -1187,7 +1189,10 @@ $.extend( _dtButtons, {
1187
1189
  $('div.dt-button-background').on( 'click.dtb-collection', function () {} );
1188
1190
 
1189
1191
  $('body').on( 'click.dtb-collection', function (e) {
1190
- if ( ! $(e.target).parents().andSelf().filter( config._collection ).length ) {
1192
+ // andSelf is deprecated in jQ1.8, but we want 1.7 compat
1193
+ var back = $.fn.addBack ? 'addBack' : 'andSelf';
1194
+
1195
+ if ( ! $(e.target).parents()[back]().filter( config._collection ).length ) {
1191
1196
  config._collection
1192
1197
  .fadeOut( config.fade, function () {
1193
1198
  config._collection.detach();
@@ -1268,6 +1273,7 @@ $.extend( _dtButtons, {
1268
1273
  buttons: $.map( vals, function ( val, i ) {
1269
1274
  return {
1270
1275
  text: lang[i],
1276
+ className: 'button-page-length',
1271
1277
  action: function ( e, dt ) {
1272
1278
  dt.page.len( val ).draw();
1273
1279
  },
@@ -1314,7 +1320,9 @@ DataTable.Api.register( 'buttons()', function ( group, selector ) {
1314
1320
  group = undefined;
1315
1321
  }
1316
1322
 
1317
- return this.iterator( true, 'table', function ( ctx ) {
1323
+ this.selector.buttonGroup = group;
1324
+
1325
+ var res = this.iterator( true, 'table', function ( ctx ) {
1318
1326
  if ( ctx._buttons ) {
1319
1327
  return Buttons.buttonSelector(
1320
1328
  Buttons.instanceSelector( group, ctx._buttons ),
@@ -1322,6 +1330,9 @@ DataTable.Api.register( 'buttons()', function ( group, selector ) {
1322
1330
  );
1323
1331
  }
1324
1332
  }, true );
1333
+
1334
+ res._groupSelector = group;
1335
+ return res;
1325
1336
  } );
1326
1337
 
1327
1338
  // Individual button selector
@@ -1408,25 +1419,40 @@ DataTable.Api.registerPlural( 'buttons().trigger()', 'button().trigger()', funct
1408
1419
  } );
1409
1420
  } );
1410
1421
 
1411
- // Get the container elements for the button sets selected
1422
+ // Get the container elements
1412
1423
  DataTable.Api.registerPlural( 'buttons().containers()', 'buttons().container()', function () {
1413
1424
  var jq = $();
1425
+ var groupSelector = this._groupSelector;
1414
1426
 
1415
- // jQuery will automatically reduce duplicates to a single entry
1416
- $( this.each( function ( set ) {
1417
- jq = jq.add( set.inst.container() );
1418
- } ) );
1427
+ // We need to use the group selector directly, since if there are no buttons
1428
+ // the result set will be empty
1429
+ this.iterator( true, 'table', function ( ctx ) {
1430
+ if ( ctx._buttons ) {
1431
+ var insts = Buttons.instanceSelector( groupSelector, ctx._buttons );
1432
+
1433
+ for ( var i=0, ien=insts.length ; i<ien ; i++ ) {
1434
+ jq = jq.add( insts[i].container() );
1435
+ }
1436
+ }
1437
+ } );
1419
1438
 
1420
1439
  return jq;
1421
1440
  } );
1422
1441
 
1423
1442
  // Add a new button
1424
1443
  DataTable.Api.register( 'button().add()', function ( idx, conf ) {
1425
- if ( this.length === 1 ) {
1426
- this[0].inst.add( conf, idx );
1444
+ var ctx = this.context;
1445
+
1446
+ // Don't use `this` as it could be empty - select the instances directly
1447
+ if ( ctx.length ) {
1448
+ var inst = Buttons.instanceSelector( this._groupSelector, ctx[0]._buttons );
1449
+
1450
+ if ( inst.length ) {
1451
+ inst[0].add( conf, idx );
1452
+ }
1427
1453
  }
1428
1454
 
1429
- return this.button( idx );
1455
+ return this.button( this._groupSelector, idx );
1430
1456
  } );
1431
1457
 
1432
1458
  // Destroy the button sets selected
@@ -1552,21 +1578,25 @@ var _exportData = function ( dt, inOpts )
1552
1578
 
1553
1579
 
1554
1580
  var header = dt.columns( config.columns ).indexes().map( function (idx) {
1555
- return config.format.header( dt.column( idx ).header().innerHTML, idx );
1581
+ var el = dt.column( idx ).header();
1582
+ return config.format.header( el.innerHTML, idx, el );
1556
1583
  } ).toArray();
1557
1584
 
1558
1585
  var footer = dt.table().footer() ?
1559
1586
  dt.columns( config.columns ).indexes().map( function (idx) {
1560
1587
  var el = dt.column( idx ).footer();
1561
- return config.format.footer( el ? el.innerHTML : '', idx );
1588
+ return config.format.footer( el ? el.innerHTML : '', idx, el );
1562
1589
  } ).toArray() :
1563
1590
  null;
1564
1591
 
1565
- var rowIndexes = dt.rows( config.rows, config.modifier ).indexes().toArray();
1566
- var cells = dt
1567
- .cells( rowIndexes, config.columns )
1592
+ var selectedCells = dt.cells( config.rows, config.columns, config.modifier );
1593
+ var cells = selectedCells
1568
1594
  .render( config.orthogonal )
1569
1595
  .toArray();
1596
+ var cellNodes = selectedCells
1597
+ .nodes()
1598
+ .toArray();
1599
+
1570
1600
  var columns = header.length;
1571
1601
  var rows = columns > 0 ? cells.length / columns : 0;
1572
1602
  var body = new Array( rows );
@@ -1576,7 +1606,7 @@ var _exportData = function ( dt, inOpts )
1576
1606
  var row = new Array( columns );
1577
1607
 
1578
1608
  for ( var j=0 ; j<columns ; j++ ) {
1579
- row[j] = config.format.body( cells[ cellCounter ], j, i );
1609
+ row[j] = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] );
1580
1610
  cellCounter++;
1581
1611
  }
1582
1612
 
@@ -1,11 +1,11 @@
1
- /*! KeyTable 2.1.2
1
+ /*! KeyTable 2.2.0
2
2
  * ©2009-2016 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.1.2
8
+ * @version 2.2.0
9
9
  * @file dataTables.keyTable.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
@@ -72,7 +72,15 @@ var KeyTable = function ( dt, opts ) {
72
72
  enable: true,
73
73
 
74
74
  /** @type {bool} Flag for if a draw is triggered by focus */
75
- focusDraw: false
75
+ focusDraw: false,
76
+
77
+ /** @type {bool} Flag to indicate when waiting for a draw to happen.
78
+ * Will ignore key presses at this point
79
+ */
80
+ waitingForDraw: false,
81
+
82
+ /** @type {object} Information about the last cell that was focused */
83
+ lastFocus: null
76
84
  };
77
85
 
78
86
  // DOM items
@@ -96,7 +104,7 @@ $.extend( KeyTable.prototype, {
96
104
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
97
105
  * API methods for DataTables API interface
98
106
  */
99
-
107
+
100
108
  /**
101
109
  * Blur the table's cell focus
102
110
  */
@@ -138,7 +146,7 @@ $.extend( KeyTable.prototype, {
138
146
  return false;
139
147
  }
140
148
 
141
- var lastIdx = this.s.lastFocus.index();
149
+ var lastIdx = this.s.lastFocus.cell.index();
142
150
  return cell.row === lastIdx.row && cell.column === lastIdx.column;
143
151
  },
144
152
 
@@ -166,7 +174,7 @@ $.extend( KeyTable.prototype, {
166
174
  }
167
175
 
168
176
  // Click to focus
169
- $( dt.table().body() ).on( 'click.keyTable', 'th, td', function () {
177
+ $( dt.table().body() ).on( 'click.keyTable', 'th, td', function (e) {
170
178
  if ( that.s.enable === false ) {
171
179
  return;
172
180
  }
@@ -177,7 +185,7 @@ $.extend( KeyTable.prototype, {
177
185
  return;
178
186
  }
179
187
 
180
- that._focus( cell, null, false );
188
+ that._focus( cell, null, false, e );
181
189
  } );
182
190
 
183
191
  // Key events
@@ -187,7 +195,7 @@ $.extend( KeyTable.prototype, {
187
195
 
188
196
  // Click blur
189
197
  if ( this.c.blurable ) {
190
- $( document ).on( 'click.keyTable', function ( e ) {
198
+ $( document ).on( 'mousedown.keyTable', function ( e ) {
191
199
  // Click on the search input will blur focus
192
200
  if ( $(e.target).parents( '.dataTables_filter' ).length ) {
193
201
  that._blur();
@@ -203,6 +211,11 @@ $.extend( KeyTable.prototype, {
203
211
  return;
204
212
  }
205
213
 
214
+ //If the click was inside the fixed columns container, don't blur
215
+ if ( $(e.target).parents().filter('.DTFC_Cloned').length ) {
216
+ return;
217
+ }
218
+
206
219
  that._blur();
207
220
  } );
208
221
  }
@@ -217,29 +230,30 @@ $.extend( KeyTable.prototype, {
217
230
  if ( dt.settings()[0].oFeatures.bStateSave ) {
218
231
  dt.on( 'stateSaveParams.keyTable', function (e, s, d) {
219
232
  d.keyTable = that.s.lastFocus ?
220
- that.s.lastFocus.index() :
233
+ that.s.lastFocus.cell.index() :
221
234
  null;
222
235
  } );
223
236
  }
224
237
 
225
- // Reload - re-focus on the currently selected item. In SSP mode this
226
- // has the effect of keeping the focus in position when changing page as
227
- // well (which is different from how client-side processing works).
228
- dt.on( 'xhr.keyTable', function ( e ) {
238
+ // Redraw - retain focus on the current cell
239
+ dt.on( 'draw.keyTable', function (e) {
229
240
  if ( that.s.focusDraw ) {
230
- // Triggered by server-side processing, and thus `_focus` will
231
- // do the refocus on the next draw event
232
241
  return;
233
242
  }
234
243
 
235
244
  var lastFocus = that.s.lastFocus;
236
245
 
237
246
  if ( lastFocus ) {
238
- that.s.lastFocus = null;
247
+ var relative = that.s.lastFocus.relative;
248
+ var info = dt.page.info();
249
+ var row = relative.row + info.start;
239
250
 
240
- dt.one( 'draw', function () {
241
- that._focus( lastFocus );
242
- } );
251
+ // Reverse if needed
252
+ if ( row >= info.recordsDisplay ) {
253
+ row = info.recordsDisplay - 1;
254
+ }
255
+
256
+ that._focus( row, relative.column, true, e );
243
257
  }
244
258
  } );
245
259
 
@@ -288,11 +302,13 @@ $.extend( KeyTable.prototype, {
288
302
  return;
289
303
  }
290
304
 
291
- var cell = this.s.lastFocus;
305
+ var cell = this.s.lastFocus.cell;
292
306
 
293
307
  $( cell.node() ).removeClass( this.c.className );
294
308
  this.s.lastFocus = null;
295
309
 
310
+ this._updateFixedColumns(cell.index().column);
311
+
296
312
  this._emitEvent( 'key-blur', [ this.s.dt, cell ] );
297
313
  },
298
314
 
@@ -332,6 +348,11 @@ $.extend( KeyTable.prototype, {
332
348
  var dt = this.s.dt;
333
349
  var editor = this.c.editor;
334
350
 
351
+ // Don't activate inline editing when the shift key is pressed
352
+ if ( key === 16 ) {
353
+ return;
354
+ }
355
+
335
356
  orig.stopPropagation();
336
357
 
337
358
  // Return key should do nothing - for textareas's it would empty the
@@ -340,16 +361,13 @@ $.extend( KeyTable.prototype, {
340
361
  orig.preventDefault();
341
362
  }
342
363
 
343
- editor.inline( this.s.lastFocus.index() );
364
+ editor.inline( this.s.lastFocus.cell.index() );
344
365
 
345
366
  // Excel style - select all text
346
- var input = $('div.DTE input, div.DTE textarea');
347
- if ( input.length ) {
348
- input[0].select();
349
- }
367
+ $('div.DTE input, div.DTE textarea').select();
350
368
 
351
369
  // Reduce the keys the Keys listens for
352
- dt.keys.enable( 'navigation-only' );
370
+ dt.keys.enable( this.c.editorKeys );
353
371
 
354
372
  // On blur of the navigation submit
355
373
  dt.one( 'key-blur.editor', function () {
@@ -386,19 +404,21 @@ $.extend( KeyTable.prototype, {
386
404
  *
387
405
  * @param {DataTables.Api|integer} row Can be given as an API instance that
388
406
  * contains the cell to focus or as an integer. As the latter it is the
389
- * visible row index - NOT the data index
407
+ * visible row index (from the whole data set) - NOT the data index
390
408
  * @param {integer} [column] Not required if a cell is given as the first
391
409
  * parameter. Otherwise this is the column data index for the cell to
392
410
  * focus on
393
411
  * @param {boolean} [shift=true] Should the viewport be moved to show cell
394
412
  * @private
395
413
  */
396
- _focus: function ( row, column, shift )
414
+ _focus: function ( row, column, shift, originalEvent )
397
415
  {
398
416
  var that = this;
399
417
  var dt = this.s.dt;
400
418
  var pageInfo = dt.page.info();
401
419
  var lastFocus = this.s.lastFocus;
420
+ if( ! originalEvent)
421
+ originalEvent = null;
402
422
 
403
423
  if ( ! this.s.enable ) {
404
424
  return;
@@ -425,10 +445,12 @@ $.extend( KeyTable.prototype, {
425
445
  // page
426
446
  if ( pageInfo.length !== -1 && (row < pageInfo.start || row >= pageInfo.start+pageInfo.length) ) {
427
447
  this.s.focusDraw = true;
448
+ this.s.waitingForDraw = true;
428
449
 
429
450
  dt
430
451
  .one( 'draw', function () {
431
452
  that.s.focusDraw = false;
453
+ that.s.waitingForDraw = false;
432
454
  that._focus( row, column );
433
455
  } )
434
456
  .page( Math.floor( row / pageInfo.length ) )
@@ -452,7 +474,7 @@ $.extend( KeyTable.prototype, {
452
474
 
453
475
  if ( lastFocus ) {
454
476
  // Don't trigger a refocus on the same cell
455
- if ( lastFocus.node() === cell.node() ) {
477
+ if ( lastFocus.node === cell.node() ) {
456
478
  return;
457
479
  }
458
480
 
@@ -463,6 +485,8 @@ $.extend( KeyTable.prototype, {
463
485
  var node = $( cell.node() );
464
486
  node.addClass( this.c.className );
465
487
 
488
+ this._updateFixedColumns(column);
489
+
466
490
  // Shift viewpoint and page to make cell visible
467
491
  if ( shift === undefined || shift === true ) {
468
492
  this._scroll( $(window), $(document.body), node, 'offset' );
@@ -476,9 +500,16 @@ $.extend( KeyTable.prototype, {
476
500
  }
477
501
 
478
502
  // Event and finish
479
- this.s.lastFocus = cell;
503
+ this.s.lastFocus = {
504
+ cell: cell,
505
+ node: cell.node(),
506
+ relative: {
507
+ row: dt.rows( { page: 'current' } ).indexes().indexOf( cell.index().row ),
508
+ column: cell.index().column
509
+ }
510
+ };
480
511
 
481
- this._emitEvent( 'key-focus', [ this.s.dt, cell ] );
512
+ this._emitEvent( 'key-focus', [ this.s.dt, cell, originalEvent || null ] );
482
513
  dt.state.save();
483
514
  },
484
515
 
@@ -491,7 +522,16 @@ $.extend( KeyTable.prototype, {
491
522
  */
492
523
  _key: function ( e )
493
524
  {
494
- if ( ! this.s.enable ) {
525
+ // If we are waiting for a draw to happen from another key event, then
526
+ // do nothing for this new key press.
527
+ if ( this.s.waitingForDraw ) {
528
+ e.preventDefault();
529
+ return;
530
+ }
531
+
532
+ var enable = this.s.enable;
533
+ var navEnable = enable === true || enable === 'navigation-only';
534
+ if ( ! enable ) {
495
535
  return;
496
536
  }
497
537
 
@@ -500,8 +540,8 @@ $.extend( KeyTable.prototype, {
500
540
  }
501
541
 
502
542
  // If not focused, then there is no key action to take
503
- var cell = this.s.lastFocus;
504
- if ( ! cell ) {
543
+ var lastFocus = this.s.lastFocus;
544
+ if ( ! lastFocus ) {
505
545
  return;
506
546
  }
507
547
 
@@ -515,63 +555,68 @@ $.extend( KeyTable.prototype, {
515
555
 
516
556
  switch( e.keyCode ) {
517
557
  case 9: // tab
558
+ // `enable` can be tab-only
518
559
  this._shift( e, e.shiftKey ? 'left' : 'right', true );
519
560
  break;
520
561
 
521
562
  case 27: // esc
522
- if ( this.s.blurable && this.s.enable === true ) {
563
+ if ( this.s.blurable && enable === true ) {
523
564
  this._blur();
524
565
  }
525
566
  break;
526
567
 
527
568
  case 33: // page up (previous page)
528
569
  case 34: // page down (next page)
529
- e.preventDefault();
530
- var index = dt.cells( {page: 'current'} ).nodes().indexOf( cell.node() );
531
-
532
- dt
533
- .one( 'draw', function () {
534
- var nodes = dt.cells( {page: 'current'} ).nodes();
535
-
536
- that._focus( dt.cell( index < nodes.length ?
537
- nodes[ index ] :
538
- nodes[ nodes.length-1 ]
539
- ) );
540
- } )
541
- .page( e.keyCode === 33 ? 'previous' : 'next' )
542
- .draw( false );
570
+ if ( navEnable ) {
571
+ e.preventDefault();
572
+
573
+ dt
574
+ .page( e.keyCode === 33 ? 'previous' : 'next' )
575
+ .draw( false );
576
+ }
543
577
  break;
544
578
 
545
579
  case 35: // end (end of current page)
546
580
  case 36: // home (start of current page)
547
- e.preventDefault();
548
- var indexes = dt.cells( {page: 'current'} ).indexes();
549
-
550
- this._focus( dt.cell(
551
- indexes[ e.keyCode === 35 ? indexes.length-1 : 0 ]
552
- ) );
581
+ if ( navEnable ) {
582
+ e.preventDefault();
583
+ var indexes = dt.cells( {page: 'current'} ).indexes();
584
+ var colIndexes = this._columns();
585
+
586
+ this._focus( dt.cell(
587
+ indexes[ e.keyCode === 35 ? indexes.length-1 : colIndexes[0] ]
588
+ ), null, true, e );
589
+ }
553
590
  break;
554
591
 
555
592
  case 37: // left arrow
556
- this._shift( e, 'left' );
593
+ if ( navEnable ) {
594
+ this._shift( e, 'left' );
595
+ }
557
596
  break;
558
597
 
559
598
  case 38: // up arrow
560
- this._shift( e, 'up' );
599
+ if ( navEnable ) {
600
+ this._shift( e, 'up' );
601
+ }
561
602
  break;
562
603
 
563
604
  case 39: // right arrow
564
- this._shift( e, 'right' );
605
+ if ( navEnable ) {
606
+ this._shift( e, 'right' );
607
+ }
565
608
  break;
566
609
 
567
610
  case 40: // down arrow
568
- this._shift( e, 'down' );
611
+ if ( navEnable ) {
612
+ this._shift( e, 'down' );
613
+ }
569
614
  break;
570
615
 
571
616
  default:
572
617
  // Everything else - pass through only when fully enabled
573
- if ( this.s.enable === true ) {
574
- this._emitEvent( 'key', [ dt, e.keyCode, this.s.lastFocus, e ] );
618
+ if ( enable === true ) {
619
+ this._emitEvent( 'key', [ dt, e.keyCode, this.s.lastFocus.cell, e ] );
575
620
  }
576
621
  break;
577
622
  }
@@ -639,7 +684,7 @@ $.extend( KeyTable.prototype, {
639
684
  var dt = this.s.dt;
640
685
  var pageInfo = dt.page.info();
641
686
  var rows = pageInfo.recordsDisplay;
642
- var currentCell = this.s.lastFocus;
687
+ var currentCell = this.s.lastFocus.cell;
643
688
  var columns = this._columns();
644
689
 
645
690
  if ( ! currentCell ) {
@@ -696,7 +741,7 @@ $.extend( KeyTable.prototype, {
696
741
  ) {
697
742
  e.preventDefault();
698
743
 
699
- this._focus( row, column );
744
+ this._focus( row, column, true, e );
700
745
  }
701
746
  else if ( ! keyBlurable || ! this.c.blurable ) {
702
747
  // No new focus, but if the table isn't blurable, then don't loose
@@ -736,10 +781,27 @@ $.extend( KeyTable.prototype, {
736
781
  } )
737
782
  .insertBefore( dt.table().node() );
738
783
 
739
- div.children().on( 'focus', function () {
740
- that._focus( dt.cell(':eq(0)', '0:visible', {page: 'current'}) );
784
+ div.children().on( 'focus', function (e) {
785
+ that._focus( dt.cell(':eq(0)', '0:visible', {page: 'current'}), null, true, e );
741
786
  } );
742
- }
787
+ },
788
+ /**
789
+ * Update fixed columns if they are enabled and if the cell we are focusing is inside a fixed column
790
+ * @param {integer} column Index of the column being changed
791
+ *
792
+ * @private
793
+ */
794
+ _updateFixedColumns:function(column){
795
+ var dt = this.s.dt;
796
+ var settings = dt.settings()[0];
797
+
798
+ if(settings._oFixedColumns){
799
+ var leftCols = settings._oFixedColumns.s.iLeftColumns;
800
+ var rightCols = settings.aoColumns.length - settings._oFixedColumns.s.iRightColumns;
801
+ if (column < leftCols || column > rightCols)
802
+ dt.fixedColumns().update();
803
+ }
804
+ }
743
805
  } );
744
806
 
745
807
 
@@ -776,6 +838,13 @@ KeyTable.defaults = {
776
838
  */
777
839
  editor: null,
778
840
 
841
+ /**
842
+ * Option that defines what KeyTable's behaviour will be when used with
843
+ * Editor's inline editing. Can be `navigation-only` or `tab-only`.
844
+ * @type {String}
845
+ */
846
+ editorKeys: 'navigation-only',
847
+
779
848
  /**
780
849
  * Select a cell to automatically select on start up. `null` for no
781
850
  * automatic selection
@@ -798,7 +867,7 @@ KeyTable.defaults = {
798
867
 
799
868
 
800
869
 
801
- KeyTable.version = "2.1.2";
870
+ KeyTable.version = "2.2.0";
802
871
 
803
872
 
804
873
  $.fn.dataTable.KeyTable = KeyTable;
@@ -870,7 +939,7 @@ $(document).on( 'preInit.dt.dtk', function (e, settings, json) {
870
939
  var defaults = DataTable.defaults.keys;
871
940
 
872
941
  if ( init || defaults ) {
873
- var opts = $.extend( {}, init, defaults );
942
+ var opts = $.extend( {}, defaults, init );
874
943
 
875
944
  if ( init !== false ) {
876
945
  new KeyTable( settings, opts );