1

recently I reached out on here for some help regarding javascript. I needed something that parsed a CSV file and outputted it to HTML.

Someone was able to help me massively. only problem is that it outputs as a one row table. In the CSV file each row does not have a specific amount of columns/data meaning that the row data varies in length.

what I've been trying to do is write some if statements to only pick up things like 'Last name' or 'known for' so i can give some order to the results.

What is the best way to do this? I will need to style the output data so i'm thinking div id's would be better than tables. also, where abouts in the code should i edit (my javascript knowledge is very beginner).

if statement i tried (probably totally wrong):

  function firstName($container){
      var firstN = $container;
      var n = firstN.includes("First Name");

    if (n != 0){
        document.getElementById("first_name").innerHTML="First name = ";
        return;
    }
    }

main block of code (CSV file can be found at http://www.fooda.website/testResults.csv):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="jquery-1.12.3.min.js" type="text/javascript">
</script>
<title>Untitled Document</title>
<script type="text/javascript">
// ============================
// Allow for a cached result
// ============================
var csvRows = [];
// ============================

// ============================
// Given an array of rows build a table.
// ============================
function buildTable(csvRows){
  // Our base result
  var $table = $("<table cellpadding=\"2\" cellspacing=\"0\"></table>");

  // ============================
  // For each row in the CSV build a <tr /> and append it to the <table />
  // ============================
  $table = csvRows.reduce(function($table, csvRow){

    // For this demo just take the first few cells/columns
    var csvRowCells = csvRow.split(",");

    // Our base table row
    var $tr = $("<tr>/tr>");

    // ============================
    // For each cell row build a <td /> and append it to the <tr />
    // ============================
    $tr = csvRowCells.reduce(function($tr, csvRowCell){
      return $tr.append($("<td>/</td>").text(csvRowCell));
    }, $tr);
    // ============================

    // Add our new <tr /> to the table then return the table
    return $table.append($tr);
  }, $table);
  // ============================

  return $table;
}
// ============================

// ============================
// Given an array of rows, randomly select one (as an array) and build a table with it.
// ============================
function fillContainerWithTable(csvRows, $container){
  var randomRow = [csvRows[Math.floor(Math.random() * csvRows.length)]];
  var $table = buildTable(randomRow);
  $container.append($table);
}
// ============================

// ============================
// the click handler
// ============================
function myFunction(){
  // some random csv I found...
  var uri = "http://www.fooda.website/testResults.csv";
  var $container = $("#wrap");

  // You probably want a clean slate.
  $container.empty();

  // ============================
  // If we have the data locally already just use it.
  // ============================
  if (csvRows.length !== 0){
    console.log("using local data...");
    fillContainerWithTable(csvRows, $container);
    return;
  }
  // ============================

  console.log("fetching remote data...");

  $.get(uri, function(data){
    csvRows = data.split("\n");
    fillContainerWithTable(csvRows, $container);
  });
}
// ============================
</script>
<style type="text/css">
body {
  font-family: arial, helvetica, sans-serif;
  font-weight: normal;
  font-size: 13px;
  color: #000;
  text-align: left;
  margin: 3px 0px;
}

#wrap {
  padding: 20px;
}

#wrap table {
  border: solid 1px;
  border-collapse: collapse;
  background-color: aliceblue;
  height:400px;
  width:100%;
}

#first_name {
    height:200px;
    width:200px;
    background-color:#0C0;
}

</style>
</head>



<body>


<button onclick="myFunction()">Click me</button>
<div id="wrap"></div>

<div id="first_name">
</div><!--first_name-->

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


</body>
</html>

Thanks in advance!

Ravi Teja Kumar Isetty
  • 1,559
  • 4
  • 21
  • 39
