I have a JavaScript app that calculates various values. I would like to have a function that stores calculated output values (e.g. when you click a "store value" button), creating a list in the background that the user could then download as, e.g., a text file. I'm wondering what the easiest implementation of this would be in the browser -- values can get wiped on page refresh so no need to store long-term. Thanks!
Are you asking for a way to download a file with these values?
Here is a quick example of how to do that:
Let's say I have an a-tag in my html like this
<a id="Button" download="download.txt">Download</a>
I can then use javascript to make it download a file with text in it
Button = document.getElementById('Button');
theText="Hello";
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);
// returns a URL you can use as a href
return textFile;
};
Button.href=makeTextFile(theText);
Then when we click the link, it downloads a text file with the contents "Hello". I got this code from somewhere a really long time ago when I was working on a project, but I don't remember where it is from.
If this isn't what you are asking for, please clarify your question.
Related
I am trying to write to a JSON file in a client side react web app. I have a nested object and I would like to be able to save this as a JSON file that a user can download.
Is this possible?
For example, here is my javascript object is:
{
summary: {
totals: {
apples: 3,
oranges: 2,
}
}
}
Yes Tyler, it is very possible.
You need to make use of blobs to do that.
Here's a sample that downloads a file containing the text "I'm a ninja!" :
let txt = "I'm a ninja"; // we all want to be one, don't we? ;)
let blob = new Blob([txt], {type: 'text/plain'});
// Only way to initiate a download is by clicking a download link,
// so let's make one
let ln = document.createElement('a');
ln.href = URL.createObjectURL(blob);
ln.download = 'ninja.txt';
ln.click(); // trigger the download
// Remove the blob url reference to free up memory
URL.revokeObjectURL(ln.href);
The only change you'd have to make is to replace txt's content with a string version of the json by calling JSON.stringify on the object. Oh, and you should also change the file name to something like data.json.
You can learn more about blobs here.
I'm creating a Google Chrome extension at the moment and I was wondering if it's possible for it to both create JSON files to download (export) and create a button where users can make the extension open and parse JSON files that they have saved in their local file system or on a USB stick (import)?
The parsing of each JSON from the local file system would simply involve reading off each key-value pair and doing something with the data. It would only have to deal with strings, so nothing complicated.
**EDIT: **My question is not a duplicate of this one because I'm not interested in changing the user's download path. All I want is to enable them to, with their consent, download a file to their normal download directory (which Filesaver.js can do). Plus, that post says nothing about importing.
You can fake link to "download" imaginary array MyData or whatever,:
var MyArray = [elem1, elem2, ....];
var _myArray = JSON.stringify(MyArray , null, 4); //indentation in json format, human readable
var vLink = document.createElement('a'),
vBlob = new Blob([_myArray], {type: "octet/stream"}),
vName = 'watever_you_like_to_call_it.json',
vUrl = window.URL.createObjectURL(vBlob);
vLink.setAttribute('href', vUrl);
vLink.setAttribute('download', vName );
vLink.click();
this will export/download your array into json file named as vName variable.
If you wish to import/read file:
create input element (type=file) and make it invisible (here I'm having html element and then adding js listener in script)
<input type="file" id="importOrig" accept=".json" style="display:none"/>
script
importOrig.addEventListener("change", importFun, false);
make button fakeImp (or any element), that you can style as you wish and that will be used as trigger for importing event
fakeImp.onclick = function () {importOrig.click()}
import function (from listener)
function importFun(e) {
var files = e.target.files, reader = new FileReader();
reader.onload = _imp;
reader.readAsText(files[0]);
}
function _imp() {
var _myImportedData = JSON.parse(this.result);
//here is your imported data, and from here you should know what to do with it (save it to some storage, etc.)
......
importOrig.value = ''; //make sure to clear input value after every import
}
I am developing a custom application in "ServiceNow" which requires Javascript and HTML coding. So, I have a field say, "description" on my form. How may I save this field's value to a word document on the desktop?
While JavaScript cannot create a file for you to download by itself, ServiceNow does have a way for you to create one. Creating a Word document is impossible without the use of a MID server and some custom Java code, but if any file type will do you can create an Excel file using an export URL. To test this out, I made a UI Action in a developer instance running Helsinki on the Problem table. I made a list view that contains only the field that I wanted to save, and then used the following code in the UI action:
function startDownload() {
window.open("https://dev13274.service-now.com/problem_list.do?EXCEL&sysparm_query=sys_id%3D" +
g_form.getUniqueValue() + "&sysparm_first_row=1&sysparm_view=download");
}
When the UI action is used, it opens a new tab that will close almost immediately and prompt the user to save or open an Excel file that contains the contents of that single field.
If you want to know more about the different ways you can export data from ServiceNow, check their wiki-page on the subject.
You can use the HTML5 FileSystem API to achieve that
window.requestFileSystem(window.PERSISTENT, 1024*1024, function (fs) {
fs.root.getFile('file.txt', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([description.value], {type: 'text/plain'});
fileWriter.write(blob);
});
});
});
FYI, chrome supports webkitRequestFileSystem.
Alternatively, use a Blob and generate download link
var text = document.getElementById("description").value;
var blob = new Blob([text], {type:'text/plain'});
var fileName = "test.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileName;
downloadLink.href = window.webkitURL.createObjectURL(textFile);
downloadLink.click();
Javascript protects clients against malicious servers who would want to read files on their computer. For that reason, you cannot read or write a file to the client's computer with javascript UNLESS you use some kind of file upload control that implicitely asks for the user's permission.
I am trying to read a local file and have each line as an index in an array using JavaScript. I have been searching for the past 20 minutes and either I'm stupid or there really isn't an answer that pertains to my problem (...but it's probably the former :P). I am really new to JavaScript so if you have an answer could you please comment the code just to I know what's going on?
Also, from the searching I've done on the internet some people said JavaScript can't read local file for security reasons so if that is correct is there another language I can use? I'm a bit familiar with PHP if that is an option, which I doubt it is.
EDIT
As per thg435's question, I'll explain what I am trying to accomplish.
My project is to analyze a BUNCH of water quality data that has been collected by the Ontario gov't (which I've done) and display it in some way. I have chosen to display it on a webpage using the Google Maps API. I currently have a file of chemicals that were found. Each line is a different chemical. I would like to read the file in an array then create an option menu displaying the chemicals in the array.
Also, the local file I would like to read will the be the same name and location all the time. I have seen people have boxes where the user clicks and chooses their file or to drag and drop but that's not what I'm looking for.
I don't think I explained this properly. I have a file in the same directory as my HTML and JavaScript files that contains words. Example:
Line 1: "Iron"
Line 2: "Aluminum"
Line 3: "Steel"
etc...
I would like to read the file and parse each line into a different index in an array. I don't want the user to be able to choose which file to read using the <input ... /> thing.
You're going to want to take a look at the FileReader API. This should allow you to read the text of a local file via readAsText(). This won't work in every browser but should work in all modern browser. You can see which browsers support it here.
Example:
<input id="file" type="file" />
var filesInput = document.getElementById("file");
filesInput.addEventListener("change", function (event) {
var files = event.target.files;
var file = files[0];
var reader = new FileReader();
reader.addEventListener("load", function (event) {
var textFile = event.target;
alert(textFile.result);
});
reader.readAsText(file);
});
It's not possible to invoke the FileReader API without user interaction. Consequently, your user would have to select whatever file to load in order for it to be read in pure JS. Since I'm assuming this will be up on a server, why not just put the list of chemicals also up on the server and GET the JSON encoded array of the results. Then you can decode them with Javascript.
You can access local files in 2 ways that I know of. The first way is making the user drag-and-drop the files onto the page, and using an <input type="file"> tag.
For the former, you would need to do the following:
addEventListener('dragover', function(e){e.preventDefault();});
addEventListener('drop', function(e) {
eventHandler.call(e.dataTransfer||e.clipboardData);
e.preventDefault();
});
For the latter, you'd need to add an event listener for the change event on the input:
document.getElementById('upload').addEventListener('change', eventHandler)
And for both, you'd need to have this as a basic callback function:
function eventHandler() {
var file = this.files[0]; //get the files
var reader = new FileReader(); //initiate reader
reader.onloadend = callbackFn; //set event handler
reader.readAsText(file); //initiate reading of files
if (this.id) { //only run if this is the input
var id = this.id;
this.outerHTML = this.outerHTML; //this resets the input
document.getElementById(id).addEventListener('change', eventHandler); //reattach event handler
}
function callbackFn(e) {
document.getElementById('output').value = e.target.result; //output it to a textarea
}
}
Here is a demo where the text contents (that what you see when opening it in notepad) of any file you drop in it, or any file you select from the input, is put in the textarea.
For more information, see https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications.
I have some text data (say var a = 'Hello World From Javascript';)in javascript variable in current window. I want to do the following
through javascript-
1. open a new window and write the text data to the window.
2. set the content type to text/plain.
3. set the content-disposition to attachment, so that download prompt comes.
4. user downloads the text data as a text file and saves it to his local disk.
is this all possible through javascript?
I know we can make ajax calls to server or redirect but in this case instead of following above steps. But in this case, these workarounds are not adaptable.
you can do that using JS & HTML5 features. Please find below a sample code.
var fileParts = ['Hello World From Javascript'];
// Create a blob object.
var bb = new Blob(fileParts,{type : 'text/plain'});
// Create a blob url for this.
var dnlnk = window.URL.createObjectURL(bb);
var currentLnk = $('#blobFl').attr('href');
// blobFl is the id of the anchor tag through which the download will be triggered.
$('#blobFl').attr('href',dnlnk);
$('#blobFl').attr('download','helloworld.txt');
// For some reason trigger from jquery dint work for me.
document.getElementById('blobFl').click();
Triggering a file download without any server request
Unfortunately this is not something you can do with normal browser capabilities. Something like flash or a browser-specific plugin will get you what you need, but security limitations within javascript will not let you download arbitrary data created within the browser.
Also the 'data' url is not supported across all browser/version combinations. I am not sure if your users are constrained on what browser they are using or not but that may limit what you can do with that solution.
Source: Triggering a file download without any server request
If you already have the file on the server (I make an ajax call to generate and save a PDF on the server) - you can do this
window.location.replace(fileUrl);
No, Content-Disposition is a response header, it has to come from the server. I think you could do it with Flash but I wouldn't recommend it.
Here's a clean, pure js version of #Rajagopalan Srinivasan's answer:
var fileParts = ["Hello World From Javascript"];
// The anchor tag to use.
const blobLink = document.getElementById("blobLink");
// Create a blob object.
var blob = new Blob(fileParts, { type: "text/plain" });
// Create a blob url for this.
var blobUrl = window.URL.createObjectURL(blob);
blobLink.setAttribute("href", blobUrl);
blobLink.setAttribute("download", "helloworld.txt");
blobLink.click();
<a id="blobLink">Download</a>