jquery-datatables 1.10.12 → 1.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1951c5edc47ddce61d83357828033e75e7b35229
4
- data.tar.gz: a0f86f4402eafb18d4edf8e3f45b96fccc1a905a
3
+ metadata.gz: cf69e7f69f37cf3be807fb96646e14095ea5d3de
4
+ data.tar.gz: cb8525a65895232943f6278db27556476d187d6b
5
5
  SHA512:
6
- metadata.gz: 5d767632d30f637ef0ed41a9248220d3491ba1da4f7330122a0505644b75006248367cc231ee09494eddc58191b530a42d43a6f303eb2089158141e12675df01
7
- data.tar.gz: d6115130d079c5085920b01452ded32c61b58d707d9a9057336606fcb128f70b71865368c6f780ff27db0f934d0d042f06107f0d3e7b122d60ce2f73d70f9556
6
+ metadata.gz: bf421ef9efd98efb194a4ad76da45c93b17ae4cdb34a5fd93c494c45df46f5c0a4b9c67f0b0919e85da0f0cbdbedbbac6a1884f3bbd7db2b152461647062d205
7
+ data.tar.gz: 7bb1786138d0a17407af9bcd6607bc9a9414ed2f0736f841cfc33301124d72dbd4591aecab9b2a09bacc1225b0b82703d03882f57f83e1df0a5e09449ac3f46e
data/.gitignore CHANGED
@@ -21,3 +21,4 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  DataTablesSrc/
24
+ alphabetSearchSrc/
@@ -172,11 +172,11 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
172
172
  buttons
173
173
  );
174
174
 
175
- if ( activeEl ) {
175
+ if ( activeEl !== undefined ) {
176
176
  $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
177
177
  }
178
178
  };
179
179
 
180
180
 
181
181
  return DataTable;
182
- }));
182
+ }));
@@ -46,9 +46,9 @@ var DataTable = $.fn.dataTable;
46
46
  /* Set the defaults for DataTables initialisation */
47
47
  $.extend( true, DataTable.defaults, {
48
48
  dom:
49
- "<'row'<'col-md-6'l><'col-md-6'f>>" +
50
- "<'row'<'col-md-12'tr>>" +
51
- "<'row'<'col-md-5'i><'col-md-7'p>>",
49
+ "<'row'<'col-xs-12 col-md-6'l><'col-xs-12 col-md-6'f>>" +
50
+ "<'row'<'col-xs-12'tr>>" +
51
+ "<'row'<'col-xs-12 col-md-5'i><'col-xs-12 col-md-7'p>>",
52
52
  renderer: 'bootstrap'
53
53
  } );
54
54
 
@@ -174,11 +174,11 @@ DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, bu
174
174
  buttons
175
175
  );
176
176
 
177
- if ( activeEl ) {
177
+ if ( activeEl !== undefined ) {
178
178
  $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
179
179
  }
180
180
  };
181
181
 
182
182
 
183
183
  return DataTable;
184
- }));
184
+ }));
@@ -47,7 +47,7 @@ meta.remove();
47
47
 
48
48
  $.extend( DataTable.ext.classes, {
49
49
  sWrapper: "dataTables_wrapper dt-foundation",
50
- sProcessing: "dataTables_processing panel"
50
+ sProcessing: "dataTables_processing panel callout"
51
51
  } );
52
52
 
53
53
 
@@ -181,7 +181,7 @@ DataTable.ext.renderer.pageButton.material = function ( settings, host, idx, but
181
181
  buttons
182
182
  );
183
183
 
184
- if ( activeEl ) {
184
+ if ( activeEl !== undefined ) {
185
185
  $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
186
186
  }
187
187
  };
@@ -183,7 +183,7 @@ DataTable.ext.renderer.pageButton.semanticUI = function ( settings, host, idx, b
183
183
  buttons
184
184
  );
185
185
 
186
- if ( activeEl ) {
186
+ if ( activeEl !== undefined ) {
187
187
  $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
188
188
  }
189
189
  };
