Calling href from onclick method does not work - javascript

Hello i was wondering how can i invoke an a click from a button onclick event:
I have made it work so far with these 2 methods :
<a class="button" type="application/octet-stream" href="http://localhost:5300/File" download>Click here for dld</a>
<input type="button" onclick="location.href='http://localhost:5300/File';" value="Download"/>
But i can not make it work with js ; i have tried like this:
<button onclick="Save('http://localhost:5300/File')">Download</button>
function Save(url){
var link=document.createElement('a');
link.url=url;
link.name="Download";
link.type="application/octet-stream";
document.body.append(link);
link.click();
document.body.removeChild(link);
delete link;
}
P.S I need to use the <button></button> and not the input !

Your code creates a link, clicks it then deletes it. You can instead just run window.location.href as you did in the HTML example.
onclick = "Save('http://localhost:5300/File')" > Download < /button>
function Save(url) {
window.location.href = url;
}
<button onclick="Save('http://localhost:5300/File')">Download</button>
Or, if you stick to your method of creating a link, you should set href for the link, not url.
function Save(url) {
var link = document.createElement('a');
link.href = url;
link.name = "Download";
link.type = "application/octet-stream";
document.body.append(link);
link.click();
document.body.removeChild(link);
}
<button onclick="Save('http://localhost:5300/File')">Download</button>

Add button type='button'
function Save(url) {
console.log(url)
var link = document.createElement('a');
link.url = url;
link.name = "Download";
link.type = "application/octet-stream";
document.body.append(link);
link.click();
document.body.removeChild(link);
delete link;
}
<a class="button" type="application/octet-stream" href="http://localhost:5300/File" download>Click here for dld</a>
<button type='button' onclick="Save('http://localhost:5300/File')">Download</button>

Do you actually need to create an a element? If not, I would use window.location.href, which is similar to clicking on a link.
Example:
function Save(url){
window.location.href = url;
}
The only issue with this might be if you're linking to an HTTP (non-secure) site from an HTTPS (secure) site.