gezer4000
  • 103
  • 1
  • 9
  • Looks like your "CSV" is actually JSON, is that right? – henry Sep 02 '16 at 17:55
  • 1
    @henry: I thought the same thing, but it's more like each row is a JSON object. But you're right, "CSV" loses all meaning in this context. gezer4000: Do you have control over the "CSV" format? It would be much easier to handle if you convert the data into true JSON. If you're set on CSV, you should consider enforcing a more CSV-like layout where each column represents a specific type of value, even if that column is empty. – TheJim01 Sep 02 '16 at 18:04
  • @TheJim01 The file included is just a sample of results. The actual file is CSV and has about 700 entries. I'm very new to javascript having only dabbled before so i'm not sure what/how to parse JSON. I'm looking for a way to take each entry in a CSV row and output it in HTML with some code to filter the results so only certain values are displayed. – gezer4000 Sep 02 '16 at 18:48
  • typo here - var $tr = $("/tr>");... should be var $tr = $(""); – gavgrif Sep 02 '16 at 21:06

1 Answers1

2

Short answer is "this is a duplicate of the many 'how do I convert JSON into an HTML table' questions on SO" and in the end I'm just going to point you towards some of them, but I want to walk you through it.

CVS (comma-separated values) looks like

Col1,Col2,Col3,Col4
row1value1,row1value2,row1value3
row2value1,row2value2
row3value1,,row3value3,row3value4

While not necessarily the case, you can think of CSV as a very compact way text-only of writing a table, where each row's values are in the same order (like table columns) and empty cells look like ",,". If the above csv was a table (e.g. if you imported it into Excel etc), it would be

Col1       Col2       Col3       Col4
row1value1 row1value2 row1value3
row2value1 row2value2
row3value1            row3value3 row3value4

Your data, on the other hand, is actually a list of JSON "objects", one per line. In JSON, an object is contained within { } and is made up of "key/value" pairs. A JSON object looks like

{"key1":"value1", "key2":"value2"}

JSON lets you group objects into arrays. A JSON array is contained within [ ].

In JSON, the above table would look like

[{'Col1':'row1value1','Col2':'row1value2','Col3':'row1value3'},
 {'Col1':'row1value1','Col2':'row1value2'},
 {'Col1':'row1value1','Col3':'row1value3','Col4':'row1value4'}]

When working with JSON, you can say "loop through each object in an array" and "for the current object, give me the Col2 value." (Note this means related JSON objects don't have to list the key/value pairs in the same order, and you don't have to specify missing values.) If you knew every possible key in your array (in this case, that'd be Col1, Col2, Col3, and Col4) you could say

"Loop through the array, put each object in a <tr>, and for each object first put the Col1 value in a <td>, then put the Col2 value in a <td>, then put the Col3 value in a <td>, then put the Col4 value in a <td>."

That's exactly what you want to do… and it turns out there are already a bunch of tools out there to do it! The only thing standing between you and using them is putting a [ at the start of your file, a , at the end of every line except the last, and a ] at the end of the file. If you can do this, you're in luck. If this is static data, just open the data up in a text editor and use a find/replace to add in the end-of-line commas. If it's being generated on the fly, you'll have to come up with a way to add things (the solution will be something like tack on [, split the file by }, tack on each chunk of the split data followed by a , unless it's the last chunk, then tack on a ], and then run that through a JSON-to-HTML-table tool). I'll leave how exactly to do that up to you -- if you get stumped, definitely open up a new "how can I convert a list of json objects into a json array" question. I'm not a JSON expert, and I bet there's some standard way of doing it

Here are a couple promising JSON-to-HTML-table solutions. I'll be interested to hear if one of them works for you!

Community
  • 1
  • 1
henry
  • 4,244
  • 2
  • 26
  • 37
  • thanks for the reply @henry So are you saying i should convert the file to JSON? how is this possible? also what sort of tools would you suggest? again, I am very new to this. – gezer4000 Sep 02 '16 at 21:31
  • I'm saying you don't really have a CSV, in the sense that's usually used. You almost almost have a JSON file, you're just missing commas at the end of each line and brackets around the whole thing. If you can add those, you'll be able to use any of the many existing JSON-to-HTML-table tools! I've rewritten my comment to turn it into more of a real answer – henry Sep 02 '16 at 23:04