@@ -1,15 +1,15 @@
1
- /*! AutoFill 2.1.2
2
- * ©2008-2015 SpryMedia Ltd - datatables.net/license
1
+ /*! AutoFill 2.1.3
2
+ * ©2008-2016 SpryMedia Ltd - datatables.net/license
3
3
  */
4
4
 
5
5
  /**
6
6
  * @summary AutoFill
7
7
  * @description Add Excel like click and drag auto-fill options to DataTables
8
- * @version 2.1.2
8
+ * @version 2.1.3
9
9
  * @file dataTables.autoFill.js
10
10
  * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
11
  * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2010-2015 SpryMedia Ltd.
12
+ * @copyright Copyright 2010-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/mit
@@ -192,8 +192,6 @@ $.extend( AutoFill.prototype, {
192
192
  var idx = dt.cell( node ).index();
193
193
  var handle = this.dom.handle;
194
194
  var handleDim = this.s.handle;
195
- var dtScroll = $('div.dataTables_scrollBody', this.s.dt.table().container() );
196
- var scrollOffsetX=0, scrollOffsetY=0;
197
195
 
198
196
  if ( ! idx || dt.columns( this.c.columns ).indexes().indexOf( idx.column ) === -1 ) {
199
197
  this._detach();
@@ -201,7 +199,8 @@ $.extend( AutoFill.prototype, {
201
199
  }
202
200
 
203
201
  if ( ! this.dom.offsetParent ) {
204
- this.dom.offsetParent = $(node).offsetParent();
202
+ // We attach to the table's offset parent
203
+ this.dom.offsetParent = $( dt.table().node() ).offsetParent();
205
204
  }
206
205
 
207
206
  if ( ! handleDim.height || ! handleDim.width ) {
@@ -212,20 +211,14 @@ $.extend( AutoFill.prototype, {
212
211
  handleDim.width = handle.outerWidth();
213
212
  }
214
213
 
215
- var offset = $(node).position();
216
-
217
- // If scrolling, and the table is not itself the offset parent, need to
218
- // offset for the scrolling position
219
- if ( dtScroll.length && this.dom.offsetParent[0] !== dt.table().node() ) {
220
- scrollOffsetY = dtScroll.scrollTop();
221
- scrollOffsetX = dtScroll.scrollLeft();
222
- }
214
+ // Might need to go through multiple offset parents
215
+ var offset = this._getPosition( node, this.dom.offsetParent );
223
216
 
224
217
  this.dom.attachedTo = node;
225
218
  handle
226
219
  .css( {
227
- top: offset.top + node.offsetHeight - handleDim.height + scrollOffsetY,
228
- left: offset.left + node.offsetWidth - handleDim.width + scrollOffsetX
220
+ top: offset.top + node.offsetHeight - handleDim.height,
221
+ left: offset.left + node.offsetWidth - handleDim.width
229
222
  } )
230
223
  .appendTo( this.dom.offsetParent );
231
224
  },
@@ -327,6 +320,7 @@ $.extend( AutoFill.prototype, {
327
320
  row: dt.rows( { page: 'current' } ).nodes().indexOf( endCell.parent()[0] ),
328
321
  column: endCell.index()
329
322
  };
323
+ var colIndx = dt.column.index( 'toData', end.column );
330
324
 
331
325
  // Be sure that is a DataTables controlled cell
332
326
  if ( ! dt.cell( endCell ).any() ) {
@@ -334,7 +328,7 @@ $.extend( AutoFill.prototype, {
334
328
  }
335
329
 
336
330
  // if target is not in the columns available - do nothing
337
- if ( dt.columns( this.c.columns ).indexes().indexOf( end.column ) === -1 ) {
331
+ if ( dt.columns( this.c.columns ).indexes().indexOf( colIndx ) === -1 ) {
338
332
  return;
339
333
  }
340
334
 
@@ -347,16 +341,10 @@ $.extend( AutoFill.prototype, {
347
341
  left = start.column < end.column ? startCell : endCell;
348
342
  right = start.column < end.column ? endCell : startCell;
349
343
 
350
- top = top.position().top;
351
- left = left.position().left;
352
- height = bottom.position().top + bottom.outerHeight() - top;
353
- width = right.position().left + right.outerWidth() - left;
354
-
355
- var dtScroll = this.dom.dtScroll;
356
- if ( dtScroll && this.dom.offsetParent[0] !== dt.table().node() ) {
357
- top += dtScroll.scrollTop();
358
- left += dtScroll.scrollLeft();
359
- }
344
+ top = this._getPosition( top ).top;
345
+ left = this._getPosition( left ).left;
346
+ height = this._getPosition( bottom ).top + bottom.outerHeight() - top;
347
+ width = this._getPosition( right ).left + right.outerWidth() - left;
360
348
 
361
349
  var select = this.dom.select;
362
350
  select.top.css( {
@@ -486,7 +474,7 @@ $.extend( AutoFill.prototype, {
486
474
  var namespace = this.s.namespace;
487
475
  var focus = this.c.focus !== null ?
488
476
  this.c.focus :
489
- dt.settings()[0].keytable ?
477
+ dt.init().keys || dt.settings()[0].keytable ?
490
478
  'focus' :
491
479
  'hover';
492
480
 
@@ -528,6 +516,50 @@ $.extend( AutoFill.prototype, {
528
516
  },
529
517
 
530
518
 
519
+ /**
520
+ * Get the position of a node, relative to another, including any scrolling
521
+ * offsets.
522
+ * @param {Node} node Node to get the position of
523
+ * @param {jQuery} targetParent Node to use as the parent
524
+ * @return {object} Offset calculation
525
+ * @private
526
+ */
527
+ _getPosition: function ( node, targetParent )
528
+ {
529
+ var
530
+ currNode = $(node),
531
+ currOffsetParent,
532
+ position,
533
+ top = 0,
534
+ left = 0;
535
+
536
+ if ( ! targetParent ) {
537
+ targetParent = $( this.s.dt.table().node() ).offsetParent();
538
+ }
539
+
540
+ do {
541
+ position = currNode.position();
542
+ currOffsetParent = currNode.offsetParent();
543
+
544
+ top += position.top + currOffsetParent.scrollTop();
545
+ left += position.left + currOffsetParent.scrollLeft();
546
+
547
+ // Emergency fall back. Shouldn't happen, but just in case!
548
+ if ( currNode.get(0).nodeName.toLowerCase() === 'body' ) {
549
+ break;
550
+ }
551
+
552
+ currNode = currOffsetParent; // for next loop
553
+ }
554
+ while ( currOffsetParent.get(0) !== targetParent.get(0) )
555
+
556
+ return {
557
+ top: top,
558
+ left: left
559
+ };
560
+ },
561
+
562
+
531
563
  /**
532
564
  * Start mouse drag - selects the start cell
533
565
  *
@@ -554,7 +586,7 @@ $.extend( AutoFill.prototype, {
554
586
  } );
555
587
 
556
588
  var select = this.dom.select;
557
- var offsetParent = $(this.s.dt.table().body()).offsetParent();
589
+ var offsetParent = $( dt.table().node() ).offsetParent();
558
590
  select.top.appendTo( offsetParent );
559
591
  select.left.appendTo( offsetParent );
560
592
  select.right.appendTo( offsetParent );
@@ -970,7 +1002,7 @@ AutoFill.actions = {
970
1002
  * @static
971
1003
  * @type String
972
1004
  */
