Getting text from file using FileReader on Load - javascript

So, I've been working on a page that uses only local files (server is not an option, unfortunately. Not even a localhost. The struggle is real.) and I've come to a situation where I need to grab text from a .csv file and populate it to the page. I have this bit of code that works, but I need to have a file set within the function when a button is pressed. Looking up the file manually isn't an option (to visualize what I'm doing, I'm making a mock database file in the most annoying way possible (because I have to, not because I want to)).
In the page I would have something like:
<button id="myButton" onclick="getText()"></button>
<script>
var myFile = "dataset.csv";
...
</script>
The following bit of code works (in regards to having it pull the data from the csv file), but, as I said, I need to pull the text from the file when a button is pressed and just have the file name set in the script, not pulling it up manually.
<!DOCTYPE html>
<html>
<body>
<input type="file" id="fileinput" />
<div id="outputdiv"></div>
<script type="text/javascript">
function readSingleFile(evt) {
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
var splited = contents.split(/\r\n|\n|\r|,/g);
for (i=0; i<splited.length; i++){
document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
}
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
</script>
</body>
</html>
From what I can tell from the API, I would need to set the file attributes to a blob in order to pass it to FileReader. How I can do this without using an input box, I have no idea. There's also a 50% chance that I am completely wrong about this since I obviously don't know how to get this done.
If someone could show me how to achieve this with regards to what I'm looking for, it would be very much appreciated. I'm absolutely stumped.
Thank you.

Note: CORS restrictons will prevent this from working in most browsers. You can use FireFox Developer Edition, which disables CORS validation.
You can use an XMLHttpRequest to load a local file:
<!DOCTYPE html>
<html>
<body>
<button onclick="readSingleFile()">Click Me</button>
<div id="outputdiv"></div>
<script type="text/javascript">
function readSingleFile() {
let xhr = new XMLHttpRequest();
let url = "relative/path/to/file.txt;
if (!url) return;
xhr.onload = dataLoaded;
xhr.onerror = _ => "There was an error loading the file.";
xhr.overrideMimeType("text/plain");
xhr.open("GET",url);
xhr.send();
}
function dataLoaded(e){
var contents = e.target.responseText;
var splited = contents.split(/\r\n|\n|\r|,/g);
for (i=0; i<splited.length; i++){
document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
}
</script>
</body>
</html>

Related

Alternate / Equivalent of jQuery.load in pure JavaScript? [duplicate]

I want home.html to load in <div id="content">.
<div id="topBar"> HOME </div>
<div id ="content"> </div>
<script>
function load_home(){
document.getElementById("content").innerHTML='<object type="type/html" data="home.html" ></object>';
}
</script>
This works fine when I use Firefox. When I use Google Chrome, it asks for plug-in. How do I get it working in Google Chrome?
I finally found the answer to my problem. The solution is
function load_home() {
document.getElementById("content").innerHTML='<object type="text/html" data="home.html" ></object>';
}
Fetch API
function load_home (e) {
(e || window.event).preventDefault();
fetch("http://www.yoursite.com/home.html" /*, options */)
.then((response) => response.text())
.then((html) => {
document.getElementById("content").innerHTML = html;
})
.catch((error) => {
console.warn(error);
});
}
XHR API
function load_home (e) {
(e || window.event).preventDefault();
var con = document.getElementById('content')
, xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (e) {
if (xhr.readyState == 4 && xhr.status == 200) {
con.innerHTML = xhr.responseText;
}
}
xhr.open("GET", "http://www.yoursite.com/home.html", true);
xhr.setRequestHeader('Content-type', 'text/html');
xhr.send();
}
based on your constraints you should use ajax and make sure that your javascript is loaded before the markup that calls the load_home() function
Reference - davidwalsh
MDN - Using Fetch
JSFIDDLE demo
You can use the jQuery load function:
<div id="topBar">
HOME
</div>
<div id ="content">
</div>
<script>
$(document).ready( function() {
$("#load_home").on("click", function() {
$("#content").load("content.html");
});
});
</script>
Sorry. Edited for the on click instead of on load.
Fetching HTML the modern Javascript way
This approach makes use of modern Javascript features like async/await and the fetch API. It downloads HTML as text and then feeds it to the innerHTML of your container element.
/**
* #param {String} url - address for the HTML to fetch
* #return {String} the resulting HTML string fragment
*/
async function fetchHtmlAsText(url) {
return await (await fetch(url)).text();
}
// this is your `load_home() function`
async function loadHome() {
const contentDiv = document.getElementById("content");
contentDiv.innerHTML = await fetchHtmlAsText("home.html");
}
The await (await fetch(url)).text() may seem a bit tricky, but it's easy to explain. It has two asynchronous steps and you could rewrite that function like this:
async function fetchHtmlAsText(url) {
const response = await fetch(url);
return await response.text();
}
See the fetch API documentation for more details.
I saw this and thought it looked quite nice so I ran some tests on it.
It may seem like a clean approach, but in terms of performance it is lagging by 50% compared by the time it took to load a page with jQuery load function or using the vanilla javascript approach of XMLHttpRequest which were roughly similar to each other.
I imagine this is because under the hood it gets the page in the exact same fashion but it also has to deal with constructing a whole new HTMLElement object as well.
In summary I suggest using jQuery. The syntax is about as easy to use as it can be and it has a nicely structured call back for you to use. It is also relatively fast. The vanilla approach may be faster by an unnoticeable few milliseconds, but the syntax is confusing. I would only use this in an environment where I didn't have access to jQuery.
Here is the code I used to test - it is fairly rudimentary but the times came back very consistent across multiple tries so I would say precise to around +- 5ms in each case. Tests were run in Chrome from my own home server:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
<div id="content"></div>
<script>
/**
* Test harness to find out the best method for dynamically loading a
* html page into your app.
*/
var test_times = {};
var test_page = 'testpage.htm';
var content_div = document.getElementById('content');
// TEST 1 = use jQuery to load in testpage.htm and time it.
/*
function test_()
{
var start = new Date().getTime();
$(content_div).load(test_page, function() {
alert(new Date().getTime() - start);
});
}
// 1044
*/
// TEST 2 = use <object> to load in testpage.htm and time it.
/*
function test_()
{
start = new Date().getTime();
content_div.innerHTML = '<object type="text/html" data="' + test_page +
'" onload="alert(new Date().getTime() - start)"></object>'
}
//1579
*/
// TEST 3 = use httpObject to load in testpage.htm and time it.
function test_()
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
{
content_div.innerHTML = xmlHttp.responseText;
alert(new Date().getTime() - start);
}
};
start = new Date().getTime();
xmlHttp.open("GET", test_page, true); // true for asynchronous
xmlHttp.send(null);
// 1039
}
// Main - run tests
test_();
</script>
</body>
</html>
try
async function load_home(){
content.innerHTML = await (await fetch('home.html')).text();
}
async function load_home() {
let url = 'https://kamil-kielczewski.github.io/fractals/mandelbulb.html'
content.innerHTML = await (await fetch(url)).text();
}
<div id="topBar"> HOME </div>
<div id="content"> </div>
When using
$("#content").load("content.html");
Then remember that you can not "debug" in chrome locally, because XMLHttpRequest cannot load -- This does NOT mean that it does not work, it just means that you need to test your code on same domain aka. your server
You can use the jQuery :
$("#topBar").on("click",function(){
$("#content").load("content.html");
});
$("button").click(function() {
$("#target_div").load("requesting_page_url.html");
});
or
document.getElementById("target_div").innerHTML='<object type="text/html" data="requesting_page_url.html"></object>';
<script>
var insertHtml = function (selector, argHtml) {
$(document).ready(function(){
$(selector).load(argHtml);
});
var targetElem = document.querySelector(selector);
targetElem.innerHTML = html;
};
var sliderHtml="snippets/slider.html";//url of slider html
var items="snippets/menuItems.html";
insertHtml("#main",sliderHtml);
insertHtml("#main2",items);
</script>
this one worked for me when I tried to add a snippet of HTML to my main.html.
Please don't forget to add ajax in your code
pass class or id as a selector and the link to the HTML snippet as argHtml
There is this plugin on github that load content into an element. Here is the repo
https://github.com/abdi0987/ViaJS
load html form a remote page ( where we have CORS access )
parse the result-html for a specific portion of the page
insert that part of the page in a div on current-page
//load page via jquery-ajax
$.ajax({
url: "https://stackoverflow.com/questions/17636528/how-do-i-load-an-html-page-in-a-div-using-javascript",
context: document.body
}).done(function(data) {
//the previous request fails beceaus we dont have CORS on this url.... just for illlustration...
//get a list of DOM-Nodes
var dom_nodes = $($.parseHTML(data));
//find the question-header
var content = dom_nodes.find('#question-header');
//create a new div and set the question-header as it's content
var newEl = document.createElement("div");
$(newEl).html(content.html());
//on our page, insert it in div with id 'inserthere'
$("[id$='inserthere']").append(newEl);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>part-result from other page:</p>
<div id="inserthere"></div>
Use this simple code
<div w3-include-HTML="content.html"></div>
<script>w3.includeHTML();</script>
</body>```
This is usually needed when you want to include header.php or whatever page.
In Javascript it's easy especially if you have HTML page and don't want to use php include function but at all you should write php function and add it as Javascript function in script tag.
In this case you should write it without function followed by name Just. Script rage the function word and start the include header.php
i.e convert the php include function to Javascript function in script tag and place all your content in that included file.
I use jquery, I found it easier
$(function() {
$("#navigation").load("navbar.html");
});
in a separate file and then load javascript file on html page
showhide.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function showHide(switchTextDiv, showHideDiv)
{
var std = document.getElementById(switchTextDiv);
var shd = document.getElementById(showHideDiv);
if (shd.style.display == "block")
{
shd.style.display = "none";
std.innerHTML = "<span style=\"display: block; background-color: yellow\">Show</span>";
}
else
{
if (shd.innerHTML.length <= 0)
{
shd.innerHTML = "<object width=\"100%\" height=\"100%\" type=\"text/html\" data=\"showhide_embedded.html\"></object>";
}
shd.style.display = "block";
std.innerHTML = "<span style=\"display: block; background-color: yellow\">Hide</span>";
}
}
</script>
</head>
<body>
<a id="switchTextDiv1" href="javascript:showHide('switchTextDiv1', 'showHideDiv1')">
<span style="display: block; background-color: yellow">Show</span>
</a>
<div id="showHideDiv1" style="display: none; width: 100%; height: 300px"></div>
</body>
</html>
showhide_embedded.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function load()
{
var ts = document.getElementById("theString");
ts.scrollIntoView(true);
}
</script>
</head>
<body onload="load()">
<pre>
some text 1
some text 2
some text 3
some text 4
some text 5
<span id="theString" style="background-color: yellow">some text 6 highlight</span>
some text 7
some text 8
some text 9
</pre>
</body>
</html>
If your html file resides locally then go for iframe instead of the tag. tags do not work cross-browser, and are mostly used for Flash
For ex : <iframe src="home.html" width="100" height="100"/>

Automatically load csv/txt file from local drive into html page as table Javascript

I found a lot of good suggestions on how to load a csv/txt file into a html page into a table, but none of the solutions are working for me. Here is the code I am working with. I have both files located in my C: drive and basically would like to load this csv/txt file and show it on as a table in index.html. Thanks so much!
data.txt
heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2
index.html
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});
function processData(allText) {
var allTextLines = allText.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j=0; j<headers.length; j++) {
tarr.push(headers[j]+":"+data[j]);
}
lines.push(tarr);
}
}
\\ alert(lines);
}
</script>
</body>
</html>
You can't access local files with JS. That would be serious security vulnerability, because you could send a malicious webpage to a user, which would download their files and send them to someone. As midrizi mentioned in the comments, you'll need a server to download files from there.
As others have noted, you can't automatically read a local file into the browser.
But you can prompt the user to select a file, using the <input type="file"> element.
Once a file has been selected via that input, it can be read via JavaScript.
<label for="file">Select a Text File:</label><br />
<input id="file" type="file" /><br/>
<button onclick="readFile()">Read File</button><br/>
let input = document.getElementById('file');
let contents = document.getElementById('contents');
function readFile () {
let file = input.files[0];
const reader = new FileReader();
reader.onload = function (evt) {
console.log('reader.onload');
contents.innerHTML = String(evt.target.result);
};
reader.readAsText(file);
}
If you can modify the data.txt a bit you can just load it as another script file without need for a server.
Change data.txt to this
var data = `heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2`
And load it as a javascript file before your actual script
<script type="text/javascript" src="data.txt"></script>
Then you can use the variable data which holds your file content without any ajax call.
There is no way you can retrieve a local file if you don't serve it, as pointed out in the comments to your question.
There are approaches you can take to that, though. If you can't serve it by any means, you could create a GitHub repo and upload your file there. Then you can use the link to your raw file:
And you can also take steps to automate that, but it should be easy enough committing your file locally whenever you update it and push it to GitHub. Just in case you're not familiar with Git and GitHub, here's a handy ref.
A word of caution: unless you have total control over the characters that you include in your CSV, parsing them by naively splitting commas like that might result in ugly stuff if the values within contain commas themselves. Some CSV files also come with extra stuff in the beginning of the file (like the sep indicator in the first row, which defines what character to interpret as separator). You may completely ignore these warnings if you're producing the CSV yourself.
Also I noticed your function does not take care of building the actual table, so I changed it so it does. I also used Fetch API to retrieve the data:
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
function processData(csv) {
let data = csv.split(/\r\n|\n/).map(v => v.split(','));
let headers = data.shift();
let table = document.createElement('table');
let thead = document.createElement('thead');
table.appendChild(thead);
thead.innerHTML = '<tr><th>' + headers.join('</th><th>') + '</th></tr>';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
for (let row of data) {
tbody.innerHTML += '<tr><td>' + row.join('</td><td>') + '</td></tr>';
}
document.body.appendChild(table);
}
// I uploaded the CSV to a personal repo for this example,
// but you CAN use a local file as long as you *serve* it
fetch("https://raw.githubusercontent.com/gyohza/test/master/so/data.txt")
.then(res => res.text())
.then(text => processData(text));
</script>
</body>
</html>

Saving data to a text file using javascript

I found a script to write the contents of a textbox to a text file, and show the download link.
But now I need help with modifying this code to save the text files in a specific location in the server once the button is clicked.
Here is the code:
<html>
<head>
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
(function () {
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
return textFile;
};
var create = document.getElementById('create'),
textbox = document.getElementById('textbox');
create.addEventListener('click', function () {
var link = document.getElementById('downloadlink');
link.href = makeTextFile(textbox.value);
link.style.display = 'block';
}, false);
})();
}//]]>
</script>
</head>
<body>
<textarea id="textbox">Type something here</textarea>
<button id="create">Create file</button>
<a download="info.txt" id="downloadlink" style="display: none">Download</a>
<script>
// tell the embed parent frame the height of the content
if (window.parent && window.parent.parent){
window.parent.parent.postMessage(["resultsFrame", {
height: document.body.getBoundingClientRect().height,
slug: "qm5AG"
}], "*")
}
</script>
</body>
</html>
Please advise.
You will need to learn backend development for server side practices. A client cant make any modification to the server without a backend in place. (That would be a huge security hole!) I would suggest learning NodeJS here: https://www.w3schools.com/nodejs/
Once you become more familiar and think you are ready to pick up this project again send me a direct message and I will point you in the right direction.

javascript auto-upload or reading a file form a local dir

I tried to read a local file. I've got a solution for MSIE.
But chorme and firefox are a little bit more restrict for such manipulations.
So I tried to use the FileReader but it seems taht it is not possible to read form a local dirve.
After some tests I've got this idea.
I want to 'auto-upload' the file without any dialog.
<!doctype html>
<html>
<script>
function handle_files(files) {
for (i = 0; i < files.length; i++) {
file = files[i]
console.log(file)
var reader = new FileReader()
reader.onload = function(e) {
console.log(e.target.result)
}
reader.onerror = function(stuff) {
console.log("error", stuff)
console.log (stuff.getMessage())
}
reader.readAsText(file) //readAsdataURL
}
}
handle_files(document.getElementById("input").value);
</script>
<body>
FileReader that works!
<input type="file" multiple onmouseover="handle_files(this.files)" id="input" value="K:\\somewhere\\over\\the\\rainbow\\c_comments.txt">
</body>
</html>
My question is now: How to manage a quite upload ?
Maybe somebody has a nice idea.
Thanks
br
Markus

Posting form values securely from one page to another on client-side using pure Javascript and NO server-side technology

I need to POST form values from one page to another using Javascript.
Now, I know that I could use a server-side technology like ASP.Net or PHP to post values but I am not allowed to use any server side script.
I am aware that using the GET method, I can pass the form values as a query string but the values will not be passed securely (which is an important requirement!)
The conditions listed below:
This code should take the values that are posted to the page and
repost to target page. HTTP POST only (not get).
In no cases, even error, the request should not stop on this bridge page.
The script needs to handle multiple posted values.
Try to use standard javascript (no 3rd party library)
Script needs to work in IE, FF, Safari, most standard browsers
Can anyone please help me find a solution to this or point me to some resource that will help me find the soln? Thanks in advance. Below is the code for passing values as a query string. Can I modify this so that my above requirements are satisfied?
FORM
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function goto_page(page) {
var usbnum = document.getElementById('usbnum').value;
var usbcode = document.getElementById('usbcode').value;
var q_str = '?usbnum=' + usbnum + '&usbcode=' + usbcode;
var url = page + q_str;
window.location = url;
}
</script>
</head>
<form id="form1" method="post">
<div>
USB No: <input name="usbnum" id="usbnum" type="text" size="80" /><br />
USB Code: <input name="usbcode" id="usbcode" type="text" size="80"/>
</div>
Next
</form>
</body>
</html>
BRIDGE PAGE
<html>
<head>
<title>Bridge Page</title>
<script type="text/javascript">
function get_params() {
var url = window.location.href;
var q_str_part = url.match(/\?(.+)$/)[1];
var val_pairs = q_str_part.split('&');
var params = {};
for (var i = 0; i < val_pairs.length; i++) {
var tmp = val_pairs[i].split('=');
params[tmp[0]] = typeof tmp[1] != 'undefined' ? tmp[1] : '';
}
return params;
}
function write_params() {
var params = get_params();
var txt = 'Hello ';
for (var i in params) {
txt += params[i] + ' ';
}
var body = document.getElementsByTagName('body')[0];
body.innerHTML += txt;
}
function write_params() {
var params = get_params();
var num_container = document.getElementById('usbnum');
var code_container = document.getElementById('usbcode');
num_container.innerHTML = params.usbnum;
code_container.innerHTML = params.usbcode;
}
</script>
</head>
<body onLoad="write_params()">
</body>
</html>
POST data can only be handled by server side code. There is no way you can use them in your javascript without help from a server side code.
You can only use GET or you can think about cookies. But at other hand, why do you want to change current page?! you can use AJAX to load more data without refreshing and no need of posting or getting variables.

Categories