21

How to make the following table into a JSON string in jquery/javascript?

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A1</td>
      <td>A2</td>
      <td>A3</td>
    </tr>
    <tr>
      <td>B1</td>
      <td>B2</td>
      <td>B3</td>
    </tr>
    <tr>
      <td>C1</td>
      <td>C2</td>
      <td>C3</td>
    </tr>
  </tbody>
</table>

I want to make it such that I can get a JSON string in a variable "myjson" that could be used in a POST request or GET request:

{
  "myrows" : [
    {
      "Column 1" : "A1",
      "Column 2" : "A2",
      "Column 3" : "A3"
    },
    {
      "Column 1" : "B1",
      "Column 2" : "B2",
      "Column 3" : "B3"
    },
    {
      "Column 1" : "C1",
      "Column 2" : "C2",
      "Column 3" : "C3"
    }
  ]
}

What is the best way to accomplish this? (Note: There may be a varying number of rows, I just want to extract the text while ignoring the other tags inside of the table)

Ryan
  • 1,387
  • 14
  • 23
Rolando
  • 58,640
  • 98
  • 266
  • 407

7 Answers7

30

Update: There's a slightly improved fork of the solution (below) on jsFiddle.

You just need to walk the DOM of your table reading it out... this is not even close to optimized but will give you the result you want. (jsFiddle)

// Loop through grabbing everything
var myRows = [];
var $headers = $("th");
var $rows = $("tbody tr").each(function(index) {
  $cells = $(this).find("td");
  myRows[index] = {};
  $cells.each(function(cellIndex) {
    myRows[index][$($headers[cellIndex]).html()] = $(this).html();
  });    
});

// Let's put this in the object like you want and convert to JSON (Note: jQuery will also do this for you on the Ajax request)
var myObj = {};
myObj.myrows = myRows;
alert(JSON.stringify(myObj));​

And the output...

{"myrows":[{"Column 1":"A1","Column 2":"A2","Column 3":"A3"},{"Column 1":"B1","Column 2":"B2","Column 3":"B3"},{"Column 1":"C1","Column 2":"C2","Column 3":"C3"}]}
scottheckel
  • 9,106
  • 1
  • 35
  • 47
10

Here is a solution without jQuery, inspired by this article:

function tableToJson(table) { 
    var data = [];
    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.push(tableRow.cells[j].innerHTML);
        } 
        data.push(rowData); 
    } 
    return data; 
}
Crann Moroney
  • 356
  • 2
  • 4
  • 13
Basj
  • 41,386
  • 99
  • 383
  • 673
6

I needed the same thing except with the ability to ignore columns, override values, and not be confused by nested tables. I ended up writing a jQuery plugin table-to-json:

https://github.com/lightswitch05/table-to-json

All you have to do is select your table using jQuery and call the plugin:

var table = $('#example-table').tableToJSON();

Here is a demo of it in action:

http://jsfiddle.net/nyg4z/27/

lightswitch05
  • 9,058
  • 7
  • 52
  • 75
4

My version of it:

var $table = $("table"),
    rows = [],
    header = [];

$table.find("thead th").each(function () {
    header.push($(this).html());
});

$table.find("tbody tr").each(function () {
    var row = {};

    $(this).find("td").each(function (i) {
        var key = header[i],
            value = $(this).html();

        row[key] = value;
    });

    rows.push(row);
});

See the Fiddle.

alextercete
  • 4,871
  • 3
  • 22
  • 36
  • Thanks!!! It helped me a lot cause you parted from $table, which in my case was necessary as I am parsing a string of html generated by wordpress ( don't ask me why ¬¬ ) – Cyberdelphos Apr 25 '16 at 18:12
2
var _table = document.getElementById("table");
var _trLength = _table.getElementsByTagName("tr").length;
var _jsonData = [];
var _obj = {};

var _htmlToJSON = function(index){
    var _tr = _table.getElementsByTagName("tr")[index];
    var _td = _tr.getElementsByTagName("td");
    var _arr = [].map.call( _td, function( td ) {
        return td.innerHTML;
    }).join( ',' );
    var _data = _arr.split(",");
    
    _obj = {
         column1     : _data[0]
        ,column2     : _data[1]
        ,column3     : _data[2]
    };
    
    _jsonData.push(_obj);
    
};

for(var i = 1; i < _trLength; i++){
    _htmlToJSON(i);
}
console.log("html to JSON",_jsonData);
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Tyler2P Jan 13 '21 at 12:03
  • Sorry sir newbie here:( – Ruel Ybañez Nov 11 '22 at 01:16
2

Try this.

var myRows = { myRows: [] };

var $th = $('table th');
$('table tbody tr').each(function(i, tr){
    var obj = {}, $tds = $(tr).find('td');
    $th.each(function(index, th){
        obj[$(th).text()] = $tds.eq(index).text();
    });
    myRows.myRows.push(obj);
});
alert(JSON.stringify(myRows));

Working demo - http://jsfiddle.net/u7nKF/1/

ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
0

Here you go http://jsfiddle.net/Ka89Q/4/

var head = [],
    i = 0,
    tableObj = {myrows: []};
$.each($("#my_table thead th"), function() {
    head[i++] = $(this).text();
});

$.each($("#my_table tbody tr"), function() {
    var $row = $(this),
        rowObj = {};

    i = 0;
    $.each($("td", $row), function() {
        var $col = $(this);
        rowObj[head[i]] = $col.text();
        i++;
    })

    tableObj.myrows.push(rowObj);
});

alert(JSON.stringify(tableObj));
ThePrimeagen
  • 4,462
  • 4
  • 31
  • 44
  • Thanks @Michael. One issue I noticed in trying to extend this to suit my purposes is that if you use th cells in your tbody to highlight key data in each row it fails over. Not a major issue but worthy of note maybe? Otherwise thanks - works lovely on 80+ rows. – Byte Insight Jan 15 '19 at 08:05