973
- AutoFill.version = '2.1.2';
1005
+ AutoFill.version = '2.1.3';
974
1006
 
975
1007
 
976
1008
  /**
@@ -104,12 +104,11 @@ $.extend( DataTable.ext.buttons, {
104
104
  },
105
105
  init: function ( dt, button, conf ) {
106
106
  var that = this;
107
- var col = dt.column( conf.columns );
108
107
 
109
108
  dt
110
109
  .on( 'column-visibility.dt'+conf.namespace, function (e, settings) {
111
110
  if ( ! settings.bDestroying ) {
112
- that.active( col.visible() );
111
+ that.active( dt.column( conf.columns ).visible() );
113
112
  }
114
113
  } )
115
114
  .on( 'column-reorder.dt'+conf.namespace, function (e, settings, details) {
@@ -129,7 +128,7 @@ $.extend( DataTable.ext.buttons, {
129
128
  that.active( col.visible() );
130
129
  } );
131
130
 
132
- this.active( col.visible() );
131
+ this.active( dt.column( conf.columns ).visible() );
133
132
  },
134
133
  destroy: function ( dt, button, conf ) {
135
134
  dt
@@ -745,14 +745,28 @@ function _createNode( doc, nodeName, opts ){
745
745
  */
746
746
  function _excelColWidth( data, col ) {
747
747
  var max = data.header[col].length;
748
- var len;
748
+ var len, lineSplit, str;
749
749
 
750
750
  if ( data.footer && data.footer[col].length > max ) {
751
751
  max = data.footer[col].length;
752
752
  }
753
753
 
754
754
  for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
755
- len = data.body[i][col].toString().length;
755
+ str = data.body[i][col].toString();
756
+
757
+ // If there is a newline character, workout the width of the column
758
+ // based on the longest line in the string
759
+ if ( str.indexOf('\n') !== -1 ) {
760
+ lineSplit = str.split('\n');
761
+ lineSplit.sort( function (a, b) {
762
+ return b.length - a.length;
763
+ } );
764
+
765
+ len = lineSplit[0].length;
766
+ }
767
+ else {
768
+ len = str.length;
769
+ }
756
770
 
757
771
  if ( len > max ) {
758
772
  max = len;
@@ -764,8 +778,10 @@ function _excelColWidth( data, col ) {
764
778
  }
765
779
  }
766
780
 
781
+ max *= 1.3;
782
+
767
783
  // And a min width
768
- return max > 5 ? max : 5;
784
+ return max > 6 ? max : 6;
769
785
  }
