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
@@ -1,11 +1,11 @@
1
- /*! Responsive 2.1.0
1
+ /*! Responsive 2.1.1
2
2
  * 2014-2016 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary Responsive
7
7
  * @description Responsive tables plug-in for DataTables
8
- * @version 2.1.0
8
+ * @version 2.1.1
9
9
  * @file dataTables.responsive.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
@@ -166,7 +166,7 @@ $.extend( Responsive.prototype, {
166
166
  // new data is added
167
167
  dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
168
168
  if ( $.inArray( false, that.s.current ) !== -1 ) {
169
- $('td, th', tr).each( function ( i ) {
169
+ $('>td, >th', tr).each( function ( i ) {
170
170
  var idx = dt.column.index( 'toData', i );
171
171
 
172
172
  if ( that.s.current[idx] === false ) {
@@ -236,6 +236,23 @@ $.extend( Responsive.prototype, {
236
236
  that._resize();
237
237
  });
238
238
 
239
+ // On Ajax reload we want to reopen any child rows which are displayed
240
+ // by responsive
241
+ dt.on( 'preXhr.dtr', function () {
242
+ var rowIds = [];
243
+ dt.rows().every( function () {
244
+ if ( this.child.isShown() ) {
245
+ rowIds.push( this.id(true) );
246
+ }
247
+ } );
248
+
249
+ dt.one( 'draw.dtr', function () {
250
+ dt.rows( rowIds ).every( function () {
251
+ that._detailsDisplay( this, false );
252
+ } );
253
+ } );
254
+ });
255
+
239
256
  dt.on( 'init.dtr', function (e, settings, details) {
240
257
  that._resizeAuto();
241
258
  that._resize();
@@ -598,7 +615,7 @@ $.extend( Responsive.prototype, {
598
615
  }
599
616
 
600
617
  // Check that the row is actually a DataTable's controlled node
601
- if ( ! dt.row( $(this).closest('tr') ).length ) {
618
+ if ( $.inArray( $(this).closest('tr').get(0), dt.rows().nodes().toArray() ) === -1 ) {
602
619
  return;
603
620
  }
604
621
 
@@ -907,6 +924,12 @@ $.extend( Responsive.prototype, {
907
924
  ':eq('+target+')' :
908
925
  target;
909
926
 
927
+ // This is a bit of a hack - we need to limit the selected nodes to just
928
+ // those of this table
929
+ if ( selector === 'td:first-child, th:first-child' ) {
930
+ selector = '>td:first-child, >th:first-child';
931
+ }
932
+
910
933
  $( selector, dt.rows( { page: 'current' } ).nodes() )
911
934
  .attr( 'tabIndex', ctx.iTabIndex )
912
935
  .data( 'dtr-keyboard', 1 );
@@ -1062,7 +1085,7 @@ Responsive.renderer = {
1062
1085
  } ).join('');
1063
1086
 
1064
1087
  return data ?
1065
- $('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
1088
+ $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>').append( data ) :
1066
1089
  false;
1067
1090
  }
1068
1091
  },
@@ -1080,7 +1103,7 @@ Responsive.renderer = {
1080
1103
  '</tr>';
1081
1104
  } ).join('');
1082
1105
 
1083
- return $('<table class="'+options.tableClass+'" width="100%"/>').append( data );
1106
+ return $('<table class="'+options.tableClass+' dtr-details" width="100%"/>').append( data );
1084
1107
  }
1085
1108
  }
1086
1109
  };
@@ -1201,7 +1224,7 @@ Api.register( 'responsive.hasHidden()', function () {
1201
1224
  * @name Responsive.version
1202
1225
  * @static
1203
1226
  */
1204
- Responsive.version = '2.1.0';
1227
+ Responsive.version = '2.1.1';
1205
1228
 
1206
1229
 
1207
1230
  $.fn.dataTable.Responsive = Responsive;
