21

I need to take table rows and convert to JSON.

Any ideas? I have this code here but it does not work.

function tableToJSON(tableID) {
    return $(tableID + "  tr").map(function (row) {
        return row.descendants().pluck("innerHTML");
    }).toJSON();
}
Rocket Hazmat
  • 204,503
  • 39
  • 283
  • 323
Nate
  • 1,974
  • 4
  • 22
  • 44
  • 1
    I'll look for a way to do it, but why? HTML tables are a way to display data, not to store it. – bigblind Jun 07 '11 at 21:31
  • @bigblind it's a pretty common thing, often used when scraping a website, to want to turn data that's not publicly available in any form other than a table, into a usable format, such as JSON. – GeorgeWL May 27 '19 at 01:22

7 Answers7

27
function tableToJson(table) {
    var data = [];

    // first row needs to be headers
    var headers = [];
    for (var i=0; i<table.rows[0].cells.length; i++) {
        headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
    }

    // go through cells
    for (var i=1; i<table.rows.length; i++) {

        var tableRow = table.rows[i];
        var rowData = {};

        for (var j=0; j<tableRow.cells.length; j++) {

            rowData[ headers[j] ] = tableRow.cells[j].innerHTML;

        }

        data.push(rowData);
    }       

    return data;
}

Taken from John Dyer's Blog

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
slandau
  • 21,956
  • 39
  • 117
  • 179
  • 14
    @Awena The author should be credited for their work. – mikemaccana Oct 06 '14 at 18:02
  • 1
    Seems to be broken with tables that use thead, tbody tags. – backdesk Dec 04 '14 at 11:14
  • 3
    It seems that the answer is an **plagiarism**. Like @John Dyer said, it seems that it came from [johndyer.name/html-table-to-json](http://www.johndyer.name/html-table-to-json/) –  May 22 '15 at 00:08
  • @JohnDyer I have added the link as attribution as it was a direct copy of the code and is against SO's plagiarism policy. Thanks, – Bhargav Rao Oct 17 '15 at 15:45
4

I was unhappy with all the solutions above and ended up writing my own jQuery plugin to accomplish this. It is very similar to the solution but accepts several options to customize the results, such as ignoring hidden rows, overriding column names, and overriding cell values

The plugin can be found here along with some examples if this is more what your looking for: https://github.com/lightswitch05/table-to-json

lightswitch05
  • 8,149
  • 6
  • 45
  • 71
3

This one worked for me: (I had only 2 lines in my table, th and td)

function htmlToJson(table) {
    var obj = {},
        itemsLength = $(table.find('tbody tr')[0]).find('th').length;
    for (i=0;i<itemsLength;i++) {
        key = $(table.find('tbody tr')[0]).find('th').eq(i).text();
        value = $(table.find('tbody tr')[1]).find('td').eq(i).text();
        obj[key] = value;
    }
    return JSON.stringify(obj)
}
3

HTML table with thead and tbody:

    function htmlTableToJson(table, edit = 0, del = 0) {
        // If exists the cols: "edit" and "del" to remove from JSON just pass values = 1 to edit and del params
        var minus = edit + del;
        var data = [];
        var colsLength = $(table.find('thead tr')[0]).find('th').length - minus;
        var rowsLength = $(table.find('tbody tr')).length;

        // first row needs to be headers
        var headers = [];
        for (var i=0; i<colsLength; i++) {
            headers[i] = $(table.find('thead tr')[0]).find('th').eq(i).text();
        }

        // go through cells
        for (var i=0; i<rowsLength; i++) {
            var tableRow = $(table.find('tbody tr')[i]);
            var rowData = {};
            for (var j=0; j<colsLength; j++) {
                rowData[ headers[j] ] = tableRow.find('td').eq(j).text();
            }
            data.push(rowData);
        }       
        return data;
    }
3

try $("#"+tableID + " tr") instead.

Saul Berardo
  • 2,530
  • 2
  • 18
  • 21
3

You should find this helpful: http://encosia.com/use-jquery-to-extract-data-from-html-lists-and-tables/

Dave Ward
  • 57,126
  • 11
  • 114
  • 134
  • Browsing to this link thorws this warning. [![Screen Shot 2017-03-28 at 7.57.30 PM.jpg](https://s13.postimg.org/6km89ehpj/Screen_Shot_2017-03-28_at_7.57.30_PM.jpg)](https://postimg.org/image/x5or4yk2r/) – lacostenycoder Mar 28 '17 at 23:59
2

HTML:

<table id="answered">
<tbody>
    <tr>
      <td data-id="user.email">email@email.com</td>
      <td data-id="meme.yodawg">Yo Dog! I Heard you liked answers, so I answered your question, with a method wrapped in a jQuery plugin!</td>
    </tr>
</tbody>
</table>

jQuery:

(function($) {

  $.extend($.fn, {

    tableRowsToJSONWithFilter : function (filter) {
      var tableSelector = this, item, attr, data, _JSON = [];
      if (typeof(tableSelector) !== 'object') {
        return new Error('Invalid tableSelect!');
      };
      $(tableSelector, 'tr').each(function(index, tr) {
        item = {};
        $('td', $(this)).each(function(index, td) {
          attr = $(td).attr('data-id');
          data = $(td).text();
          if (attr !== undefined && data !== '' && filter && new RegExp(filter, 'i').test(attr)) {
            item[attr] = data;
          };
        });
        _JSON.push(item);
      });
      return _JSON;
    }

  })

})(jQuery);

Usage:

$('#answered').tableRowsToJSONWithFilter('yodawg');