Assign createElement to variable in React - javascript

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);
};

Related

Blob url doesn't exsists?

Blob link is created, but the link returns 404 error
About this code; I am making markdown text editor, and am working on copy/paste image functionality, such as from screenshot. When paste action is made, this code should console.log blob url of a pasted image. But it looks like image doesn't exsists when I go to blob link.
What I did wrong for passing the image as blob?
code
import { useState } from 'react'
import { ReactMarkdown } from 'react-markdown/lib/react-markdown'
export default function Home() {
const [input, setInput] = useState('')
const handlePaste = async(e) => {
var items = e.clipboardData.items;
let image = [].slice.call(items).filter((obj)=> {
// Filter the image items only
return obj.type.indexOf('image') !== -1;
})
const item = image[0];
console.log(item)
// Get the blob of image
const blob = await item.getAsFile();
let blobURL = URL.createObjectURL(blob);
console.log(blobURL)
};
return (
<>
<textarea
name=""
id=""
cols="30"
rows="10"
value={input}
onPaste={handlePaste}
onChange={(e)=>setInput(e.target.value)}
/>
<ReactMarkdown childrenhow ={input}/>
</>
)
}
You can't "go to the link". You can access the blob as a File object, and you can use the object URL as e.g. the src attribute of an img tag within the same document. But the object URL stops referring to anything as soon as you leave the page.

Any function to Download rendered images from Fetched Api in javascript

I tried to get random images from unsplash api by given code below, now i am looking for to way to DOWNLOAD displayed image from that Api
const numItemsToGenerate = 1;
function renderItem(){
fetch(`https://source.unsplash.com/920x720?
beach`).then((response)=> {
let item = document.getElementById('container');
item.innerHTML = `
<img class="beach_image" src="${response.url}"
alt="beach image"/>
`
})
}
for(let i=0;i<numItemsToGenerate;i++){
renderItem();
}
I have created a function, that downloads the image from the unsplash. But the problem is, it doesn't work on Stackoverflow's snippet, since is creates null blob URL. You need to run this program on a server (like localhost), in order to work.
Try it on - https://jsfiddle.net/xt5wb2vn/
HTML
<div id="container">
</div>
<button class="download">Click to download</button>
JavaScript
const numItemsToGenerate = 1;
function downloadImage(url) {
let a = document.createElement("a");
a.href = url;
a.download = 'image.jpg';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
function renderItem() {
fetch(`https://source.unsplash.com/920x720?beach`)
.then(resp => resp.blob())
.then(image => {
const image_url = URL.createObjectURL(image)
let item = document.getElementById('container');
item.innerHTML = `<img class="beach_image" src="${image_url}" alt="beach image"/>`;
return image_url;
}).then(url=>document.querySelector(".download").onclick = ()=>downloadImage(url))
}
renderItem()
Use URL.createObjectURL
So, the function should look like
fetch(`https://source.unsplash.com/920x720?beach`)
.then(resp => resp.blob())
.then(image => {
const image_url = URL.createObjectURL(image)
const item = document.getElementById('container')
item.src = image_url
})

Calling href from onclick method does not work

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>

Generate a json file from data got after user adds it to the webpage

I want to append information to a json file, when something is done on my webpage. For example, when a button clicked, I want information from my textarea be added to a json "message" field. The same with name and e-mail. How can I do that using JS/jQuery?
var info = {};
showJSON();
function generateNewData(attribute) {
info[attribute] = $('#' + attribute).val();
showJSON();
}
function showJSON() {
$('#json').html(
JSON.stringify(info, null, 2)
);
}
function downloadJSON() {
saveData(info, 'my-json-filename.json');
}
function saveData(data, fileName) {
let a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
let json = JSON.stringify(data, null, 2), // remove ', null, 2' if you don't want indentation
blob = new Blob([json], { type: "octet/stream" }),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' id='name' onkeypress='generateNewData("name")'/>
<br />
<input type='email' id='email' onkeypress='generateNewData("email")'/>
<br />
<textarea id='message' onkeypress='generateNewData("message")'></textarea>
<pre id='json'></pre>
<button onClick='downloadJSON();'>Download JSON</button>
So for example if we want to generate a JSON object after the user writes anything new then we can do the following snippet...

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>

Categories