770
786
 
771
787
  try {
@@ -835,11 +851,9 @@ function _xlsxToStrings( obj ) {
835
851
  str = str.replace( /_dt_b_namespace_token_/g, ':' );
836
852
  }
837
853
 
838
- // Both IE and Edge will put empty name space attributes onto the
839
- // rows and columns making them useless
840
- str = str
841
- .replace( /<row xmlns="" /g, '<row ' )
842
- .replace( /<cols xmlns="">/g, '<cols>' );
854
+ // Safari, IE and Edge will put empty name space attributes onto
855
+ // various elements making them useless. This strips them out
856
+ str = str.replace( /<(.*?) xmlns=""(.*?)>/g, '<$1 $2>' );
843
857
 
844
858
  obj[ name ] = str;
845
859
  }
@@ -891,9 +905,17 @@ var excelStrings = {
891
905
  '<sheetData/>'+
892
906
  '</worksheet>',
893
907
 
894
- "xl/styles.xml":
908
+ "xl/styles.xml":
895
909
  '<?xml version="1.0" encoding="UTF-8"?>'+
896
910
  '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+
911
+ '<numFmts count="6">'+
912
+ '<numFmt numFmtId="164" formatCode="#,##0.00_-\ [$$-45C]"/>'+
913
+ '<numFmt numFmtId="165" formatCode="&quot;£&quot;#,##0.00"/>'+
914
+ '<numFmt numFmtId="166" formatCode="[$€-2]\ #,##0.00"/>'+
915
+ '<numFmt numFmtId="167" formatCode="0.0%"/>'+
916
+ '<numFmt numFmtId="168" formatCode="#,##0;(#,##0)"/>'+
917
+ '<numFmt numFmtId="169" formatCode="#,##0.00;(#,##0.00)"/>'+
918
+ '</numFmts>'+
897
919
  '<fonts count="5" x14ac:knownFonts="1">'+
898
920
  '<font>'+
899
921
  '<sz val="11" />'+
@@ -977,7 +999,7 @@ var excelStrings = {
977
999
  '<cellStyleXfs count="1">'+
978
1000
  '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />'+
979
1001
  '</cellStyleXfs>'+
980
- '<cellXfs count="2">'+
1002
+ '<cellXfs count="61">'+
981
1003
  '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
982
1004
  '<xf numFmtId="0" fontId="1" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
983
1005
  '<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
@@ -1028,6 +1050,33 @@ var excelStrings = {
1028
1050
  '<xf numFmtId="0" fontId="2" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
1029
1051
  '<xf numFmtId="0" fontId="3" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
1030
1052
  '<xf numFmtId="0" fontId="4" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
1053
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1054
+ '<alignment horizontal="left"/>'+
1055
+ '</xf>'+
1056
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1057
+ '<alignment horizontal="center"/>'+
1058
+ '</xf>'+
1059
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1060
+ '<alignment horizontal="right"/>'+
1061
+ '</xf>'+
1062
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1063
+ '<alignment horizontal="fill"/>'+
1064
+ '</xf>'+
1065
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1066
+ '<alignment textRotation="90"/>'+
1067
+ '</xf>'+
1068
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
1069
+ '<alignment wrapText="1"/>'+
1070
+ '</xf>'+
1071
+ '<xf numFmtId="9" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1072
+ '<xf numFmtId="164" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1073
+ '<xf numFmtId="165" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1074
+ '<xf numFmtId="166" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1075
+ '<xf numFmtId="167" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1076
+ '<xf numFmtId="168" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1077
+ '<xf numFmtId="169" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1078
+ '<xf numFmtId="3" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1079
+ '<xf numFmtId="4" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
1031
1080
  '</cellXfs>'+
1032
1081
  '<cellStyles count="1">'+
1033
1082
  '<cellStyle name="Normal" xfId="0" builtinId="0" />'+
@@ -1039,6 +1088,20 @@ var excelStrings = {
1039
1088
  // Note we could use 3 `for` loops for the styles, but when gzipped there is
1040
1089
  // virtually no difference in size, since the above can be easily compressed
1041
1090
 
1091
+ // Pattern matching for special number formats. Perhaps this should be exposed
1092
+ // via an API in future?
1093
+ var _excelSpecials = [
1094
+ { match: /^\-?\d+\.\d%$/, style: 60, fmt: function (d) { return d/100; } }, // Precent with d.p.
1095
+ { match: /^\-?\d+\.?\d*%$/, style: 56, fmt: function (d) { return d/100; } }, // Percent
1096
+ { match: /^\-?\$[\d,]+.?\d*$/, style: 57 }, // Dollars
1097
+ { match: /^\-?£[\d,]+.?\d*$/, style: 58 }, // Pounds
1098
+ { match: /^\-?€[\d,]+.?\d*$/, style: 59 }, // Euros
1099
+ { match: /^\([\d,]+\)$/, style: 61, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets
1100
+ { match: /^\([\d,]+\.\d{2}\)$/, style: 62, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets - 2d.p.
1101
+ { match: /^[\d,]+$/, style: 63 }, // Numbers with thousand separators
1102
+ { match: /^[\d,]+\.\d{2}$/, style: 64 } // Numbers with 2d.p. and thousands separators
1103
+ ];
1104
+
1042
1105
 
1043
1106
 
1044
1107
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -1166,58 +1229,85 @@ DataTable.ext.buttons.excelFlash = $.extend( {}, flashButton, {
1166
1229
  for ( var i=0, ien=row.length ; i<ien ; i++ ) {
1167
1230
  // Concat both the Cell Columns as a letter and the Row of the cell.
1168
1231
  var cellId = createCellPos(i) + '' + currentRow;
1169
- var cell;
1232
+ var cell = null;
1170
1233
 
1171
- if ( row[i] === null || row[i] === undefined ) {
1172
- row[i] = '';
1234
+ // For null, undefined of blank cell, continue so it doesn't create the _createNode
1235
+ if ( row[i] === null || row[i] === undefined || row[i] === '' ) {
1236
+ continue;
1173
1237
  }
1174
1238
 
1175
- // Detect numbers - don't match numbers with leading zeros or a negative
1176
- // anywhere but the start
1177
- if ( typeof row[i] === 'number' || (
1178
- row[i].match &&
1179
- $.trim(row[i]).match(/^-?\d+(\.\d+)?$/) &&
1180
- ! $.trim(row[i]).match(/^0\d+/) )
1181
- ) {
1182
- cell = _createNode( rels, 'c', {
1183
- attr: {
1184
- t: 'n',
1185
- r: cellId
1186
- },
1187
- children: [
1188
- _createNode( rels, 'v', { text: row[i] } )
1189
- ]
1190
- } );
1191
- }
1192
- else {
1193
- // Replace non standard characters for text output
1194
- var text = ! row[i].replace ?
1195
- row[i] :
1196
- row[i]
1197
- .replace(/&(?!amp;)/g, '&amp;')
1198
- .replace(/</g, '&lt;')
1199
- .replace(/>/g, '&gt;')
1200
- .replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, '');
1201
-
1202
- cell = _createNode( rels, 'c', {
1203
- attr: {
1204
- t: 'inlineStr',
1205
- r: cellId
1206
- },
1207
- children:{
1208
- row: _createNode( rels, 'is', {
1209
- children: {
1210
- row: _createNode( rels, 't', {
1211
- text: text
1212
- } )
1213
- }
1214
- } )
1239
+ row[i] = $.trim( row[i] );
1240
+
1241
+ // Special number formatting options
1242
+ for ( var j=0, jen=_excelSpecials.length ; j<jen ; j++ ) {
1243
+ var special = _excelSpecials[j];
1244
+
1245
+ if ( row[i].match && row[i].match( special.match ) ) {
1246
+ var val = row[i].replace(/[^\d\.\-]/g, '');
1247
+
1248
+ if ( special.fmt ) {
1249
+ val = special.fmt( val );
1215
1250
  }
1216
- } );
1251
+
1252
+ cell = _createNode( rels, 'c', {
1253
+ attr: {
1254
+ r: cellId,
1255
+ s: special.style
1256
+ },
1257
+ children: [
1258
+ _createNode( rels, 'v', { text: val } )
1259
+ ]
1260
+ } );
1261
+
1262
+ break;
1263
+ }
1264
+ }
1265
+
1266
+ if ( ! cell ) {
1267
+ if ( typeof row[i] === 'number' || (
1268
+ row[i].match &&
1269
+ row[i].match(/^-?\d+(\.\d+)?$/) &&
1270
+ ! row[i].match(/^0\d+/) )
1271
+ ) {
1272
+ // Detect numbers - don't match numbers with leading zeros
1273
+ // or a negative anywhere but the start
1274
+ cell = _createNode( rels, 'c', {
1275
+ attr: {
1276
+ t: 'n',
1277
+ r: cellId
1278
+ },
1279
+ children: [
1280
+ _createNode( rels, 'v', { text: row[i] } )
1281
+ ]
1282
+ } );
1283
+ }
1284
+ else {
1285
+ // String output - replace non standard characters for text output
1286
+ var text = ! row[i].replace ?
1287
+ row[i] :
1288
+ row[i].replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, '');
1289
+
1290
+ cell = _createNode( rels, 'c', {
1291
+ attr: {
1292
+ t: 'inlineStr',
1293
+ r: cellId
1294
+ },
1295
+ children:{
1296
+ row: _createNode( rels, 'is', {
1297
+ children: {
1298
+ row: _createNode( rels, 't', {
1299
+ text: text
1300
+ } )
1301
+ }
1302
+ } )
1303
+ }
1304
+ } );
1305
+ }
1217
1306
  }
1218
1307
 
1219
1308
  rowNode.appendChild( cell );
1220
1309
  }
1310
+
1221
1311
  relsGet.appendChild(rowNode);
1222
1312
  rowPos++;
1223
1313
  };
@@ -1299,7 +1389,7 @@ DataTable.ext.buttons.pdfFlash = $.extend( {}, flashButton, {
1299
1389
 
1300
1390
  _setText( flash, JSON.stringify( {
1301
1391
  title: _filename(config, false),
1302
- message: config.message,
1392
+ message: typeof config.message == 'function' ? config.message(dt, button, config) : config.message,
1303
1393
  colWidth: ratios.toArray(),
1304
1394
  orientation: config.orientation,
1305
1395
  size: config.pageSize,