How to select a file in html and manage it in javascript - javascript

I need to select a .csv file in html and manage it with javascript (I need to convert it into JSON), I did something but it doesn't work well.
To select a file in html I did this:
<input id="inputFile" accept=".csv" type="file"> <br>
<br>
<input value="Send" type="button" onclick="showFile()">
<label id="mylabel">
</label>
<script src="../javascript/parseFileScript.js"></script>
and to manage it I did this:
//take a string containing a csv
function csvJSON(csv){
console.log(typeof csv)
var lines=csv.split("\n");
var result = [];
// NOTE: If your columns contain commas in their values, you'll need
// to deal with those before doing the next step
// (you might convert them to &&& or something, then covert them back later)
// jsfiddle showing the issue https://jsfiddle.net/
var headers=lines[0].split(",");
for(var i=1;i<lines.length;i++){
var obj = {};
var currentline=lines[i].split(",");
for(var j=0;j<headers.length;j++){
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
//return result; //JavaScript object
return JSON.stringify(result); //JSON
}
//load the selected file and convert in string
async function getCSV() {
let file = document.getElementById('inputFile').files[0];
console.log(typeof file)
let text = await file.text();
return text;
}
//put the body of the selected file in a label
function showFile() {
let csv = getCSV();
let json = csvJSON(csv);
document.getElementById('mylabel').innerHTML = json;
}
The error I get is Uncaught TypeError: csv.split is not a function, so I check for the type of csv in the function csvJSON and for the type of file in getCSV and in both cases the console tells me that the type is object.
Can someone explain to me where I'm wrong and how to solve the problem, please?

Related

How do I use an HTML text box value as a JavaScript parameter or variable and call the JavaScript Function with the text box value?

I have a JavaScript function that works on its own, however, I am having difficulty getting it to function correctly inside of an HTML web page (no server backend). The function that works correctly by itself is:
function decodeUrlDefensev3(link) {
var matches = link.match(new RegExp('v3/__(.+?)__;(.*?)!'))
// love me a mutable array
var decode_pile = Array.from(matches[1]);
var chars_pile = Array.from(atob(matches[2])).reverse();
for (var match of link.matchAll(/\*/g)) {
decode_pile[match.index] = match.pop()
}
return decode_pile.join('')
}
var link = "https://urldefense.com/v3/__https://files.bitsight.com/e3t/Ctc/LR*113/c1NcF04/VWyThK1lvg49W724nRX2d04lQW1xTZ7Q4QfX7gN6fpSV75nCTJV3Zsc37CgZP4N95fbTLz6L-gW48j6gR3bC3zwW6L_GnH7kDhzMW9418Rb3hJ605W2HjF587SWBXyW8RmYtF6fgdWYW5XQmQn1bFttzW5qPlhD5h_TCqW4-gDCr8x7fD0N4M_DVGdxFD9W2T0jhF4j9YsWW7603Qw8dF3j7W36QBsz4RM6hNW6Hpcdy8Qtmw4W8y5VBz2TLWGhVTNFr45gN7FDW7m9S0M1tvjXNW7vLHnj2945hZW437Z0x5Vd_ZcW7MjgJC89gYB6W2Y3sH14zDDZvW39S6bT1pFgM2W8gn9pV4HdltbW3MTVMS59VlW-VBQkF74S69PWW5yn7jz6PhmVLW4sYpYl4yDVH4W3dkf3v6S141VW3Sqpcn7xkSPcW33N24p3R1FxPW3y04W03TWHN4N2wvRyC4j7X83p5G1__;Kw!!HhY5bxTJhQ!vdj_DUrp0JIWgTw61Vg8M1chEvhp0k7XlLFiomq0Wu1rCrze9dzn2inIIVKchdRRP6HqJshCEuIHCbwCa1ha0FPyFA$"
console.log(decodeUrlDefensev3(link))
Expected output:
https://files.bitsight.com/e3t/Ctc/LR*113/c1NcF04/VWyThK1lvg49W72*nRX2d04lQW1xTZ7Q4QfX7gN6fpSV75nCTJV3Zsc37CgZP4N95fbTLz6L-gW48j6gR3bC3zwW6L_GnH7kDhzMW9418Rb3hJ605W2HjF587SWBXyW8RmYtF6fgdWYW5XQmQn1bFttzW5qPlhD5h_TCqW4-gDCr8x7fD0N4M_DVGdxFD9W2T0jhF4j9YsWW7603Qw8dF3j7W36QBsz4RM6hNW6Hpcdy8Qtmw4W8y5VBz2TLWGhVTNFr45gN7FDW7m9S0M1tvjXNW7vLHnj2945hZW437Z0x5Vd_ZcW7MjgJC89gYB6W2Y3sH14zDDZvW39S6bT1pFgM2W8gn9pV4HdltbW3MTVMS59VlW-VBQkF74S69PWW5yn7jz6PhmVLW4sYpYl4yDVH4W3dkf3v6S141VW3Sqpcn7xkSPcW33N24p3R1FxPW3y04W03TWHN4N2wvRyC4j7X83p5G1
The above code will return a correctly decoded website URL in the console. This works for technical people however, I am trying to create a basic HTML with a text box for users to enter the encoded URL, click a button, then return the decoded URL on their screen.
Using the below code:
function decodeUrlDefensev3(link) {
var matches = link.match(new RegExp('v3/__(.+?)__;(.*?)!'))
// love me a mutable array
var decode_pile = Array.from(matches[1]);
var chars_pile = Array.from(atob(matches[2])).reverse();
for (var match of link.matchAll(/\*/g)) {
decode_pile[match.index] = match.pop()
}
return decode_pile.join('')
}
var link = document.getElementById('textbox1').value;
console.log(link)
<input type="text" id="textbox1" value="https://www.google.com" />
<input type="button" value="button1" onclick="decodeUrlDefensev3(link)" />
<input type="button" value="button2" onclick="function2()" />
The console.log(link) returns the true variable saved above. However, when I click the button, I get an error "Uncaught TypeError: Cannot read properties of null (reading '1')".
How do I pass the textbox input and properly call my function so that whatever is entered inside of textbox1 is parsed using my JavaScript function?
An example of what I am trying to do can be found here:https://jsfiddle.net/37phxda8/1/
I need to use my function above, not the function on that JS Fiddle.
You aren't passing the parameter to the decodeurl function. Try it like this:
function decodeUrlDefensev3(link) {
var matches = link.match(new RegExp('v3/__(.+?)__;(.*?)!'))
// love me a mutable array
var decode_pile = Array.from(matches[1]);
var chars_pile = Array.from(atob(matches[2])).reverse();
for (var match of link.matchAll(/\*/g)) {
decode_pile[match.index] = match.pop()
}
return decode_pile.join('')
}
function handleClick() {
var link = document.getElementById('textbox1').value;
decodeUrlDefensev3(link);
}
Then in your html:
<input type="button" value="button1" onclick="handleClick()"/>
The error is probably because there are no results from the link.match function (for "https://www.google.com"), let alone 3 [2nd and 3rd items of the result are used for decode_pile and chars_pile respectively]. You should either change the RegExp for the match or provide and error message like the commented if block in the edited code below.
Also, your function is not taking updated input from textbox1 - only the initial value of "https://www.google.com" set in html. You should retrieve it within the function like:
function decodeUrlDefensev3() {
var link = document.getElementById('textbox1').value;
var matches = link.match(new RegExp('v3/__(.+?)__;(.*?)!'))
/*if (!matches || matches.length < 3) {
alert("Invalid input, could not decode");
return null;
}*/
// love me a mutable array
var decode_pile = Array.from(matches[1]);
var chars_pile = Array.from(atob(matches[2])).reverse();
for (var match of link.matchAll(/\*/g)) {
decode_pile[match.index] = match.pop()
}
return decode_pile.join('')
}
And then your HTML for the button can simply be:
<input type="button" value="button1" onclick="decodeUrlDefensev3()"/>

Create structured JSON object from CSV file in JavaScript?

I want to create a JSON object from the contents of a CSV file. The CSV file is loaded locally via the FileReader API and that seems to work, however I am having trouble structuring the JSON in the desired way.
My code for loading the CSV file looks like this:
<!DOCTYPE html>
<html>
<body>
<p>Select local CSV File:</p>
<input id="csv" type="file">
<output id="out"> input file content</output>
<script>
var fileInput = document.getElementById("csv"),
readFile = function () {
var reader = new FileReader();
reader.onload = function () {
// Display CSV file contents
document.getElementById('out').innerHTML = reader.result;
};
reader.readAsBinaryString(fileInput.files[0]);
};
fileInput.addEventListener('change', readFile);
</script>
</body>>
</html>
The code above allows me to load the contents of the CSV file and display them on the current page. To structure the CSV data into the desired format above I tried the following, however it didn't work to me:
<!DOCTYPE html>
<html>
<body>
<script>
var fileReader = new FileReader();
function getFile(inputFile) {
let file = inputFile.files[0];
fileReader.readAsText(file);
}
function csvJSON(csv){
var lines=csv.split("\n");
var result = [];
var headers=lines[0].split(",");
for(var i=1;i<lines.length;i++){
var obj = {};
var currentline=lines[i].split(",");
for(var j=0;j<headers.length;j++){
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return JSON.stringify(result); //JSON
}
function readFile(evt) {
let parsed = csvJSON(evt.target.result);
return parsed;
}
</script>
</body>
</html>
How can I acquire my expected JSON object(s)? Any suggestions would be appreciated
One approach to this would be to iterate through your input CSV data on increments of "6" (where 6 represents the number of different bits of data for each student) to capture all student data per CSV row, and then populate an array of structured JSON objects in the desired format like so:
/* Helper function to perform the CSV to JSON transform */
function convertToJson(inputCsv) {
/* Split input string by `,` and clean up each item */
const arrayCsv = inputCsv.split(',').map(s => s.replace(/"/gi, '').trim())
const outputJson = [];
/* Iterate through input csv at increments of 6, to capture entire CSV row
per iteration */
for (let i = 6; i < arrayCsv.length; i += 6) {
/* Extract CSV data for current row, and assign to named variables */
const [date, firstName, middleName, lastName, uin, rsvpStatus] =
arrayCsv.slice(i, i + 6)
/* Populate structured JSON entry for this CSV row */
outputJson.push({
uin,
studentInfo: {
firstName,
middleName,
lastName,
rsvpStatus
}
});
}
return outputJson;
}
/* Input CSV data from your exsiting code */
const csv = `"Timestamp", "Enter First Name:", "Enter Middle Initial",
"Enter Last Name:", "Enter UIN:", "Are you attending the event?",
"2019/02/22 12:41:56 PM CST", "Jonathan", "Samson", "Rowe", "123456789",
"No", "2019/02/22 12:44:56 PM CST", "phil", "Aspilla", "beltran", "123456788",
"Yes"`
const json = convertToJson(csv);
console.log(json);
var csv = '"Timestamp","Enter First Name:","Enter Middle Initial","Enter Last Name:","Enter UIN:","Are you attending the event?"\n"2019/02/22 12:41:56 PM CST","Jonathan","Samson","Rowe","123456789","No"\n"2019/02/22 12:44:56 PM CST","phil","Aspilla","beltran","123456788","Yes"';
var csvJSON = function(csv) {
let vals = csv.split('\n'), ret = [];
for( let i = 1, len = vals.length; i < len; i++ ){
let person = vals[i].split(',');
ret.push({
uin : person[4],
studentInfo : {
firstName : person[1],
middleName : person[2],
lastName : person[3],
rsvpStatus : person[5]
}
});
}
return JSON.stringify(ret);
}
console.log(csvJSON(csv));
This is assuming the structure of the CSV is always the same.
If you are struggling to parse data, you can also use PapaParse, it has a lot of configurations and it's pretty easy to use:
// Parse CSV string
var data = Papa.parse(csv);
See more information at https://www.papaparse.com/demo

How to find data type of each column from csv file using Java Script?

I have tried to find data-type of each column using Java Script, It prints string data-type for number,string and date.
I need each column data-type whether it is date or string or number or float.
Without CSV it prints correct data-type.
Working Example without CSV file
var num=15;
var str="xyz";
console.log(typeof num);
console.log(typeof str);
Output
number
string
But using csv file it prints string for all columns.
My CSV file is:
01/01/1991,12,xyz,14.4
01/01/1992,20,abc,20.5
01/02/1980,78,xy,60.8
I am using Papa Parse javascript plug-in for getting each column and then checking data-type.
How do I get each column's data-type from CSV file?
Is there any other way to parse CSV to array where we can traverse on particular row or column?
While you are loading your CSV in your javascript variable, that variable is a string.
You have to extract your csv into a JSON array and you have to cast each variable accordingly.
Code:
$.ajax({
type: "GET",
url: "sample.csv",
success: function (data) { loadData(data); }
});
/*var data = 'date,name,value\n\
01/01/1991,xyz,14.4\n\
01/01/1992,abc,20.5\n\
01/02/1980,xy,60.8';
loadData(data);*/
function loadData(data1){
console.log(data1);
var dataPoints = data1.split(/\r\n|\n/);
//console.log(lines);
var headers = dataPoints[0].split(','); // if you have header
var lines = [];
console.log(headers);
console.log(dataPoints.length);
for (var i = 1; i < dataPoints.length; i++) {
//console.log(i);
var point = dataPoints[i].split(',');
//console.log(point);
if (point.length == headers.length) {
var json= {};
for (var j = 0; j < headers.length; j++) {
if(headers[j]=='date'){
json[headers[j]] = new Date(point[j]);
}else if(headers[j]=='value'){
//console.log(point[j]);
json[headers[j]] = Number(point[j]);
}else{
json[headers[j]] = point[j];
}
}
lines.push(json);
console.log(json);
}
}
console.log(lines);
}
Sample CSV:
date,name,value
01/01/1991,xyz,14.4
01/01/1992,abc,20.5
01/02/1980,xy,60.8
Modified Code

How to convert any array to json dynamically

I am trying to get a file from user, convert it into an array and need to develop a histogram. For developing a histogram, I need to have that data in json format. Though there are enough example to convert an array into json hard coded, but I am not able to find a single example to convert it dynamically on real time basis. Here is my code:
<input type="file" name="F1" id="F1" size="80">
<input type="button" value="Read" name="B1" id="B1" onclick="execFile()">
function execFile() {
// main function to open, parse, and then render
var myfile=document.getElementById("F1")
arr = readCSV(myfile.value);
// parse csv line by line
for (var i=0;i<arr.length;i++) {
arr[i] = parseLineCSV(arr[i]);
}
for (var i=0;i<arr.length;i++) {
document.write(arr[i]);
}
}
So, I need to pass an array arr to convert to json. I found this code from another user but it seems not working for me.
for(var i=1;i<arr.length;i++) {
var tmp_values = [];
alert(arr.length);
for (var l=1;l<arr[0].length;l++) {
alert(arr[0].length);
tmp_values.push({label: arr[0][l], value: arr[i][l]}); //label + value respectively
alert("2");
}
jsonObj.push({key: arr[i][0], values: tmp_values}); //key
alert("3");
}
I am doing some mistake as I am able to get only arr.length and alert 3.. I am doing some mistake with push function, but cant figure out what. So , please help
I found this solution, normally this should do the trick.
var myJsonString = JSON.stringify(yourArray);
see here for more :
Convert array to JSON

Creating a JSON dynamically with each input value using jquery

I got a situation where I would like to read some data off a JSON format through PHP, however I am having some issues understanding how I should construct the Javascript object to create the JSON format dynamically.
My scenario is as follows:
<input title="QA" type="text" class="email">
<input title="PROD" type="text" class="email">
<input title="DEV" type="text" class="email">
The Javascript code I have so far goes through each input grabs the data, I am however unable to understand how to process from here on.
var taskArray = {};
$("input[class=email]").each(function() {
var id = $(this).attr("title");
var email = $(this).val();
//how to create JSON?
});
I would like to get the following output if possible.
[{title: QA, email: 'a#a.com'}, {title: PROD, email: 'b#b.com'},{title: DEV, email: 'c#c.com'}]
Where the email is acquired by the input field value.
Like this:
function createJSON() {
jsonObj = [];
$("input[class=email]").each(function() {
var id = $(this).attr("title");
var email = $(this).val();
item = {}
item ["title"] = id;
item ["email"] = email;
jsonObj.push(item);
});
console.log(jsonObj);
}
Explanation
You are looking for an array of objects. So, you create a blank array. Create an object for each input by using 'title' and 'email' as keys. Then you add each of the objects to the array.
If you need a string, then do
jsonString = JSON.stringify(jsonObj);
Sample Output
[{"title":"QA","email":"a#b"},{"title":"PROD","email":"b#c"},{"title":"DEV","email":"c#d"}]
I don't think you can turn JavaScript objects into JSON strings using only jQuery, assuming you need the JSON string as output.
Depending on the browsers you are targeting, you can use the JSON.stringify function to produce JSON strings.
See http://www.json.org/js.html for more information, there you can also find a JSON parser for older browsers that don't support the JSON object natively.
In your case:
var array = [];
$("input[class=email]").each(function() {
array.push({
title: $(this).attr("title"),
email: $(this).val()
});
});
// then to get the JSON string
var jsonString = JSON.stringify(array);
May be this will help, I'd prefer pure JS wherever possible, it improves the performance drastically as you won't have lots of JQuery function calls.
var obj = [];
var elems = $("input[class=email]");
for (i = 0; i < elems.length; i += 1) {
var id = this.getAttribute('title');
var email = this.value;
tmp = {
'title': id,
'email': email
};
obj.push(tmp);
}
same from above example - if you are just looking for json (not an array of object) just use
function getJsonDetails() {
item = {}
item ["token1"] = token1val;
item ["token2"] = token1val;
return item;
}
console.log(JSON.stringify(getJsonDetails()))
this output ll print as (a valid json)
{
"token1":"samplevalue1",
"token2":"samplevalue2"
}
I tried this:
// Sample JS object
var varobject = {
name: "Name",
Intern: "Test",
};
// Converting JS object to JSON string
JSON.stringify(varobject);

Categories

Resources