const btn = document.querySelector('button');
btn.addEventListener('click', function(e) {
e.preventDefault();
save('http://localhost:5300/File');
});
function save(url) {
let link = document.createElement('a');
link.href = url;
link.name = "Download";
link.type = "application/octet-stream";
document.body.append(link);
link.click();
document.body.removeChild(link);
delete link;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Download</button>

Related

Download a file from a link on button value

I searched a lot but couldn't find a solution I thank anyone who can help me.
I want to download files on button click but based on values in the text of buttons.
I have three buttons in my HTML like this
<input type="button" onclick="myFunction(this, name1.mp3)" value="button1.mp3">
<input type="button" onclick="myFunction(this, name2.mp3)" value="button2.mp3">
<input type="button" onclick="myFunction(this, name3.mp3)" value="button3.mp3">
my JavaScript is
function myFunction(elmnt, name) {
var url = "http://mysite*com/" + elmnt.value;
var downloadFileWithThisName = name;
---my download code---
}
How can I download my url with the name I passed to function?
what should I write for ---my download code--- part?
Thank you in advance.
function myFunction(elmnt, name) {
var url = "http://mysite*com/" + elmnt.value;
const a = document.createElement('a');
a.href = url;
a.download = name; // here you can specify your filename
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
What you could do is to dynamically create an A element, add the 'download' attribute, set the Href and click it, all in code. Then remove it from the DOM.
The best answer judging for your code is shown here: https://stackoverflow.com/a/42696866/1891140
var file_path = 'host/path/file.ext';
var a = document.createElement('A');
a.href = file_path;
a.download = file_path.substr(file_path.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
But you also can do it by using a simple JQUERY:
$("<a href='"+url+"' download class='hidden-a'></a>").appendTo("body");
$(".hidden-a")[0].click();

Capturing cancel event from browser

I am using the following code to create an document.createElement reference, but I am unable to handle if the user clicks cancel. any inputs on how to achieve it ? I am using Angular.
My Typescript code is given below
downloadFile(){
url = 'data:application/vnd.ms-excel;utf-8,test';
let link = document.createElement("a");
document.body.appendChild(link);
link.href = url;
link.download = fileNameToBeDownloaded + '.xls';
link.dispatchEvent(new MouseEvent(`click`, {bubbles: true, cancelable: true, view: window}));}
HTML code is given below
<button type="button" (click)=downloadFile() [disabled]="selectedFileId=='' || selectedFileId==undefined || selectedFileId=='Select' " class="btn btn-primary btn-md btnStyle">Download as a file</button>

Assign createElement to variable in React

I am new to React and would like to use my method (works fine in plain js). I have got a problem with assigning createElement to variable.
class UploadBar extends Component {
state = {
selectedFile: null
};
fileSelectedHandler = event => {
this.setState({
selectedFile: event.target.files[0]
});
};
fileLocalHandler = event => {
event.preventDefault();
let link = URL.createObjectURL(this.selectedFile);
let link = document.createElement("a");
link.href = URL.createObjectURL(this.selectedFile);
document.body.appendChild(link);
link.download = this.selectedFile.name;
link.click();
document.body.removeChild(link);
};
render() {
return (
<div id="uploadBar">
<input
multiple
type="file"
accept="application/pdf"
onChange={this.fileSelectedHandler}
/>
<button id="uploadBtn" onClick={this.fileLocalHandler}>
Upload a file
</button>
</div>
);
}
}
Could you help me with proper use of my fileLocalHandler method?
You want to access the selected file from this.state, not directly from this:
fileLocalHandler = event => {
event.preventDefault();
const { selectedFile } = this.state;
let link = document.createElement("a");
link.href = URL.createObjectURL(selectedFile);
document.body.appendChild(link);
link.download = selectedFile.name;
link.click();
document.body.removeChild(link);
};

Saving HTML5 textarea contents to file

Could someone help me save the contents of a HTML5 textArea to file, preferably using JavaScript?
<textarea id="textArea">
Notes here...
</textarea>
<button type="button" value="save"> Save</button>
That should do it.
function saveTextAsFile() {
var textToWrite = document.getElementById('textArea').innerHTML;
var textFileAsBlob = new Blob([ textToWrite ], { type: 'text/plain' });
var fileNameToSaveAs = "file.txt"; //filename.extension
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null) {
// Chrome allows the link to be clicked without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
} else {
// Firefox requires the link to be added to the DOM before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
var button = document.getElementById('save');
button.addEventListener('click', saveTextAsFile);
function destroyClickedElement(event) {
// remove the link from the DOM
document.body.removeChild(event.target);
}
#textArea {
display: block;
width: 100%;
}
<textarea id="textArea" rows="3">
Notes here...
</textarea>
<button type="button" value="save" id="save">Save</button>
JSFiddle
A simplified version of the code in the answers:
function download(){
var text = document.getElementById("my-textarea").value;
text = text.replace(/\n/g, "\r\n"); // To retain the Line breaks.
var blob = new Blob([text], { type: "text/plain"});
var anchor = document.createElement("a");
anchor.download = "my-filename.txt";
anchor.href = window.URL.createObjectURL(blob);
anchor.target ="_blank";
anchor.style.display = "none"; // just to be safe!
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
}
and the html:
<textarea id="my-textarea">
Notes here...
</textarea>
<button type="button" onclick="download()">Save</button>
I tested engincancan's answer, and it was almost there, but not quite. First of all, the file format for "ecc.plist" was not recognizable anywhere. Second of all, in order for the code to work on the desktop in Safari, Chrome, and Firefox, you have to use an existing anchor tag and not create one (document.createElement('a')). The destroyClickedElement approach only works in Chrome, because it is so forgiving and lenient. And, in order for the download to work in Firefox, you have to have document.body.appendChild(downloadLink.download);
I also had wanted to save my local storage text to a file for download and the code works on desktop for Safari, Chrome and Firefox on Mac. However, I think it is impossible in iOS to save the Blob() anywhere with Chrome or Firefox. It does work, interestingly enough in Safari. For example, I can save the text file to my Wunderlist app. Here is the link my repo on Github: The Cat Whisperer on Github gh-pages
Here is the JavaScript code:
const fileDownloadButton = document.getElementById('save');
function localStorageToFile() {
const csv = JSON.stringify(localStorage['autosave']);
const csvAsBlob = new Blob([csv], {type: 'text/plain'});
const fileNameToSaveAs = 'local-storage.txt';
const downloadLink = document.getElementById('save');
downloadLink.download = fileNameToSaveAs;
if (window.URL !== null) {
// Chrome allows the link to be clicked without actually adding it to the DOM
downloadLink.href = window.URL.createObjectURL(csvAsBlob);
downloadLink.target = `_blank`;
} else {
downloadLink.href = window.URL.createObjectURL(csvAsBlob);
downloadLink.target = `_blank`;
downloadLink.style.display = 'none';
// add .download so works in Firefox desktop.
document.body.appendChild(downloadLink.download);
}
downloadLink.click();
}
// file download button event listener
fileDownloadButton.addEventListener('click', localStorageToFile);
<textarea id = "textArea">
Notes here...
</textarea>
<button onclick="savetextarea()" type="button">Save</button>
<script>
function savetextarea(){
var txt = document.getElementById("textArea").value;
document.getElementById("saveinput").value = txt;
document.forms["aForm"].submit();
}
</script>
<form action="savecontent" name="aForm">
<input id="saveinput" type="hidden" name="filecontent" value="">
</form>

How to save a base64 image to user's disk using JavaScript?

I have converted the source content from the <img> html tag to a base64String using JavaScript. The image was displayed clearly. Now I want to save that image to user's disk using javascript.
<html>
<head>
<script>
function saveImageAs () {
var imgOrURL;
embedImage.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" +
"AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" +
"9TXL0Y4OHwAAAABJRU5ErkJggg==";
imgOrURL = embedImage;
if (typeof imgOrURL == 'object')
imgOrURL = embedImage.src;
window.win = open(imgOrURL);
setTimeout('win.document.execCommand("SaveAs")', 0);
}
</script>
</head>
<body>
<a href="#" ONCLICK="saveImageAs(); return false" >save image</a>
<img id="embedImage" alt="Red dot">
</body>
</html>
This code worked well when I set the image path as source for <img> html tag. However, when I pass the source as base64String does not work.
How to achieve what I want?
HTML5 download attribute
Just to allow user to download the image or other file you may use the HTML5 download attribute.
Static file download
<a href="/images/image-name.jpg" download>
<!-- OR -->
<a href="/images/image-name.jpg" download="new-image-name.jpg">
Dynamic file download
In cases requesting image dynamically it is possible to emulate such download.
If your image is already loaded and you have the base64 source then:
function saveBase64AsFile(base64, fileName) {
var link = document.createElement("a");
document.body.appendChild(link); // for Firefox
link.setAttribute("href", base64);
link.setAttribute("download", fileName);
link.click();
}
Otherwise if image file is downloaded as Blob you can use FileReader to convert it to Base64:
function saveBlobAsFile(blob, fileName) {
var reader = new FileReader();
reader.onloadend = function () {
var base64 = reader.result ;
var link = document.createElement("a");
document.body.appendChild(link); // for Firefox
link.setAttribute("href", base64);
link.setAttribute("download", fileName);
link.click();
};
reader.readAsDataURL(blob);
}
Firefox
The anchor tag you are creating also needs to be added to the DOM in Firefox, in order to be recognized for click events (Link).
IE is not supported: Caniuse link
In JavaScript you cannot have the direct access to the filesystem.
However, you can make browser to pop up a dialog window allowing the user to pick the save location. In order to do this, use the replace method with your Base64String and replace "image/png" with "image/octet-stream":
"data:image/png;base64,iVBORw0KG...".replace("image/png", "image/octet-stream");
Also, W3C-compliant browsers provide 2 methods to work with base64-encoded and binary data:
atob()
btoa()
Probably, you will find them useful in a way...
Here is a refactored version of what I understand you need:
window.addEventListener('DOMContentLoaded', () => {
const img = document.getElementById('embedImage');
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' +
'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO' +
'9TXL0Y4OHwAAAABJRU5ErkJggg==';
img.addEventListener('load', () => button.removeAttribute('disabled'));
const button = document.getElementById('saveImage');
button.addEventListener('click', () => {
window.location.href = img.src.replace('image/png', 'image/octet-stream');
});
});
<!DOCTYPE html>
<html>
<body>
<img id="embedImage" alt="Red dot" />
<button id="saveImage" disabled="disabled">save image</button>
</body>
</html>
This Works
function saveBase64AsFile(base64, fileName) {
var link = document.createElement("a");
document.body.appendChild(link);
link.setAttribute("type", "hidden");
link.href = "data:text/plain;base64," + base64;
link.download = fileName;
link.click();
document.body.removeChild(link);
}
Based on the answer above but with some changes
Check out https://github.com/eligrey/FileSaver.js/ which wraps the HTML5 method and provides workarounds for e.g. IE10.

Categories