I am trying to create a Browser Dialog to let the user upload images to my webpage.
I know that I have to use an <input type="file"> but I do not know where (or better, when) retrieve the information when the user has accepted the prompt that appears when you click on the button.
In my case, when you click on a button, the prompt appears and I handle this event via Javascript.
Here is my code:
window.onload = function(){
var buttonFile = document.getElementById("buttonFile");
var file = document.getElementById("file");
buttonFile.onclick = function(){
document.getElementById("file").click();
}
var files = document.getElementById('file').files[0]; //I do not know where to put this line
alert(files);
};
#file{
display: none;
}
<input type="file" id="file" accept=".jpg, .png, .jpeg">
<button id="buttonFile">Upload file</button>
Of course, now is retrieving undefined because I am trying to retrieve it regardless if the prompt has appeared or not. If I put the line inside the onclick event of the button it also does not have the info yet. I also tried to create an onclick event for the file, but it also does not retrieve the info because it does not know when it has been accepted.
So here I have some questions:
Where should I put this line to get the value of the image that I am uploading?
As the filter of the input is not supported for old browsers, should I check it on the server side also, right?
If I want to check it on the server side (PHP), have I to link it to a form?
Thanks in advance!
You've got everything right so far, except you don't need to get the value of the files until the user has uploaded them. Otherwise, it will definitely be undefined.
window.onload = function() {
var buttonFile = document.getElementById("buttonFile");
var file = document.getElementById("file");
buttonFile.onclick = function() {
document.getElementById("file").click();
};
file.onchange = function(e){
if (this.files && this.files[0]) {
alert(JSON.stringify(this.files[0]));
}
};
};
1) You shouldn't put the line in the onclick handler at all.
2) You're correct in that older browsers don't check for the type. Regardless you should ALWAYS do server side validation.
3) Unless you decide to use web services.
window.onload = function() {
var buttonFile = document.getElementById("buttonFile");
var file = document.getElementById("file");
buttonFile.onclick = function() {
document.getElementById("file").click();
};
file.onchange = function() {
alert(file.files[0].name);
};
};
#file{
display: none;
}
<input type="file" id="file" accept=".jpg, .png, .jpeg">
<button id="buttonFile">Upload file</button>
Related
I have a problem which was solved by a hack and I'm looking for a better way to solve it.
What I want to do is when the user clicks input:file and selects an image it should be displayed on screen without upload (using FileReader).
The problem is, I can't reach almost anything inside Filereaders onload method (I need to reach this.image for changing image) sadly I used
let el = <HTMLImageElement>document.querySelector(".veik");
el.src = this.result;`
My code
html:
<input type="file" name="test" id="file" (change)="onChange($event)">
ts:
onChange($event){
this.readThis($event);
}
ReadThis(inputValue: any) : void {
var file:File = inputValue.target.files[0];
var myReader:FileReader = new FileReader();
myReader.onload = function(e){
let el = <HTMLImageElement>document.querySelector(".veik");
el.src = this.result;
};
myReader.readAsDataURL(file);
}
Maybe you can try to use a FileItem type to get access to the temporary file
For example:
[1]. Change your (inputValue: any) to a generic FileItem class, like:
(inputValue: FileItem),
[2] Create a constant to get access to the uploaded file, like :
const file: File = item._file
Now you can access things like file.name , file.size etc.
Hope that helps.
Cheers
I'm a newbie in html/javascript and made two buttons that can upload image (choose file button and upload button).
However, I want to make it to just a single button and don't know how to combine those two button. I already searched on google, they said we can use onchange to combine submit button but I already have onchange function that can show image right away after choosing image file to iframe.
Here is my html code for <form>
<form action="/upload", method="post", enctype="multipart/form-data">
<div style='height:0px; width:0px; overflow:hidden;'><input type="file" name="upFile" id="upFile" onchange="getCmaFileView(this, 'name').submit()" target="dropzone_1"/></div>
</form>
Also, here is my script and button
<script type = "text/javascript">
function getFile(){
document.getElementById("upFile").click();
}
</script>
...
<li><a onclick="getFile()" style="cursor:pointer; color:#000000;">Choose File</a></li>
I tried with adding .submit() in onchange, but it didn't work.
Does anybody have an idea for this?
Please please help me out here!
Thanks in advance.
EDIT
function getCmaFileInfo(obj,stype) {
var fileObj, pathHeader , pathMiddle, pathEnd, allFilename, fileName, extName;
var file;
var img, reader;
// file = upload.files[0];
upload = document.getElementsByTagName('input')[0];
holder = document.getElementById('dropzone');
reader = new FileReader();
file = upload.files[0];
var iupload, holder;
reader.onload = function (event) {
img = new Image();
//console.log(event.target.result);
img.src = event.target.result;
img.width = document.getElementById("dropzone").clientWidth;
img.height= window.innerHeight;
// note: no onload required since we've got the dataurl...I think! :)
holder.innerHTML = '';
holder.appendChild(img);
};
reader.readAsDataURL(file);
}
function getCmaFileView(obj,stype) {
getCmaFileInfo(obj,stype);
}
Can't you just add one more function/code in your getCmaFileView() - Which will just submit the form? Also it will be called after your image viewing part is done so that may solve your problem.
function getCmaFileView(obj,stype) {
getCmaFileInfo(obj,stype);
//form.submit() OR call_to_your_submit_function();
}
I have tried so many examples but none of them works
t
(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);
})();
<textarea id="textbox">Type something here</textarea>
<button id="create">Create file</button>
<a download="info.txt" id="downloadlink" style="display: none">Download</a>
here is a code which is working good but i need to download automatically without using link
is it possible?
You could use the following script to create and save automatically a file from the browser to your operating system. This code works only on latest version of Chrome.
What the script does?
It creates a temporary URL containing the specified File object or Blob object - Programmatically click the link just created so the file will be download by the browser.
Immediately after remove the link from the page.
var saveDataToFile = function (data, fileName, properties) {
window.URL = window.URL || window.webkitURL;
var file = new File(data, fileName, properties),
link = document.createElement('a');
link.href = window.URL.createObjectURL(file);
link.download = fileName;
document.body.appendChild(link);
link.click();
var timer = setTimeout(function () {
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);
clearTimeout(timer);
}, 100);
};
If you deconstruct this problem, there's a few key points:
Initially, when the user hasn't typed text into the textarea, the button should not be visible. (I may be wrong here though)
When the user starts typing, the button has to appear.
Whatever is inside the textarea after that, has to be downloadable per click on the button.
So, it's a matter of two event listeners.
The first one is "focus": when the textarea received focus, its value is an empty string, and the button appears. The user hasn't yet started typing, but there's actually no need to force them to.
The second one is "change": per every change in the field, we need to update the value of href attribute of the link, so that when the user clicks that element, file download happens, and the content is precisely what's inside the textarea. Good thing, a function passed to "change" event listener is executed with the first argument instance of Event, which means you can do event.target.value to get the new value per every change. It means, the whole text from within textarea.
Summing up, it's
<textarea id="textbox" placeholder="Type something here"></textarea>
<a download="info.txt" id="create" href="#" style="display: none;">Create file</a>
and
(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');
var textbox = document.getElementById('textbox');
textbox.addEventListener('focus', function (event) {
create.style.display = 'block';
create.href = makeTextFile(''); // initially, the text is empty.
});
textbox.addEventListener('change', function (event) {
create.href = makeTextFile(event.target.value); // per every change, update value of href attribute of #create
});
})();
Take note that only a element can have href assigned with Blob value. Using a button element would be a little bit more complicated, so it might be easier to just make the a element look like a button.
See the Codepen to make sure it works as you expect, or feel free to edit it otherwise.
I want to display the image using the upload form and submit button.
But the problem though, I can't make the image appear.
Here's what I did.
function myFunction() {
var x = document.getElementById("myFile").value;
document.getElementById('myImg').src = document.getElementById("myFile").name;
<form>Select a file to upload:
<input type="file" id="myFile" name=filename>
</form>
<button type="button" onclick="myFunction()">Upload This</button>
<img id="myImg" src="">
I just don't know what seems to be the problem with this.
Thank you for helping me out.
The browser does NOT allow javascript full access to the .value property of an input tag with type="file". This is for security reasons so no local path information is made available to javascript.
Thus, you can't set a .src value on an image tag based on a file input value that the end-user specified.
If you don't want to upload the image to server side, you have a possibility to do it only in the client side.
add a div to your html (dom):
<div id='bottom'>
<div id='drag-image' class='holder-file-uploader bottom-asset'> Drag here an image</div>
</div>
add this javascript:
<script>
var holder = document.getElementById('drag-image');
holder.ondragover = function () { return false; };
holder.ondragend = function () { return false; };
holder.ondrop = function (event) {
event.preventDefault && event.preventDefault();
//do something with:
var files = event.dataTransfer.files;
console.log(files);
bottomFileAdd(files, 0);
return false;
};
//Recursive function to add files in the bottom div
//this code was adapted from another code, i didn't test it
var bottomFileAdd = function (files, i) {
if(!i) i=0;
if (!files || files.length>=i) return;
var file = files.item(i);
var img = document.createElement('img');
var bottom = document.getElementById('bottom'); //this string should not be static
bottom.appendChild(img);
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target);
img.src = event.target.result;
bottomFileAdd(files, i+1);
};
reader.readAsDataURL(file);
}
</script>
note: It may not work in older browsers.
I hope it helps.
You tried to set the src attribute of the <img> tag to a local file path. However, the web browser doesn't expose the local file URL (file://...) in the value property of the <input> tag. The browser implementation may vary; Chrome, for example, gives you a fake path.
You can load the image by the FileReader API into a data URI and show it by setting the src attribute of the <img> tag:
function myFunction() {
var myFile = document.getElementById("myFile");
if (myFile.files && myFile.files.length) {
if (typeof FileReader !== "undefined") {
var fileReader = new FileReader();
fileReader.onload = function(event) {
document.getElementById("myImg").src = event.target.result;
};
fileReader.readAsDataURL(myFile.files[0]);
} else {
alert("Your browser doesn't support the FileReader API.")
}
} else {
alert("No file was selected.")
}
}
You need a fairly modern web browser for this to work:
Browser Firefox Chrome IE Opera Safari
Version 3.6 7 10 12.02 6.0.2
You can have a look at a working sample page. The final implementation of such image preview should set the <img> element to a fixed size, but your markup with my function is enough as a simple demonstration.
I'm going to develop a firefox extension which adds a button beside the file input fields (the <input type="file"> tag) when a file is selected.
The file overlay.js, which contains the extension's logic, manages the "file choose" event through this method:
var xpitest = {
...
onFileChosen: function(e) {
var fileInput = e.explicitOriginalTarget;
if(fileInput.type=="file"){
var parentDiv = fileInput.parentNode;
var newButton = top.window.content.document.createElement("input");
newButton.setAttribute("type", "button");
newButton.setAttribute("id", "Firefox.Now_button_id");
newButton.setAttribute("value", "my button");
newButton.setAttribute("name", "Firefox.Now_button_name");
parentDiv.insertBefore(newButton, fileInput);
}
}
...
}
window.addEventListener("change", function(e) {xpitest.onFileChosen(e)},false);
My problem is that, everytime I choose a file, a new button is being added, see this picture:
http://img11.imageshack.us/img11/5844/sshotn.png
If I select the same file more than once, no new button appears (this is correct).
As we can see, on the first file input, only one file has been selected.
On the second one I've chosen two different files, in effect two buttons have been created...
On the third, I've chosen three different files.
The correct behavior should be this:
when a file is chosen, create my_button beside the input field
if my_button exists, delete it and create another one (I need this, beacuse I should connect it to a custom event which will do something with the file name)
My question is: how can I correctly delete the button? Note that the my_button html code does not appear on page source!
Thanks
Pardon me if I'm thinking too simply, but couldn't you just do this?
var button = document.getElementById('Firefox.Now_button_id')
button.parentNode.removeChild(button)
Is this what you were looking for? Feel free to correct me if I misunderstood you.
Solved. I set an ID for each with the following method:
onPageLoad: function(e){
var inputNodes = top.window.content.document.getElementsByTagName("input");
for(var i=0; i<inputNodes.length; i++){
if(inputNodes[i].type=="file")
inputNodes[i].setAttribute("id",i.toString());
}
}
I call this method only on page load:
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", xpitest.onPageLoad, true);
Then I've modified the onFileChosen method in this way:
onFileChosen: function(e) {
var fileInput = e.explicitOriginalTarget;
if(fileInput.type=="file"){
var parentDiv = fileInput.parentNode;
var buttonId = fileInput.id + "Firefox.Now_button_id";
var oldButton = top.window.content.document.getElementById(buttonId);
if(oldButton!=null){
parentDiv.removeChild(oldButton);
this.count--;
}
var newButton = top.window.content.document.createElement("input");
newButton.setAttribute("type", "button");
newButton.setAttribute("id", buttonId);
newButton.setAttribute("value", "my button");
newButton.setAttribute("name", "Firefox.Now_button_name");
parentDiv.insertBefore(newButton, fileInput);
this.count++;
}
}