@@ -59,9 +59,13 @@ _display.modal = function ( options ) {
59
59
  else {
60
60
  if ( ! update ) {
61
61
  if ( options && options.header ) {
62
- _modal.find('div.modal-header')
62
+ var header = _modal.find('div.modal-header');
63
+ var button = header.find('button').detach();
64
+
65
+ header
63
66
  .empty()
64
- .append( '<h4 class="modal-title">'+options.header( row )+'</h4>' );
67
+ .append( '<h4 class="modal-title">'+options.header( row )+'</h4>' )
68
+ .prepend( button );
65
69
  }
66
70
 
67
71
  _modal.find( 'div.modal-body' )
@@ -59,9 +59,13 @@ _display.modal = function ( options ) {
59
59
  else {
60
60
  if ( ! update ) {
61
61
  if ( options && options.header ) {
62
- _modal.find('div.modal-header')
62
+ var header = _modal.find('div.modal-header');
63
+ var button = header.find('button').detach();
64
+
65
+ header
63
66
  .empty()
64
- .append( '<h4 class="modal-title">'+options.header( row )+'</h4>' );
67
+ .append( '<h4 class="modal-title">'+options.header( row )+'</h4>' )
68
+ .prepend( button );
65
69
  }
66
70
 
67
71
  _modal.find( 'div.modal-body' )
@@ -1,11 +1,11 @@
1
- /*! RowReorder 1.1.2
1
+ /*! RowReorder 1.2.0
2
2
  * 2015-2016 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary RowReorder
7
7
  * @description Row reordering extension for DataTables
8
- * @version 1.1.2
8
+ * @version 1.2.0
9
9
  * @file dataTables.rowReorder.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
@@ -170,6 +170,10 @@ $.extend( RowReorder.prototype, {
170
170
  // Use `table().container()` rather than just the table node for IE8 -
171
171
  // otherwise it only works once...
172
172
  $(dt.table().container()).on( 'mousedown.rowReorder touchstart.rowReorder', this.c.selector, function (e) {
173
+ if ( ! that.c.enabled ) {
174
+ return;
175
+ }
176
+
173
177
  var tr = $(this).closest('tr');
174
178
 
175
179
  // Double check that it is a DataTable row
@@ -447,6 +451,7 @@ $.extend( RowReorder.prototype, {
447
451
  */
448
452
  _mouseUp: function ( e )
449
453
  {
454
+ var that = this;
450
455
  var dt = this.s.dt;
451
456
  var i, ien;
452
457
  var dataSrc = this.c.dataSrc;
@@ -507,11 +512,19 @@ $.extend( RowReorder.prototype, {
507
512
 
508
513
  // Editor interface
509
514
  if ( this.c.editor ) {
515
+ // Disable user interaction while Editor is submitting
516
+ this.c.enabled = false;
517
+
510
518
  this.c.editor
511
- .edit( diffNodes, false, {
512
- submit: 'changed'
513
- } )
519
+ .edit(
520
+ diffNodes,
521
+ false,
522
+ $.extend( {submit: 'changed'}, this.c.formOptions )
523
+ )
514
524
  .multiSet( dataSrc, idDiff )
525
+ .one( 'submitComplete', function () {
526
+ that.c.enabled = true;
527
+ } )
515
528
  .submit();
516
529
  }
517
530
 
@@ -647,6 +660,20 @@ RowReorder.defaults = {
647
660
  */
648
661
  editor: null,
649
662
 
663
+ /**
664
+ * Enable / disable RowReorder's user interaction
665
+ * @type {Boolean}
666
+ */
667
+ enabled: true,
668
+
669
+ /**
670
+ * Form options to pass to Editor when submitting a change in the row order.
671
+ * See the Editor `from-options` object for details of the options
672
+ * available.
673
+ * @type {Object}
674
+ */
675
+ formOptions: {},
676
+
650
677
  /**
651
678
  * Drag handle selector. This defines the element that when dragged will
652
679
  * reorder a row.
@@ -673,13 +700,44 @@ RowReorder.defaults = {
673
700
  };
674
701
 
675
702
 
703
+ /*
704
+ * API
705
+ */
706
+ var Api = $.fn.dataTable.Api;
707
+
708
+ // Doesn't do anything - work around for a bug in DT... Not documented
709
+ Api.register( 'rowReorder()', function () {
710
+ return this;
711
+ } );
712
+
713
+ Api.register( 'rowReorder.enable()', function ( toggle ) {
714
+ if ( toggle === undefined ) {
715
+ toggle = true;
716
+ }
717
+
718
+ return this.iterator( 'table', function ( ctx ) {
719
+ if ( ctx.rowreorder ) {
720
+ ctx.rowreorder.c.enabled = toggle;
721
+ }
722
+ } );
723
+ } );
724
+
725
+ Api.register( 'rowReorder.disable()', function () {
726
+ return this.iterator( 'table', function ( ctx ) {
727
+ if ( ctx.rowreorder ) {
728
+ ctx.rowreorder.c.enabled = false;
729
+ }
730
+ } );
731
+ } );
732
+
733
+
676
734
  /**
677
735
  * Version information
678
736
  *
679
737
  * @name RowReorder.version
680
738
  * @static
681
739
  */
682
- RowReorder.version = '1.1.2';
740
+ RowReorder.version = '1.2.0';
683
741
 
684
742
 
685
743
  $.fn.dataTable.RowReorder = RowReorder;
@@ -1,4 +1,4 @@
1
- /*! Select for DataTables 1.2.0
1
+ /*! Select for DataTables 1.2.1
2
2
  * 2015-2016 SpryMedia Ltd - datatables.net/license/mit
3
3
  */
4
4
 
@@ -6,7 +6,7 @@
6
6
  * @summary Select for DataTables
7
7
  * @description A collection of API methods, events and buttons for DataTables
8
8
  * that provides selection options of the items in a DataTable
9
- * @version 1.2.0
9
+ * @version 1.2.1
10
10
  * @file dataTables.select.js
11
11
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
12
12
  * @contact datatables.net/forums
@@ -54,7 +54,7 @@ var DataTable = $.fn.dataTable;
54
54
  // Version information for debugger
55
55
  DataTable.select = {};
56
56
 
57
- DataTable.select.version = '1.2.0';
57
+ DataTable.select.version = '1.2.1';
58
58
 
59
59
  DataTable.select.init = function ( dt ) {
60
60
  var ctx = dt.settings()[0];
@@ -71,15 +71,18 @@ DataTable.select.init = function ( dt ) {
71
71
  var info = true;
72
72
  var selector = 'td, th';
73
73
  var className = 'selected';
74
+ var setStyle = false;
74
75
 
75
76
  ctx._select = {};
76
77
 
77
78
  // Initialisation customisations
78
79
  if ( opts === true ) {
79
80
  style = 'os';
81
+ setStyle = true;
80
82
  }
81
83
  else if ( typeof opts === 'string' ) {
82
84
  style = opts;
85
+ setStyle = true;
83
86
  }
84
87
  else if ( $.isPlainObject( opts ) ) {
85
88
  if ( opts.blurable !== undefined ) {
@@ -96,6 +99,7 @@ DataTable.select.init = function ( dt ) {
96
99
 
97
100
  if ( opts.style !== undefined ) {
98
101
  style = opts.style;
102
+ setStyle = true;
99
103
  }
100
104
 
101
105
  if ( opts.selector !== undefined ) {
@@ -129,7 +133,7 @@ DataTable.select.init = function ( dt ) {
129
133
 
130
134
  // If the init options haven't enabled select, but there is a selectable
131
135
  // class name, then enable
132
- if ( $( dt.table().node() ).hasClass( 'selectable' ) ) {
136
+ if ( ! setStyle && $( dt.table().node() ).hasClass( 'selectable' ) ) {
133
137
  dt.select.style( 'os' );
134
138
  }
135
139
  };
@@ -301,7 +305,7 @@ function disableMouseSelection( dt )
301
305
  var ctx = dt.settings()[0];
302
306
  var selector = ctx._select.selector;
303
307
 
304
- $( dt.table().body() )
308
+ $( dt.table().container() )
305
309
  .off( 'mousedown.dtSelect', selector )
306
310
  .off( 'mouseup.dtSelect', selector )
307
311
  .off( 'click.dtSelect', selector );
@@ -317,16 +321,16 @@ function disableMouseSelection( dt )
317
321
  */
318
322
  function enableMouseSelection ( dt )
319
323
  {
320
- var body = $( dt.table().body() );
324
+ var container = $( dt.table().container() );
321
325
  var ctx = dt.settings()[0];
322
326
  var selector = ctx._select.selector;
323
327
 
324
- body
328
+ container
325
329
  .on( 'mousedown.dtSelect', selector, function(e) {
326
330
  // Disallow text selection for shift clicking on the table so multi
327
331
  // element selection doesn't look terrible!
328
332
  if ( e.shiftKey || e.metaKey || e.ctrlKey ) {
329
- body
333
+ container
330
334
  .css( '-moz-user-select', 'none' )
331
335
  .one('selectstart.dtSelect', selector, function () {
332
336
  return false;
@@ -336,7 +340,7 @@ function enableMouseSelection ( dt )
336
340
  .on( 'mouseup.dtSelect', selector, function() {
337
341
  // Allow text selection to occur again, Mozilla style (tested in FF
338
342
  // 35.0.1 - still required)
339
- body.css( '-moz-user-select', '' );
343
+ container.css( '-moz-user-select', '' );
340
344
  } )
341
345
  .on( 'click.dtSelect', selector, function ( e ) {
342
346
  var items = dt.select.items();
@@ -1000,16 +1004,26 @@ function i18n( label, def ) {
1000
1004
  };
1001
1005
  }
1002
1006
 
1007
+ // Common events with suitable namespaces
1008
+ function namespacedEvents ( config ) {
1009
+ var unique = config._eventNamespace;
1010
+
1011
+ return 'draw.dt.DT'+unique+' select.dt.DT'+unique+' deselect.dt.DT'+unique;
1012
+ }
1013
+
1014
+ var _buttonNamespace = 0;
1015
+
1003
1016
  $.extend( DataTable.ext.buttons, {
1004
1017
  selected: {
1005
1018
  text: i18n( 'selected', 'Selected' ),
1006
1019
  className: 'buttons-selected',
1007
- init: function ( dt ) {
1020
+ init: function ( dt, node, config ) {
1008
1021
  var that = this;
1022
+ config._eventNamespace = '.select'+(_buttonNamespace++);
1009
1023
 
1010
1024
  // .DT namespace listeners are removed by DataTables automatically
1011
1025
  // on table destroy
1012
- dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1026
+ dt.on( namespacedEvents(config), function () {
1013
1027
  var enable = that.rows( { selected: true } ).any() ||
1014
1028
  that.columns( { selected: true } ).any() ||
1015
1029
  that.cells( { selected: true } ).any();
@@ -1018,15 +1032,19 @@ $.extend( DataTable.ext.buttons, {
1018
1032
  } );
1019
1033
 
1020
1034
  this.disable();
1035
+ },
1036
+ destroy: function ( dt, node, config ) {
1037
+ dt.off( config._eventNamespace );
1021
1038
  }
1022
1039
  },
1023
1040
  selectedSingle: {
1024
1041
  text: i18n( 'selectedSingle', 'Selected single' ),
1025
1042
  className: 'buttons-selected-single',
1026
- init: function ( dt ) {
1043
+ init: function ( dt, node, config ) {
1027
1044
  var that = this;
1045
+ config._eventNamespace = '.select'+(_buttonNamespace++);
1028
1046
 
1029
- dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1047
+ dt.on( namespacedEvents(config), function () {
1030
1048
  var count = dt.rows( { selected: true } ).flatten().length +
1031
1049
  dt.columns( { selected: true } ).flatten().length +
1032
1050
  dt.cells( { selected: true } ).flatten().length;
@@ -1035,6 +1053,9 @@ $.extend( DataTable.ext.buttons, {
1035
1053
  } );
1036
1054
 
1037
1055
  this.disable();
1056
+ },
1057
+ destroy: function ( dt, node, config ) {
1058
+ dt.off( config._eventNamespace );
1038
1059
  }
1039
1060
  },
1040
1061
  selectAll: {
@@ -1051,10 +1072,11 @@ $.extend( DataTable.ext.buttons, {
1051
1072
  action: function () {
1052
1073
  clear( this.settings()[0], true );
1053
1074
  },
1054
- init: function ( dt ) {
1075
+ init: function ( dt, node, config ) {
1055
1076
  var that = this;
1077
+ config._eventNamespace = '.select'+(_buttonNamespace++);
1056
1078
 
1057
- dt.on( 'draw.dt.DT select.dt.DT deselect.dt.DT', function () {
1079
+ dt.on( namespacedEvents(config), function () {
1058
1080
  var count = dt.rows( { selected: true } ).flatten().length +
1059
1081
  dt.columns( { selected: true } ).flatten().length +
1060
1082
  dt.cells( { selected: true } ).flatten().length;
@@ -1063,6 +1085,9 @@ $.extend( DataTable.ext.buttons, {
1063
1085
  } );
1064
1086
 
1065
1087
  this.disable();
1088
+ },
1089
+ destroy: function ( dt, node, config ) {
1090
+ dt.off( config._eventNamespace );
1066
1091
  }
1067
1092
  }
1068
1093
  } );
@@ -1,15 +1,15 @@
1
- /*! DataTables 1.10.12
2
- * ©2008-2015 SpryMedia Ltd - datatables.net/license
1
+ /*! DataTables 1.10.13
2
+ * ©2008-2016 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary DataTables
7
7
  * @description Paginate, search and order HTML tables
8
- * @version 1.10.12
8
+ * @version 1.10.13
9
9
  * @file jquery.dataTables.js
10
- * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
- * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2008-2015 SpryMedia Ltd.
10
+ * @author SpryMedia Ltd
11
+ * @contact www.datatables.net
12
+ * @copyright Copyright 2008-2016 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
@@ -279,7 +279,7 @@
279
279
  * "bPaginate": false
280
280
  * } );
281
281
  *
282
- * $(window).bind('resize', function () {
282
+ * $(window).on('resize', function () {
283
283
  * oTable.fnAdjustColumnSizing();
284
284
  * } );
285
285
  * } );
@@ -1101,7 +1101,7 @@
1101
1101
  var oLanguage = oSettings.oLanguage;
1102
1102
  $.extend( true, oLanguage, oInit.oLanguage );
1103
1103
 
1104
- if ( oLanguage.sUrl !== "" )
1104
+ if ( oLanguage.sUrl )
1105
1105
  {
1106
1106
  /* Get the language definitions from a file - because this Ajax call makes the language
1107
1107
  * get async to the remainder of this function we use bInitHandedOff to indicate that
@@ -1213,131 +1213,125 @@
1213
1213
  }
1214
1214
 
1215
1215
  var features = oSettings.oFeatures;
1216
+ var loadedInit = function () {
1217
+ /*
1218
+ * Sorting
1219
+ * @todo For modularisation (1.11) this needs to do into a sort start up handler
1220
+ */
1216
1221
 
1217
- /* Must be done after everything which can be overridden by the state saving! */
1218
- if ( oInit.bStateSave )
1219
- {
1220
- features.bStateSave = true;
1221
- _fnLoadState( oSettings, oInit );
1222
- _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
1223
- }
1222
+ // If aaSorting is not defined, then we use the first indicator in asSorting
1223
+ // in case that has been altered, so the default sort reflects that option
1224
+ if ( oInit.aaSorting === undefined ) {
1225
+ var sorting = oSettings.aaSorting;
1226
+ for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
1227
+ sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1228
+ }
1229
+ }
1224
1230
 
1231
+ /* Do a first pass on the sorting classes (allows any size changes to be taken into
1232
+ * account, and also will apply sorting disabled classes if disabled
1233
+ */
1234
+ _fnSortingClasses( oSettings );
1225
1235
 
1226
- /*
1227
- * Sorting
1228
- * @todo For modularisation (1.11) this needs to do into a sort start up handler
1229
- */
1236
+ if ( features.bSort ) {
1237
+ _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1238
+ if ( oSettings.bSorted ) {
1239
+ var aSort = _fnSortFlatten( oSettings );
1240
+ var sortedColumns = {};
1230
1241
 
1231
- // If aaSorting is not defined, then we use the first indicator in asSorting
1232
- // in case that has been altered, so the default sort reflects that option
1233
- if ( oInit.aaSorting === undefined )
1234
- {
1235
- var sorting = oSettings.aaSorting;
1236
- for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
1237
- {
1238
- sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1239
- }
1240
- }
1242
+ $.each( aSort, function (i, val) {
1243
+ sortedColumns[ val.src ] = val.dir;
1244
+ } );
1241
1245
 
1242
- /* Do a first pass on the sorting classes (allows any size changes to be taken into
1243
- * account, and also will apply sorting disabled classes if disabled
1244
- */
1245
- _fnSortingClasses( oSettings );
1246
+ _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
1247
+ _fnSortAria( oSettings );
1248
+ }
1249
+ } );
1250
+ }
1246
1251
 
1247
- if ( features.bSort )
1248
- {
1249
1252
  _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1250
- if ( oSettings.bSorted ) {
1251
- var aSort = _fnSortFlatten( oSettings );
1252
- var sortedColumns = {};
1253
+ if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
1254
+ _fnSortingClasses( oSettings );
1255
+ }
1256
+ }, 'sc' );
1253
1257
 
1254
- $.each( aSort, function (i, val) {
1255
- sortedColumns[ val.src ] = val.dir;
1256
- } );
1257
1258
 
1258
- _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
1259
- _fnSortAria( oSettings );
1260
- }
1259
+ /*
1260
+ * Final init
1261
+ * Cache the header, body and footer as required, creating them if needed
1262
+ */
1263
+
1264
+ // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1265
+ var captions = $this.children('caption').each( function () {
1266
+ this._captionSide = $(this).css('caption-side');
1261
1267
  } );
1262
- }
1263
1268
 
1264
- _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1265
- if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
1266
- _fnSortingClasses( oSettings );
1269
+ var thead = $this.children('thead');
1270
+ if ( thead.length === 0 ) {
1271
+ thead = $('<thead/>').appendTo($this);
1267
1272
  }
1268
- }, 'sc' );
1273
+ oSettings.nTHead = thead[0];
1269
1274
 
1275
+ var tbody = $this.children('tbody');
1276
+ if ( tbody.length === 0 ) {
1277
+ tbody = $('<tbody/>').appendTo($this);
1278
+ }
1279
+ oSettings.nTBody = tbody[0];
1270
1280
 
1271
- /*
1272
- * Final init
1273
- * Cache the header, body and footer as required, creating them if needed
1274
- */
1281
+ var tfoot = $this.children('tfoot');
1282
+ if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
1283
+ // If we are a scrolling table, and no footer has been given, then we need to create
1284
+ // a tfoot element for the caption element to be appended to
1285
+ tfoot = $('<tfoot/>').appendTo($this);
1286
+ }
1275
1287
 
1276
- // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1277
- var captions = $this.children('caption').each( function () {
1278
- this._captionSide = $this.css('caption-side');
1279
- } );
1288
+ if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
1289
+ $this.addClass( oClasses.sNoFooter );
1290
+ }
1291
+ else if ( tfoot.length > 0 ) {
1292
+ oSettings.nTFoot = tfoot[0];
1293
+ _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
1294
+ }
1280
1295
 
1281
- var thead = $this.children('thead');
1282
- if ( thead.length === 0 )
1283
- {
1284
- thead = $('<thead/>').appendTo(this);
1285
- }
1286
- oSettings.nTHead = thead[0];
1296
+ /* Check if there is data passing into the constructor */
1297
+ if ( oInit.aaData ) {
1298
+ for ( i=0 ; i<oInit.aaData.length ; i++ ) {
1299
+ _fnAddData( oSettings, oInit.aaData[ i ] );
1300
+ }
1301
+ }
1302
+ else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
1303
+ /* Grab the data from the page - only do this when deferred loading or no Ajax
1304
+ * source since there is no point in reading the DOM data if we are then going
1305
+ * to replace it with Ajax data
1306
+ */
1307
+ _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
1308
+ }
1287
1309
 
1288
- var tbody = $this.children('tbody');
1289
- if ( tbody.length === 0 )
1290
- {
1291
- tbody = $('<tbody/>').appendTo(this);
1292
- }
1293
- oSettings.nTBody = tbody[0];
1310
+ /* Copy the data index array */
1311
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1294
1312
 
1295
- var tfoot = $this.children('tfoot');
1296
- if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
1297
- {
1298
- // If we are a scrolling table, and no footer has been given, then we need to create
1299
- // a tfoot element for the caption element to be appended to
1300
- tfoot = $('<tfoot/>').appendTo(this);
1301
- }
1313
+ /* Initialisation complete - table can be drawn */
1314
+ oSettings.bInitialised = true;
1302
1315
 
1303
- if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
1304
- $this.addClass( oClasses.sNoFooter );
1305
- }
1306
- else if ( tfoot.length > 0 ) {
1307
- oSettings.nTFoot = tfoot[0];
1308
- _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
1309
- }
1316
+ /* Check if we need to initialise the table (it might not have been handed off to the
1317
+ * language processor)
1318
+ */
1319
+ if ( bInitHandedOff === false ) {
1320
+ _fnInitialise( oSettings );
1321
+ }
1322
+ };
1310
1323
 
1311
- /* Check if there is data passing into the constructor */
1312
- if ( oInit.aaData )
1324
+ /* Must be done after everything which can be overridden by the state saving! */
1325
+ if ( oInit.bStateSave )
1313
1326
  {
1314
- for ( i=0 ; i<oInit.aaData.length ; i++ )
1315
- {
1316
- _fnAddData( oSettings, oInit.aaData[ i ] );
1317
- }
1327
+ features.bStateSave = true;
1328
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
1329
+ _fnLoadState( oSettings, oInit, loadedInit );
1318
1330
  }
1319
- else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
1320
- {
1321
- /* Grab the data from the page - only do this when deferred loading or no Ajax
1322
- * source since there is no point in reading the DOM data if we are then going
1323
- * to replace it with Ajax data
1324
- */
1325
- _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
1331
+ else {
1332
+ loadedInit();
1326
1333
  }
1327
1334
 
1328
- /* Copy the data index array */
1329
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1330
-
1331
- /* Initialisation complete - table can be drawn */
1332
- oSettings.bInitialised = true;
1333
-
1334
- /* Check if we need to initialise the table (it might not have been handed off to the
1335
- * language processor)
1336
- */
1337
- if ( bInitHandedOff === false )
1338
- {
1339
- _fnInitialise( oSettings );
1340
- }
1341
1335
  } );
1342
1336
  _that = null;
1343
1337
  return this;
@@ -1368,8 +1362,10 @@
1368
1362
  var _re_dic = {};
1369
1363
  var _re_new_lines = /[\r\n]/g;
1370
1364
  var _re_html = /<.*?>/g;
1371
- var _re_date_start = /^[\w\+\-]/;
1372
- var _re_date_end = /[\w\+\-]$/;
1365
+
1366
+ // This is not strict ISO8601 - Date.parse() is quite lax, although
1367
+ // implementations differ between browsers.
1368
+ var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1373
1369
 
1374
1370
  // Escape regular expression special characters
1375
1371
  var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
@@ -1851,7 +1847,7 @@
1851
1847
  .css( {
1852
1848
  position: 'fixed',
1853
1849
  top: 0,
1854
- left: 0,
1850
+ left: $(window).scrollLeft()*-1, // allow for scrolling
1855
1851
  height: 1,
1856
1852
  width: 1,
1857
1853
  overflow: 'hidden'
@@ -2544,7 +2540,7 @@
2544
2540
  function _fnSplitObjNotation( str )
2545
2541
  {
2546
2542
  return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
2547
- return s.replace(/\\./g, '.');
2543
+ return s.replace(/\\\./g, '.');
2548
2544
  } );
2549
2545
  }
2550
2546
 
@@ -4202,13 +4198,13 @@
4202
4198
  var jqFilter = $('input', filter)
4203
4199
  .val( previousSearch.sSearch )
4204
4200
  .attr( 'placeholder', language.sSearchPlaceholder )
4205
- .bind(
4201
+ .on(
4206
4202
  'keyup.DT search.DT input.DT paste.DT cut.DT',
4207
4203
  searchDelay ?
4208
4204
  _fnThrottle( searchFn, searchDelay ) :
4209
4205
  searchFn
4210
4206
  )
4211
- .bind( 'keypress.DT', function(e) {
4207
+ .on( 'keypress.DT', function(e) {
4212
4208
  /* Prevent form submission */
4213
4209
  if ( e.keyCode == 13 ) {
4214
4210
  return false;
@@ -4338,16 +4334,19 @@
4338
4334
  }
4339
4335
 
4340
4336
  var data;
4337
+ var out = [];
4341
4338
  var display = settings.aiDisplay;
4342
4339
  var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
4343
4340
 
4344
- for ( var i=display.length-1 ; i>=0 ; i-- ) {
4341
+ for ( var i=0 ; i<display.length ; i++ ) {
4345
4342
  data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4346
4343
 
4347
- if ( ! rpSearch.test( data ) ) {
4348
- display.splice( i, 1 );
4344
+ if ( rpSearch.test( data ) ) {
4345
+ out.push( display[i] );
4349
4346
  }
4350
4347
  }
4348
+
4349
+ settings.aiDisplay = out;
4351
4350
  }
4352
4351
 
4353
4352
 
@@ -4367,6 +4366,7 @@
4367
4366
  var prevSearch = settings.oPreviousSearch.sSearch;
4368
4367
  var displayMaster = settings.aiDisplayMaster;
4369
4368
  var display, invalidated, i;
4369
+ var filtered = [];
4370
4370
 
4371
4371
  // Need to take account of custom filtering functions - always filter
4372
4372
  if ( DataTable.ext.search.length !== 0 ) {
@@ -4395,11 +4395,13 @@
4395
4395
  // Search the display array
4396
4396
  display = settings.aiDisplay;
4397
4397
 
4398
- for ( i=display.length-1 ; i>=0 ; i-- ) {
4399
- if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
4400
- display.splice( i, 1 );
4398
+ for ( i=0 ; i<display.length ; i++ ) {
4399
+ if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
4400
+ filtered.push( display[i] );
4401
4401
  }
4402
4402
  }
4403
+
4404
+ settings.aiDisplay = filtered;
4403
4405
  }
4404
4406
  }
4405
4407
 
@@ -4812,13 +4814,13 @@
4812
4814
  // reference is broken by the use of outerHTML
4813
4815
  $('select', div)
4814
4816
  .val( settings._iDisplayLength )
4815
- .bind( 'change.DT', function(e) {
4817
+ .on( 'change.DT', function(e) {
4816
4818
  _fnLengthChange( settings, $(this).val() );
4817
4819
  _fnDraw( settings );
4818
4820
  } );
4819
4821
 
4820
4822
  // Update node value whenever anything changes the table's length
4821
- $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
4823
+ $(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
4822
4824
  if ( settings === s ) {
4823
4825
  $('select', div).val( len );
4824
4826
  }
@@ -5683,7 +5685,7 @@
5683
5685
 
5684
5686
  if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
5685
5687
  var bindResize = function () {
5686
- $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
5688
+ $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
5687
5689
  _fnAdjustColumnSizing( oSettings );
5688
5690
  } ) );
5689
5691
  };
@@ -6294,86 +6296,102 @@
6294
6296
  * Attempt to load a saved table state
6295
6297
  * @param {object} oSettings dataTables settings object
6296
6298
  * @param {object} oInit DataTables init object so we can override settings
6299
+ * @param {function} callback Callback to execute when the state has been loaded
6297
6300
  * @memberof DataTable#oApi
6298
6301
  */
6299
- function _fnLoadState ( settings, oInit )
6302
+ function _fnLoadState ( settings, oInit, callback )
6300
6303
  {
6301
6304
  var i, ien;
6302
6305
  var columns = settings.aoColumns;
6306
+ var loaded = function ( s ) {
6307
+ if ( ! s || ! s.time ) {
6308
+ callback();
6309
+ return;
6310
+ }
6303
6311
 
6304
- if ( ! settings.oFeatures.bStateSave ) {
6305
- return;
6306
- }
6307
-
6308
- var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
6309
- if ( ! state || ! state.time ) {
6310
- return;
6311
- }
6312
+ // Allow custom and plug-in manipulation functions to alter the saved data set and
6313
+ // cancelling of loading by returning false
6314
+ var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
6315
+ if ( $.inArray( false, abStateLoad ) !== -1 ) {
6316
+ callback();
6317
+ return;
6318
+ }
6312
6319
 
6313
- /* Allow custom and plug-in manipulation functions to alter the saved data set and
6314
- * cancelling of loading by returning false
6315
- */
6316
- var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
6317
- if ( $.inArray( false, abStateLoad ) !== -1 ) {
6318
- return;
6319
- }
6320
+ // Reject old data
6321
+ var duration = settings.iStateDuration;
6322
+ if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
6323
+ callback();
6324
+ return;
6325
+ }
6320
6326
 
6321
- /* Reject old data */
6322
- var duration = settings.iStateDuration;
6323
- if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
6324
- return;
6325
- }
6327
+ // Number of columns have changed - all bets are off, no restore of settings
6328
+ if ( s.columns && columns.length !== s.columns.length ) {
6329
+ callback();
6330
+ return;
6331
+ }
6326
6332
 
6327
- // Number of columns have changed - all bets are off, no restore of settings
6328
- if ( columns.length !== state.columns.length ) {
6329
- return;
6330
- }
6333
+ // Store the saved state so it might be accessed at any time
6334
+ settings.oLoadedState = $.extend( true, {}, state );
6331
6335
 
6332
- // Store the saved state so it might be accessed at any time
6333
- settings.oLoadedState = $.extend( true, {}, state );
6336
+ // Restore key features - todo - for 1.11 this needs to be done by
6337
+ // subscribed events
6338
+ if ( s.start !== undefined ) {
6339
+ settings._iDisplayStart = s.start;
6340
+ settings.iInitDisplayStart = s.start;
6341
+ }
6342
+ if ( s.length !== undefined ) {
6343
+ settings._iDisplayLength = s.length;
6344
+ }
6334
6345
 
6335
- // Restore key features - todo - for 1.11 this needs to be done by
6336
- // subscribed events
6337
- if ( state.start !== undefined ) {
6338
- settings._iDisplayStart = state.start;
6339
- settings.iInitDisplayStart = state.start;
6340
- }
6341
- if ( state.length !== undefined ) {
6342
- settings._iDisplayLength = state.length;
6343
- }
6346
+ // Order
6347
+ if ( s.order !== undefined ) {
6348
+ settings.aaSorting = [];
6349
+ $.each( s.order, function ( i, col ) {
6350
+ settings.aaSorting.push( col[0] >= columns.length ?
6351
+ [ 0, col[1] ] :
6352
+ col
6353
+ );
6354
+ } );
6355
+ }
6344
6356
 
6345
- // Order
6346
- if ( state.order !== undefined ) {
6347
- settings.aaSorting = [];
6348
- $.each( state.order, function ( i, col ) {
6349
- settings.aaSorting.push( col[0] >= columns.length ?
6350
- [ 0, col[1] ] :
6351
- col
6352
- );
6353
- } );
6354
- }
6357
+ // Search
6358
+ if ( s.search !== undefined ) {
6359
+ $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
6360
+ }
6355
6361
 
6356
- // Search
6357
- if ( state.search !== undefined ) {
6358
- $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
6359
- }
6362
+ // Columns
6363
+ //
6364
+ if ( s.columns ) {
6365
+ for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
6366
+ var col = s.columns[i];
6360
6367
 
6361
- // Columns
6362
- for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
6363
- var col = state.columns[i];
6368
+ // Visibility
6369
+ if ( col.visible !== undefined ) {
6370
+ columns[i].bVisible = col.visible;
6371
+ }
6364
6372
 
6365
- // Visibility
6366
- if ( col.visible !== undefined ) {
6367
- columns[i].bVisible = col.visible;
6373
+ // Search
6374
+ if ( col.search !== undefined ) {
6375
+ $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
6376
+ }
6377
+ }
6368
6378
  }
6369
6379
 
6370
- // Search
6371
- if ( col.search !== undefined ) {
6372
- $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
6373
- }
6380
+ _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
6381
+ callback();
6382
+ }
6383
+
6384
+ if ( ! settings.oFeatures.bStateSave ) {
6385
+ callback();
6386
+ return;
6374
6387
  }
6375
6388
 
6376
- _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
6389
+ var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
6390
+
6391
+ if ( state !== undefined ) {
6392
+ loaded( state );
6393
+ }
6394
+ // otherwise, wait for the loaded callback to be executed
6377
6395
  }
6378
6396
 
6379
6397
 
@@ -6526,17 +6544,17 @@
6526
6544
  function _fnBindAction( n, oData, fn )
6527
6545
  {
6528
6546
  $(n)
6529
- .bind( 'click.DT', oData, function (e) {
6547
+ .on( 'click.DT', oData, function (e) {
6530
6548
  n.blur(); // Remove focus outline for mouse users
6531
6549
  fn(e);
6532
6550
  } )
6533
- .bind( 'keypress.DT', oData, function (e){
6551
+ .on( 'keypress.DT', oData, function (e){
6534
6552
  if ( e.which === 13 ) {
6535
6553
  e.preventDefault();
6536
6554
  fn(e);
6537
6555
  }
6538
6556
  } )
6539
- .bind( 'selectstart.DT', function () {
6557
+ .on( 'selectstart.DT', function () {
6540
6558
  /* Take the brutal approach to cancelling text selection */
6541
6559
  return false;
6542
6560
  } );
@@ -7664,7 +7682,8 @@
7664
7682
  }
7665
7683
 
7666
7684
  for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7667
- a = selector[i] && selector[i].split ?
7685
+ // Only split on simple strings - complex expressions will be jQuery selectors
7686
+ a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
7668
7687
  selector[i].split(',') :
7669
7688
  [ selector[i] ];
7670
7689
 
@@ -7804,6 +7823,7 @@
7804
7823
 
7805
7824
  var __row_selector = function ( settings, selector, opts )
7806
7825
  {
7826
+ var rows;
7807
7827
  var run = function ( sel ) {
7808
7828
  var selInt = _intVal( sel );
7809
7829
  var i, ien;
@@ -7815,13 +7835,15 @@
7815
7835
  return [ selInt ];
7816
7836
  }
7817
7837
 
7818
- var rows = _selector_row_indexes( settings, opts );
7838
+ if ( ! rows ) {
7839
+ rows = _selector_row_indexes( settings, opts );
7840
+ }
7819
7841
 
7820
7842
  if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7821
7843
  // Selector - integer
7822
7844
  return [ selInt ];
7823
7845
  }
7824
- else if ( ! sel ) {
7846
+ else if ( sel === null || sel === undefined || sel === '' ) {
7825
7847
  // Selector - none
7826
7848
  return rows;
7827
7849
  }
@@ -8134,7 +8156,7 @@
8134
8156
  addRow( data, klass );
8135
8157
 
8136
8158
  if ( row._details ) {
8137
- row._details.remove();
8159
+ row._details.detach();
8138
8160
  }
8139
8161
 
8140
8162
  row._details = $(rows);
@@ -8335,7 +8357,7 @@
8335
8357
  // can be an array of these items, comma separated list, or an array of comma
8336
8358
  // separated lists
8337
8359
 
8338
- var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
8360
+ var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8339
8361
 
8340
8362
 
8341
8363
  // r1 and r2 are redundant - but it means that the parameters match for the
@@ -9082,6 +9104,10 @@
9082
9104
  var t = $(table).get(0);
9083
9105
  var is = false;
9084
9106
 
9107
+ if ( table instanceof DataTable.Api ) {
9108
+ return true;
9109
+ }
9110
+
9085
9111
  $.each( DataTable.settings, function (i, o) {
9086
9112
  var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
9087
9113
  var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
@@ -9170,9 +9196,11 @@
9170
9196
  var args = Array.prototype.slice.call(arguments);
9171
9197
 
9172
9198
  // Add the `dt` namespace automatically if it isn't already present
9173
- if ( ! args[0].match(/\.dt\b/) ) {
9174
- args[0] += '.dt';
9175
- }
9199
+ args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
9200
+ return ! e.match(/\.dt\b/) ?
9201
+ e+'.dt' :
9202
+ e;
9203
+ } ).join( ' ' );
9176
9204
 
9177
9205
  var inst = $( this.tables().nodes() );
9178
9206
  inst[key].apply( inst, args );
@@ -9237,8 +9265,8 @@
9237
9265
  // Blitz all `DT` namespaced events (these are internal events, the
9238
9266
  // lowercase, `dt` events are user subscribed and they are responsible
9239
9267
  // for removing them
9240
- jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
9241
- $(window).unbind('.DT-'+settings.sInstance);
9268
+ jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9269
+ $(window).off('.DT-'+settings.sInstance);
9242
9270
 
9243
9271
  // When scrolling we had to break the table up - restore it
9244
9272
  if ( table != thead.parentNode ) {
@@ -9368,7 +9396,7 @@
9368
9396
  * @type string
9369
9397
  * @default Version number
9370
9398
  */
9371
- DataTable.version = "1.10.12";
9399
+ DataTable.version = "1.10.13";
9372
9400
 
9373
9401
  /**
9374
9402
  * Private data store, containing all of the settings objects that are
@@ -10876,6 +10904,8 @@
10876
10904
  * @type function
10877
10905
  * @member
10878
10906
  * @param {object} settings DataTables settings object
10907
+ * @param {object} callback Callback that can be executed when done. It
10908
+ * should be passed the loaded state object.
10879
10909
  * @return {object} The DataTables state object to be loaded
10880
10910
  *
10881
10911
  * @dtopt Callbacks
@@ -10885,21 +10915,14 @@
10885
10915
  * $(document).ready( function() {
10886
10916
  * $('#example').dataTable( {
10887
10917
  * "stateSave": true,
10888
- * "stateLoadCallback": function (settings) {
10889
- * var o;
10890
- *
10891
- * // Send an Ajax request to the server to get the data. Note that
10892
- * // this is a synchronous request.
10918
+ * "stateLoadCallback": function (settings, callback) {
10893
10919
  * $.ajax( {
10894
10920
  * "url": "/state_load",
10895
- * "async": false,
10896
10921
  * "dataType": "json",
10897
10922
  * "success": function (json) {
10898
- * o = json;
10923
+ * callback( json );
10899
10924
  * }
10900
10925
  * } );
10901
- *
10902
- * return o;
10903
10926
  * }
10904
10927
  * } );
10905
10928
  * } );
@@ -11838,14 +11861,15 @@
11838
11861
 
11839
11862
 
11840
11863
  /**
11841
- * DataTables features four different built-in options for the buttons to
11864
+ * DataTables features six different built-in options for the buttons to
11842
11865
  * display for pagination control:
11843
11866
  *
11867
+ * * `numbers` - Page number buttons only
11844
11868
  * * `simple` - 'Previous' and 'Next' buttons only
11845
11869
  * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11846
11870
  * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11847
- * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
11848
- * page numbers
11871
+ * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11872
+ * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11849
11873
  *
11850
11874
  * Further methods can be added using {@link DataTable.ext.oPagination}.
11851
11875
  * @type string
@@ -14494,6 +14518,10 @@
14494
14518
  full_numbers: function ( page, pages ) {
14495
14519
  return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14496
14520
  },
14521
+
14522
+ first_last_numbers: function (page, pages) {
14523
+ return ['first', _numbers(page, pages), 'last'];
14524
+ },
14497
14525
 
14498
14526
  // For testing and plug-ins to use
14499
14527
  _numbers: _numbers,
@@ -14605,7 +14633,7 @@
14605
14633
 
14606
14634
  attach( $(host).empty(), buttons );
14607
14635
 
14608
- if ( activeEl ) {
14636
+ if ( activeEl !== undefined ) {
14609
14637
  $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
14610
14638
  }
14611
14639
  }
@@ -14628,10 +14656,10 @@
14628
14656
  // Dates (only those recognised by the browser's Date.parse)
14629
14657
  function ( d, settings )
14630
14658
  {
14631
- // V8 will remove any unknown characters at the start and end of the
14632
- // expression, leading to false matches such as `$245.12` or `10%` being
14633
- // a valid date. See forum thread 18941 for detail.
14634
- if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
14659
+ // V8 tries _very_ hard to make a string passed into `Date.parse()`
14660
+ // valid, so we need to use a regex to restrict date formats. Use a
14661
+ // plug-in for anything other than ISO8601 style strings
14662
+ if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
14635
14663
  return null;
14636
14664
  }
14637
14665
  var parsed = Date.parse(d);
@@ -14768,7 +14796,7 @@
14768
14796
  $.extend( _ext.type.order, {
14769
14797
  // Dates
14770
14798
  "date-pre": function ( d ) {
14771
- return Date.parse( d ) || 0;
14799
+ return Date.parse( d ) || -Infinity;
14772
14800
  },
14773
14801
 
14774
14802
  // html
@@ -14939,6 +14967,7 @@
14939
14967
  return __htmlEscapeEntities( d );
14940
14968
  }
14941
14969
 
14970
+ flo = flo.toFixed( precision );
14942
14971
  d = Math.abs( flo );
14943
14972
 
14944
14973
  var intPart = parseInt( d, 10 );