24

[EDIT] I solved the problem using D3, nevermind thanks!

So I have a csv file that looks something like this, and I need to import a local csv file into my client side javascript:

    "L.Name", "F.Name", "Gender", "School Type", "Subjects"
    "Doe",    "John",  "M",      "University",  "Chem I, statistics, English, Anatomy"
    "Tan",    "Betty",   "F",     "High School", "Algebra I, chem I, English 101"
    "Han",    "Anna",    "F",     "University",  "PHY 3, Calc 2, anatomy I, spanish 101"
    "Hawk",   "Alan",    "M",     "University",  "English 101, chem I" 

I eventually need do parse it and output something like:

Chem I: 3         (number of people taking each subject)
Spanish 101: 1 
Philosophy 204: 0 

But for now, I am stuck on just importing it into javascript.

My current code looks like this:

<!DOCTYPE html>  
<html>  
<body>
<h1>Title!</h1>
<p>Please enter the subject(s) that you wish to search for:</p>
<input id="numb" type="text"/> 
<button onclick="myFunction()">Click me to see! :) </button>
<script>
function myFunction() {
    var splitResearchArea = []; 
    var textInput = document.getElementById('numb').value; 
    var splitTextInput = textInput.split(",");

  for(var i =0; i<splitTextInput.length; i++) {
    var spltResearchArea = splitTextInput[i];
    splitResearchArea.push(spltResearchArea);
  }
}

I've researched and found some helpful links on Stackoverflow like this, this, and this but I'm new to javascript and I don't completely understand it. Should I use Ajax? FileReader? jQuery? What are the benefits of using one over the other? And how would you implement this in code?

But yeah, I'm just confused since I'm very new to javascript, so any help in the right direction would be great. Thank you!!

John Montgomery
  • 6,739
  • 9
  • 52
  • 68
ocean800
  • 3,489
  • 13
  • 41
  • 73
  • @cybernetic Why did you edit this question to remove all of the details? And neither the original question nor any of the current answers have any mention of the Fetch API. – John Montgomery Feb 20 '20 at 19:33
  • 1
    It was closed, as too general. SO invited me to edit to presumably make it more useful. If it’s not then just ignore my edit. – Cybernetic Feb 20 '20 at 19:50
  • 1
    Sometimes I think SO Posts are closed as "too general" purely for political reasons... Look at the number of upvotes. This question is obviously useful. – Shawn Eary Feb 17 '22 at 22:58

3 Answers3

58

Here is how to use the readAsBinaryString() from the FileReader API to load a local file.

Basically, just need to listen to change event in <input type="file"> and call the readFile function.

const fileInput = document.getElementById('csv')
const readFile = () => {
  const reader = new FileReader()
  reader.onload = () => {
    document.getElementById('out').innerHTML = reader.result
  }
  // start reading the file. When it is done, calls the onload event defined above.
  reader.readAsBinaryString(fileInput.files[0])
}

fileInput.addEventListener('change', readFile)
<div>
  <p>Select local CSV File:</p>
  <input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>

jsFiddle

Teocci
  • 7,189
  • 1
  • 50
  • 48
