Skip to content
Snippets Groups Projects
jquery.tabletojson.js 4.45 KiB
Newer Older
  • Learn to ignore specific revisions
  • (function( $ ) {
      'use strict';
    
      $.fn.tableToJSON = function(opts) {
    
        // Set options
        var defaults = {
          ignoreColumns: [],
          onlyColumns: null,
          ignoreHiddenRows: true,
          headings: null,
          allowHTML: false
        };
        opts = $.extend(defaults, opts);
    
        var notNull = function(value) {
          return value !== undefined && value !== null;
        };
    
        var ignoredColumn = function(index) {
          if( notNull(opts.onlyColumns) ) {
            return $.inArray(index, opts.onlyColumns) === -1;
          }
          return $.inArray(index, opts.ignoreColumns) !== -1;
        };
    
        var arraysToHash = function(keys, values) {
          var result = {}, index = 0;
          $.each(values, function(i, value) {
            // when ignoring columns, the header option still starts
            // with the first defined column
            if ( index < keys.length && notNull(value) ) {
              result[ keys[index] ] = value;
              index++;
            }
          });
          return result;
        };
    
        var cellValues = function(cellIndex, cell) {
          var value, result;
          var override = $(cell).data('override');
          if ( opts.allowHTML ) {
            value = $.trim($(cell).html());
          } else {
            value = $.trim($(cell).text());
          }
          result = notNull(override) ? override : value;
          return result;
        };
    
        var rowValues = function(row) {
          var result = [];
          $(row).children('td,th').each(function(cellIndex, cell) {
            result.push( cellValues(cellIndex, cell) );
          });
          return result;
        };
    
        var getHeadings = function(table) {
          var firstRow = table.find('tr:first').first();
          return notNull(opts.headings) ? opts.headings : rowValues(firstRow);
        };
    
        var construct = function(table, headings) {
          var i, j, len, len2, txt, $row, $cell,
            tmpArray = [], cellIndex = 0, result = [];
          table.children('tbody,*').children('tr').each(function(rowIndex, row) {
            if( rowIndex > 0 || notNull(opts.headings) ) {
              $row = $(row);
              if( $row.is(':visible') || !opts.ignoreHiddenRows ) {
                if (!tmpArray[rowIndex]) {
                  tmpArray[rowIndex] = [];
                }
                cellIndex = 0;
                $row.children().each(function(){
                  $cell = $(this);
    
                  // process rowspans
                  if ($cell.filter('[rowspan]').length) {
                    len = parseInt( $cell.attr('rowspan'), 10) - 1;
                    txt = cellValues(cellIndex, $cell, []);
                    for (i = 1; i <= len; i++) {
                      if (!tmpArray[rowIndex + i]) { tmpArray[rowIndex + i] = []; }
                      tmpArray[rowIndex + i][cellIndex] = txt;
                    }
                  }
                  // process colspans
                  if ($cell.filter('[colspan]').length) {
                    len = parseInt( $cell.attr('colspan'), 10) - 1;
                    txt = cellValues(cellIndex, $cell, []);
                    for (i = 1; i <= len; i++) {
                      // cell has both col and row spans
                      if ($cell.filter('[rowspan]').length) {
                        len2 = parseInt( $cell.attr('rowspan'), 10);
                        for (j = 0; j < len2; j++) {
                          tmpArray[rowIndex + j][cellIndex + i] = txt;
                        }
                      } else {
                        tmpArray[rowIndex][cellIndex + i] = txt;
                      }
                    }
                  }
                  // skip column if already defined
                  while (tmpArray[rowIndex][cellIndex]) { cellIndex++; }
                  txt = tmpArray[rowIndex][cellIndex] || cellValues(cellIndex, $cell, []);
                  if (notNull(txt)) {
                    tmpArray[rowIndex][cellIndex] = txt;
                  }
                  cellIndex++;
                });
              }
            }
          });
          $.each(tmpArray, function( i, row ){
            if (notNull(row)) {
              // remove ignoredColumns / add onlyColumns
              var newRow = notNull(opts.onlyColumns) || opts.ignoreColumns.length ?
                $.grep(row, function(v, index){ return !ignoredColumn(index); }) : row,
    
                // remove ignoredColumns / add onlyColumns if headings is not defined
                newHeadings = notNull(opts.headings) ? headings :
                  $.grep(headings, function(v, index){ return !ignoredColumn(index); });
    
              txt = arraysToHash(newHeadings, newRow);
              result[result.length] = txt;
            }
          });
          return result;
        };
    
        // Run
        var headings = getHeadings(this);
        return construct(this, headings);
      };
    })( jQuery );