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
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,