Jose Rui Santos
  • 15,009
  • 9
  • 58
  • 71
  • 1
    I see.... thanks!! However, I don't want the user to choose the csv file... the form will have a text field to enter in the subjects, and then it will have a drop down menu of all the schools to choose from. Based on the school they pick, the script needs to import the proper csv file and just output the results for each subject entered, not the whole csv file. Would this still apply? – ocean800 Apr 01 '15 at 16:03
  • @ocean800 If you need to load predefined csv files, depending on what the user inputs, then you can do that through the jquery [$.ajax](http://api.jquery.com/jquery.ajax/) or you can include the csv files in your html page as ` – Jose Rui Santos Apr 01 '15 at 16:29
  • 1
    @ocean800 For security reasons, it is not possible to programatically load files from local file system in JS. The only way to do it, is as I did it: using an `` to let the user **be aware** of that specific file loading, that the user selected himself. If this does not fit your needs, then you need a backend – Jose Rui Santos Apr 01 '15 at 17:02
  • Thanks, that link was very helpful! So then, in order to do it that way, I'd have to put the content of each csv file into the html document? – ocean800 Apr 01 '15 at 18:58
  • @ocean800 If your csv files never change, then yes you can place their data inside script tags or, more conveniently, in JS arrays such as `var csv1 = [{ name: "bill", age: 34 }, { name: "ana", age: 44 }, { name: "cory", age: 18}]; var csv2 = [...]`. This exemplifies a csv1 file with 3 rows and 2 columns, name and age. – Jose Rui Santos Apr 01 '15 at 19:14
  • I see.. thank you. I have about 50 csv files I have to use, so I'm not sure if I should do it this way, but in the other case, I would have to 100% set up a server correct? – ocean800 Apr 01 '15 at 20:10
  • @ocean800 That's correct. A server that would not serve you the files, but more interestingly, serve you already the final results ready for html output. – Jose Rui Santos Apr 01 '15 at 20:22
3

There are as many ways of accomplishing what you want as you could possibly imagine.

If I were doing this, I might start by splitting the input text into lines like so:

var lines = inputText.split('\n');

Then, I would extract the names of the headers from the first line. You need a function to read the values from each line.

// This assumes no commas in the values names.
function getCsvValuesFromLine(line) {
    var values = line[0].split(',');
    value = values.map(function(value){
        return value.replace(/\"/g, '');
    });
    return values;
}

var headers = getCsvValuesFromLine(lines[0]);

Next, I would loop over the remaining lines and create an array of objects representing the values in the lines.

lines.shift(); // remove header line from array
var people = lines.map(function(line) {
    var person = {};
    var lineValues = getCsvValuesFromLine(line);
    for (var i = 0; i < lines.length; i += 1) {
        person[headers[i]] = lineValues[i];
    }
    return person;
});

If this all works, you should end up with an array of objects representing the values in each line in your CSV.


The above is a rough outline of what the code might look like. I have not tested it and it certainly is not production ready, but I hope it gives you an idea of how to go about doing what you want.

I've used several built-in Javascript functions. I suggest looking them up on MDN if you're not familiar with them; they are good to know.

Finally, there is an odd quirk in Javascript with its automatic semi-colon insertion (a bad feature of the language, IMO). In order to avoid problems, do not put a new-line before an opening brace.

Always write

XXXX {
    ....
}

and don't write

XXXX
{
    ....
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Vivian River
  • 31,198
  • 62
  • 198
  • 313
  • 1
    I see... thank you, and I will be looking up a lot of these methods. Also, I had no idea about the automatic semi-colon insertion, so thanks so much!! – ocean800 Apr 01 '15 at 16:18
  • I would further suggest that when you look up these methods, search for the Mozilla Developer Network (MDN) reference. W3Schools is popular, but know for some inaccurate information. Search Google for `Javascript [methodname] MDN`. Also, please be sure to up-vote the answers you find helpful. – Vivian River Apr 02 '15 at 18:29
  • I also wrote a short beginner's guide to Javascript that you might find useful: http://danielsadventure.info/Javascript/Javascript.html. In it, I point out some of the differences between Javascript and other languages. – Vivian River Apr 02 '15 at 18:30
  • That link looks really helpful, thanks!! I'll check out the MDN as well. – ocean800 Apr 03 '15 at 17:56
2

i use this library from google: https://github.com/evanplaice/jquery-csv/ First - u have to

$.get(ur_csv_file_path);

and then use guide from page

Evan Plaice
  • 13,944
  • 6
  • 76
  • 94
Legendary
  • 2,243
  • 16
  • 26
  • 1
    Oh... Thanks!!... However, I thought you use $.get() when it's an http request to the server. Will it be the same considering that I just want to import a local csv file on my computer? – ocean800 Apr 01 '15 at 14:35
  • JS has NOT access to server, only throw XHR request, dont forget about front-end and back-end – Legendary Apr 01 '15 at 14:35
  • I can help you work with ajax and xhr, if you ahve trouble with it? – Legendary Apr 01 '15 at 14:37
  • read this for explonation about js and local files: http://stackoverflow.com/questions/371875/local-file-access-with-javascript (first answer) – Legendary Apr 01 '15 at 14:38
  • Oh, thanks! And yes, I've never worked with ajax and xhr before... but thanks. So I should also be using FileReader to do this also? Sorry, I really am a beginner so I might not completely be understanding what you're saying completely – ocean800 Apr 01 '15 at 14:44
  • So, tell me more about ur task, if u have local pc and u need script, what sometimes read and parse csv file - u better use not js, if u need script, what will worked on web - and some people will load csv files and get results - u need simple server + js with ajax – Legendary Apr 01 '15 at 14:46
  • Well, the overall goal for me is to create an html form that will tell me the percentage of students in a particular subject(s). Once they've entered the subject(s) they want to search for, and picked the school from a drop down menu, the percentages should then show up on the page. – ocean800 Apr 01 '15 at 14:51
  • U want load csv file throw from in html, right? – Legendary Apr 01 '15 at 14:54
  • 1
    Well, yes, when the user clicks the submit button on the form, I want script to load the csv file and then parse it, and return the results to the html page. I'm not sure if I'm understanding properly sorry. – ocean800 Apr 01 '15 at 14:59
  • Ok, i get it u need 1) simple server (php, nodejs, ruby - whatever u want) 2) on server u have to save file from form to an directory, and respond with path, 3) on js - u load file throw ajax, and on success callback get path to file, and then u can read and work with it – Legendary Apr 01 '15 at 15:01
  • Alright... but since I simply want to double click on the html file, run it from my computer, and access all my files locally, is it not possible to do it without a web server? – ocean800 Apr 01 '15 at 15:09
  • Have an idea - if u can insert csv in html, and ther parse it - it can work, but im not sure – Legendary Apr 01 '15 at 15:11
  • hmmm alright. I'll try to see if I can do something like that. Thanks a lot for the help!!!! – ocean800 Apr 01 '15 at 15:19
  • Hey, look what i found, do you try this? http://www.panayiotisgeorgiou.net/how-to-import-csv-to-html/ @ocean800 – Legendary Apr 01 '15 at 15:19
  • oh wow thanks!!! thank link is going to be really helpful!! – ocean800 Apr 01 '15 at 15:22
  • Let me know, if u have trouble) – Legendary Apr 01 '15 at 15:43
  • 3
    @ocean800 Since this answer mentions jquery-csv, here is the demo that does exactly what you describe. http://evanplaice.github.io/jquery-csv/examples/file-handling.html. FYI, I'm the author of jquery-csv. – Evan Plaice Jan 21 '16 at 13:43