1

I have been using PapaParse to convert .csv files to JSON. PapaParse returns the .csv file as an array of objects.

There have been many answers here (such as this elegant one: display array of objects in a dynamic table javascript) about how to take an array of objects and make it into a table if you know the structure, but I would like to be able to make a generic parser, since I have a number of .csv files to convert, which will automatically fill in the information and size the table, (just as "console.table" does.)

I can see how to retrieve the data for the header, but is there a way to avoid having to know the key names for each column, since they will always be different for each .csv file? e.g. "Location" and "Year" here:

td.innerHTML = jsData[i].Location;
td = tr.insertCell(tr.cells.length);
td.innerHTML = jsData[i].Year;
td = tr.insertCell(tr.cells.length); etc. 

JS Fiddle here.

Thanks!

Community
  • 1
  • 1
Tyler330
  • 395
  • 2
  • 6
  • 15

2 Answers2

3

You can use for in loop to get all object values :

for(var key in jsData[i])
{
    td.innerHTML = jsData[i][key];
    td = tr.insertCell(tr.cells.length);
}

var jsData = new Array();
jsData[0] = {
    Location: "Uruguay",
    Year: 1930,
    Winner: "Uruguay",
    WinScore: 4,
    Loser: "Argentina",
    LosScore: 2
};
jsData[1] = {
    Location: "Italy",
    Year: 1934,
    Winner: "Italy",
    WinScore: 2,
    Loser: "Czechoslovakia",
    LosScore: 1
};
jsData[2] = {
    Location: "France",
    Year: 1938,
    Winner: "Italy",
    WinScore: 4,
    Loser: "Hungary",
    LosScore: 2
};
jsData[3] = {
    Location: "Brazil",
    Year: 1950,
    Winner: "Uruguay",
    WinScore: 2,
    Loser: "Brazil",
    LosScore: 1
};
jsData[4] = {
    Location: "Switzerland",
    Year: 1954,
    Winner: "West Germany",
    WinScore: 3,
    Loser: "Hungary",
    LosScore: 2
};

// Draw table from 'jsData' array of objects



function drawTable(tbody) {
    var tbody = document.getElementById("matchData");
    var headerNames = Object.getOwnPropertyNames(jsData[0]);
    var columnCount = headerNames.length;
    //Add the header row.
    var row = tbody.insertRow(-1);
    for (var i = 0; i < columnCount; i++) {
        var headerCell = document.createElement("TH");
        headerCell.innerHTML = headerNames[i];
        row.appendChild(headerCell);
    }
    var tr, td;

    // loop through data source
    for (var i = 0; i < jsData.length; i++) {
        tr = tbody.insertRow(tbody.rows.length);
        td = tr.insertCell(tr.cells.length);
        td.setAttribute("align", "center");

        for(var key in jsData[i])
        {
            td.innerHTML = jsData[i][key];
            td = tr.insertCell(tr.cells.length);
        }
        
    }
}
drawTable("matchdata");
<table id="cupFinals" border=1 px>
    <tbody id="matchData"></tbody>
</table>

Hope this helps.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
1

tl;dr jsfiddle

Sure there is a way. Given an object, such as this one:

var obj = {x:'x', y:'y' ...}

You can access every property by for(var i in obj) loop. In such loop, variable i will be subsequently assigned all property names in obj. If you do this:

for(var i in obj) {
    console.log(i);
}

You will get "x" and "y" in the console.

Similarly, for your code, you can access jsData[i] like that. The loop then looks like this:

for (var i = 0; i < jsData.length; i++) {
    var tr = tbody.insertRow(tbody.rows.length);
    for(var colName in jsData[i]) {
        var td = tr.insertCell(tr.cells.length);
        td.innerHTML = jsData[i][colName];
    }
}

I'd like to further remark that .insertRow is not as fast as .appendChild method, as seen here. So I'd do this:

for (var i = 0; i < jsData.length; i++) {
    var tr = document.createElement("tr");
    for(var colName in jsData[i]) {
        var td = document.createElement("td");
        td.innerHTML = jsData[i][colName];
        tr.appendChild(td);
    }
    tbody.appendChild(tr);
}

This is especially important when the table is already in the displayed document.

Community
  • 1
  • 1
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Wow -- the speed of responses never fails to amaze. Thank you -- I will try this out on my actual data. – Tyler330 Nov 22 '15 at 22:40