PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/ajax/libs/jquery.tablesorter/2.16.4/widgets/widget-output.js

https://gitlab.com/Blueprint-Marketing/cdnjs
JavaScript | 276 lines | 235 code | 12 blank | 29 comment | 11 complexity | 6c96d02341f97bb872521a7176deaffd MD5 | raw file
  1. /* Output widget (beta) for TableSorter 5/5/2014 (v2.16.4)
  2. * Requires tablesorter v2.8+ and jQuery 1.7+
  3. * Modified from:
  4. * HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
  5. * Download-File-JS: https://github.com/PixelsCommander/Download-File-JS (http://www.apache.org/licenses/LICENSE-2.0)
  6. */
  7. /*jshint browser:true, jquery:true, unused:false */
  8. /*global jQuery: false */
  9. ;(function($){
  10. "use strict";
  11. var ts = $.tablesorter,
  12. output = ts.output = {
  13. event : 'outputTable',
  14. // wrap line breaks & tabs in quotes
  15. regexQuote : /([\n\t]|<[^<]+>)/, // test
  16. regexBR : /(<br([\s\/])?>|\n)/g, // replace
  17. regexIMG : /<img[^>]+alt\s*=\s*['"]([^'"]+)['"][^>]*>/i, // match
  18. regexHTML : /<[^<]+>/g, // replace
  19. replaceCR : '\\n',
  20. replaceTab : '\\t',
  21. popupTitle : 'Output',
  22. popupStyle : 'width:100%;height:100%;', // for textarea
  23. message : 'Your device does not support downloading. Please try again in desktop browser.',
  24. init : function(c) {
  25. c.$table
  26. .off(output.event)
  27. .on(output.event, function(){
  28. // explicitly use table.config.widgetOptions because we want
  29. // the most up-to-date values; not the "wo" from initialization
  30. output.process(c, c.widgetOptions);
  31. });
  32. },
  33. processRow: function(c, $rows, isHeader, isJSON) {
  34. var $this, row, col, rowlen, collen, txt,
  35. wo = c.widgetOptions,
  36. tmpRow = [],
  37. addSpanIndex = isHeader && isJSON && wo.output_headerRows && $.isFunction(wo.output_callbackJSON),
  38. cellIndex = 0;
  39. $rows.each(function(rowIndex) {
  40. if (!tmpRow[rowIndex]) { tmpRow[rowIndex] = []; }
  41. cellIndex = 0;
  42. $(this).children().each(function(){
  43. $this = $(this);
  44. // process rowspans
  45. if ($this.filter('[rowspan]').length) {
  46. rowlen = parseInt( $this.attr('rowspan'), 10) - 1;
  47. txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
  48. for (row = 1; row <= rowlen; row++) {
  49. if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
  50. tmpRow[rowIndex + row][cellIndex] = txt;
  51. }
  52. }
  53. // process colspans
  54. if ($this.filter('[colspan]').length) {
  55. collen = parseInt( $this.attr('colspan'), 10) - 1;
  56. txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
  57. for (col = 1; col <= collen; col++) {
  58. // if we're processing the header & making JSON, the header names need to be unique
  59. if ($this.filter('[rowspan]').length) {
  60. rowlen = parseInt( $this.attr('rowspan'), 10);
  61. for (row = 0; row < rowlen; row++) {
  62. if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
  63. tmpRow[rowIndex + row][cellIndex + col] = addSpanIndex ?
  64. wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : txt;
  65. }
  66. } else {
  67. tmpRow[rowIndex][cellIndex + col] = addSpanIndex ?
  68. wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : txt;
  69. }
  70. }
  71. }
  72. // don't include hidden columns
  73. if ( $this.css('display') !== 'none' ) {
  74. // skip column if already defined
  75. while (tmpRow[rowIndex][cellIndex]) { cellIndex++; }
  76. tmpRow[rowIndex][cellIndex] = tmpRow[rowIndex][cellIndex] ||
  77. output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
  78. cellIndex++;
  79. }
  80. });
  81. });
  82. return tmpRow;
  83. },
  84. process : function(c, wo) {
  85. var mydata, $this, $rows, headers, csvData, len,
  86. hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
  87. indx = 0,
  88. tmpData = (wo.output_separator || ',').toLowerCase(),
  89. outputJSON = tmpData === 'json',
  90. outputArray = tmpData === 'array',
  91. separator = outputJSON || outputArray ? ',' : wo.output_separator,
  92. $el = c.$table;
  93. // regex to look for the set separator or HTML
  94. wo.output_regex = new RegExp('(' + (/\\/.test(separator) ? '\\' : '' ) + separator + ')' );
  95. // get header cells
  96. $this = $el.find('thead tr:visible').not('.' + (ts.css.filterRow || 'tablesorter-filter-row') );
  97. headers = output.processRow(c, $this, true, outputJSON);
  98. // all tbody rows
  99. $rows = $el.children('tbody').children('tr');
  100. // get (f)iltered, (v)isible or all rows (look for the first letter only)
  101. $rows = /f/.test(wo.output_saveRows) ? $rows.not('.' + (wo.filter_filteredRow || 'filtered') ) :
  102. /v/.test(wo.output_saveRows) ? $rows.filter(':visible') : $rows;
  103. // process to array of arrays
  104. csvData = output.processRow(c, $rows);
  105. len = headers.length;
  106. if (outputJSON) {
  107. tmpData = [];
  108. $.each( csvData, function(indx, val){
  109. // multiple header rows & output_headerRows = true, pick the last row...
  110. tmpData.push( output.row2Hash( headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1], val ) );
  111. });
  112. // requires JSON stringify; if it doesn't exist, the output will show [object Object],... in the output window
  113. mydata = hasStringify ? JSON.stringify(tmpData) : tmpData;
  114. } else {
  115. tmpData = output.row2CSV(wo, wo.output_headerRows ? headers : [ headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1] ], outputArray)
  116. .concat( output.row2CSV(wo, csvData, outputArray) );
  117. // stringify the array; if stringify doesn't exist the array will be flattened
  118. mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
  119. }
  120. // callback; if true returned, continue processing
  121. if (!wo.output_callback(mydata)) { return; }
  122. if ( /p/.test( (wo.output_delivery || '').toLowerCase() ) ) {
  123. output.popup(mydata, wo.output_popupStyle, outputJSON || outputArray);
  124. } else {
  125. output.download(wo, mydata);
  126. }
  127. }, // end process
  128. row2CSV : function(wo, tmpRow, outputArray) {
  129. var tmp, rowIndex,
  130. csvData = [],
  131. rowLen = tmpRow.length;
  132. for (rowIndex = 0; rowIndex < rowLen; rowIndex++) {
  133. // remove any blank rows
  134. tmp = tmpRow[rowIndex].join('').replace(/\"/g,'');
  135. if (tmpRow[rowIndex].length > 0 && tmp !== '') {
  136. csvData[csvData.length] = outputArray ? tmpRow[rowIndex] : tmpRow[rowIndex].join(wo.output_separator);
  137. }
  138. }
  139. return csvData;
  140. },
  141. row2Hash : function(keys, values) {
  142. var json = {};
  143. $.each(values, function(indx, val) {
  144. if ( indx < keys.length ) {
  145. json[ keys[indx] ] = val;
  146. }
  147. });
  148. return json;
  149. },
  150. formatData : function(wo, input, isHeader) {
  151. var txt,
  152. quotes = (wo.output_separator || ',').toLowerCase(),
  153. separator = quotes === 'json' || quotes === 'array',
  154. // replace " with “ if undefined
  155. result = input.replace(/\"/g, wo.output_replaceQuote || '\u201c');
  156. // replace line breaks with \\n & tabs with \\t
  157. result = result.replace(output.regexBR, output.replaceCR).replace(/\t/g, output.replaceTab);
  158. // extract img alt text
  159. txt = result.match(output.regexIMG);
  160. if (!wo.output_includeHTML && txt !== null) {
  161. result = txt[1];
  162. }
  163. // replace/remove html
  164. result = wo.output_includeHTML && !isHeader ? result : result.replace(output.regexHTML, '');
  165. result = wo.output_trimSpaces || isHeader ? $.trim(result) : result;
  166. // JSON & array outputs don't need quotes
  167. quotes = separator ? false : wo.output_wrapQuotes || wo.output_regex.test(result) || output.regexQuote.test(result);
  168. return quotes ? '"' + result + '"' : result;
  169. },
  170. popup : function(data, style, wrap) {
  171. var generator = window.open('', output.popupTitle, style);
  172. generator.document.write(
  173. '<html><head><title>' + output.popupTitle + '</title></head><body>' +
  174. '<textarea wrap="' + (wrap ? 'on' : 'off') + '" style="' + output.popupStyle + '">' + data + '\n</textarea>' +
  175. '</body></html>'
  176. );
  177. generator.document.close();
  178. generator.focus();
  179. // select all text and focus within the textarea in the popup
  180. // $(generator.document).find('textarea').select().focus();
  181. return true;
  182. },
  183. // modified from https://github.com/PixelsCommander/Download-File-JS
  184. download : function (wo, data){
  185. var e, link,
  186. processedData = wo.output_encoding + encodeURIComponent(data);
  187. // iOS devices do not support downloading. We have to inform user about this.
  188. if (/(iP)/g.test(navigator.userAgent)) {
  189. alert(output.message);
  190. return false;
  191. }
  192. // If in Chrome or Safari - download via virtual link click
  193. if ( /(chrome|safari)/.test(navigator.userAgent.toLowerCase()) ) {
  194. // Creating new link node.
  195. link = document.createElement('a');
  196. link.href = processedData;
  197. link.download = wo.output_saveFileName;
  198. // Dispatching click event.
  199. if (document.createEvent) {
  200. e = document.createEvent('MouseEvents');
  201. e.initEvent('click', true, true);
  202. link.dispatchEvent(e);
  203. return true;
  204. }
  205. }
  206. // Force file download (whether supported by server).
  207. processedData += '?download';
  208. window.open(processedData, '_self');
  209. return true;
  210. },
  211. remove : function(c) {
  212. c.$table.off(output.event);
  213. }
  214. };
  215. ts.addWidget({
  216. id: "output",
  217. options: {
  218. output_separator : ',', // set to "json", "array" or any separator
  219. output_dataAttrib : 'data-name', // header attrib containing modified header name
  220. output_headerRows : false, // if true, include multiple header rows (JSON only)
  221. output_delivery : 'popup', // popup, download
  222. output_saveRows : 'filtered', // all, visible or filtered
  223. output_replaceQuote : '\u201c;', // left double quote
  224. output_includeHTML : false,
  225. output_trimSpaces : true,
  226. output_wrapQuotes : false,
  227. output_popupStyle : 'width=500,height=300',
  228. output_saveFileName : 'mytable.csv',
  229. // callback executed when processing completes
  230. // return true to continue download/output
  231. // return false to stop delivery & do something else with the data
  232. output_callback : function(data){ return true; },
  233. // JSON callback executed when a colspan is encountered in the header
  234. output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex) + ')'; },
  235. // output data type (with BOM or Windows-1252 is needed for excel)
  236. // NO BOM : 'data:text/csv;charset=utf8,'
  237. // With BOM : 'data:text/csv;charset=utf8,%EF%BB%BF'
  238. // WIN 1252 : 'data:text/csv;charset=windows-1252'
  239. output_encoding : 'data:text/csv;charset=utf8,'
  240. },
  241. init: function(table, thisWidget, c) {
  242. output.init(c);
  243. },
  244. remove: function(table, c){
  245. output.remove(c);
  246. }
  247. });
  248. })(jQuery);