The follow code isn't working for me in FF/IE. Chrome works. The problem seems to be that the function 'handleImage' ins't be called. What goes wrong here?
Thanks
function handleImage(event) {
console.log('Handle the image');
var reader = new FileReader();
reader.onload = function (event) {
$('#uploader img').attr('src', event.target.result);
}
if (event.target.files[0] != undefined) {
reader.readAsDataURL(event.target.files[0]);
imageLoaderError = false
} else {
imageLoaderError = true
}
}
var imageLoader = document.getElementById('image');
var imageLoaderError = false;
imageLoader.addEventListener('change', handleImage, false);
Related
I am working with FileReader and I have come across an issue with the onLoad method of FileReader not being executed synchronously with the rest of the code. Basically I have 2 functions like these:
imageExists(url, callback) {
var img = new Image();
img.onload = function () { callback(true); };
img.onerror = function () { callback(false); };
img.src = url;
}
isImageCorrupt(file): boolean {
var reader = new FileReader();
var isCorrupt = false;
reader.readAsDataURL(file);
reader.onload = (e) => {
this.imageExists(e.target.result, (exists) => {
if (exists) {
isCorrupt = false;
// Image is not corrupt
} else {
isCorrupt = true;
//Image is corrupt
}
});
};
return isCorrupt;
}
The isImageCorrupt() function calls the reader.onLoad which calls the imageExists callback function, which also contains a image onload method.
The problem is that during the execution of the isImageCorrupt() function, the reader.onLoad has not changed the value of isCorrupt yet but the function has returned the value in the last line which is always false.
I want my function to wait for the reader.onLoad to finish its execution before the function returns the value.
maybe something like this?
isImageCorrupt(file): Promise<Boolean> {
return new Promise((resolve) => {
var reader = new FileReader();
reader.onload = (e) => {
var img = new Image();
img.onload = function () {
resolve(false);
};
img.onerror = function () {
resolve(true);
};
img.src = <string>e.target.result;
}
reader.readAsDataURL(file);
});
}
*disclaimer: I did not test it
You could use Promises. The code could be still refactorized using async/await
isImageCorrupt(file): Promise<boolean> {
return new Promise<boolean>((resolve,reject)=>{
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = ()=>{
var img = new Image();
img.src = reader.result;
img.onload = function () {
resolve(false);
};
img.onerror = function () {
resolve(true);
};
}
reader.onerror=()=>{reject(true)}
});
};
isImageCorrupt(yourFile).then((result)=>{/*HERE USE RESULT*/},(error)=>{HERE USE ERROR RESULT})
However you shouldn't return true o false, but resolve if it's ok and reject otherwise, whithout a boolean value in this way
isImageCorrupt(file): Promise<void> {
return new Promise<void>((resolve,reject)=>{
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = ()=>{
var img = new Image();
img.src = reader.result;
img.onload = function () {
resolve();
};
img.onerror = function () {
reject();
};
}
reader.onerror=()=>{reject()}
});
};
isImageCorrupt(yourFile).then(()=>{/*HERE OK*/},()=> {HERE
THERE WAS SOME ERROR/PROBLEM})
Hi I need help on how I can make my drag and drop read the .text files that is dropped in the dropzone.. I'm still exploring javascript and would need help to guide me on what is wrong with my code..
The content of the text file should be shown on the displayarea
Reference: http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
Thanks in advance!
https://jsfiddle.net/d6nur0wc/1/
(function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(event) {
event.preventDefault();
this.className = "dropzone";
console.log(event.dataTransfer.files[0]);
window.onload = function() {
var fileInput = document.getElementById('dropzone');
var fileDisplayArea = document.getElementById('displayarea');
fileInput.addEventListener('dropzone.ondrop', function(read) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(read) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
}
else {
fileDisplayArea.innerText = "File not supported!";
}
});
}
}
dropzone.ondragover = function() {
this.className = "dropzone dragover";
return false;
};
dropzone.ondragleave = function() {
this.className = "dropzone";
return false;
};
}())
Your code should be like this. you have to remove onload event listener. it can't be compatible here.
(function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(event) {
event.preventDefault();
this.className = "dropzone";
console.log(event.dataTransfer.files[0]);
var fileInput = document.getElementById('dropzone');
var fileDisplayArea = document.getElementById('displayarea');
var file = event.dataTransfer.files[0]
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(read) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
}
else {
fileDisplayArea.innerText = "File not supported!";
}
}
dropzone.ondragover = function() {
this.className = "dropzone dragover";
return false;
};
dropzone.ondragleave = function() {
this.className = "dropzone";
return false;
};
}())
I am a hybrid (Cordova) mobile app developer and my requirement is to share GIF images to various social media platforms. I have written a function that converts my image into Base64 data url. Mostly it converts the image and makes the share smooth but sometimes, it fails to share the image on click of share button. And sometimes it does not open the share window. I suspect it is taking a bit long to convert the image. Here is my sample code:
function convertFileToDataURLviaFileReader(url, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.send();
}
And this is how the function is being called:
//The below function will be called on click of share buttons
function showSnackBar(e) {
imgSource = null;
selectedImgId = null;
imgDataURL = null;
var x = document.getElementById("snackbar");
imgSource = e.target.currentSrc;
selectedImgId = e.target.id;
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
}, 3000);
//calling function to Convert ImageURL to DataURL
convertFileToDataURLviaFileReader(imgSource, function (base64Img) {
imgDataURL = base64Img;
});
$("#btnShare").click(function (e) {
if(imgDataURL != null) {
window.plugins.socialsharing.share(null, 'Android filename', imgDataURL, null)
}
})
};
Try setting a variable if the conversion isn't done yet, then launching the share dialog once the conversion is complete (notice the use of the openShare variable below):
function showSnackBar(e) {
imgSource = null;
selectedImgId = null;
imgDataURL = null;
var x = document.getElementById("snackbar");
imgSource = e.target.currentSrc;
selectedImgId = e.target.id;
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
}, 3000);
var openShare = false;
//calling function to Convert ImageURL to DataURL
convertFileToDataURLviaFileReader(imgSource, function (base64Img) {
imgDataURL = base64Img;
if(openShare){
openShare = false;
window.plugins.socialsharing.share(null, 'Android filename', imgDataURL, null);
}
});
$("#btnShare").click(function (e){
if(imgDataURL != null) {
window.plugins.socialsharing.share(null, 'Android filename', imgDataURL, null)
}else{
openShare = true;
}
});
};
I'm trying to make a small snippet to preview images before uploading them:
$.fn.previewImg=function($on){
var input = this;
try{
if (this.is("input[type='file']")) {
input.change(function(){
var reader = new FileReader();
reader.onloadend = function(){
for (var i = 0; i < $on.length; i++) {
if (/img/i.test($on[i].tagName)) $on[i].src = reader.result;
else $on[i].style.bakgroundImage = "url("+reader.result+")";
}
};
});
}else throw new exception("Trying to preview image from an element that is not a file input!");
}catch(x){
console.log(x);
}
};
I'm calling it like:
$("#file").previewImg($(".preview_img"));
but the onloadend function is never called.
FIDDLE
Actually , you got to specify the file and instruct the fileReader to read it.
Below is the corrected code.
$.fn.previewImg=function($on){
var input = this;
try{
if (this.is("input[type='file']")) {
input.change(function(evt){
var reader = new FileReader();
console.log("Input changed");
reader.onloadend = function(){
console.log("onloadend triggered");
for (var i = 0; i < $on.length; i++) {
if (/img/i.test($on[i].tagName)) $on[i].src = reader.result;
else $on[i].style.bakgroundImage = "url("+reader.result+")";
}
};
//get the selected file
var files = evt.target.files;
//instruct reader to read it
reader.readAsDataURL(files[0]);
});
}else throw new exception("Trying to preview image from an element that is not a file input!");
}catch(x){
console.log(x);
}
};
$("#file").previewImg($(".preview_img"));
i have a input file which is used to upload images. However, I have to validate its size before upload. As below is the code I've tried on.
I have a parent function, that calls the method,ValidateImageSize( ):
$('input:file').change(function (e) {
if (ValidateImageSize(this))
// do something
else
alert("wrong size");
});
and the method shown as below:
var ValidateImageSize = function (input) {
var reader = new FileReader();
reader.onload = function (e) {
var img = new Image();
img.onload = function (e) {
return this.height == 40 && this.width == 40 ? true : false;
}
img.src = e.target.result;
}
reader.readAsDataURL(input.files[0]);
};
The method ValidateImageSize() always returns 'undefined' to its parents, cause it have yet executes the onload functions.
The output I need is either true/ false. Perhaps the structure of my codes itself is incorrect.
How can I solve this?
Use callback, something like as below:
var validation_callback = function(isValid) {
if (isValid) {
// do something
} else {
alert("wrong size");
}
};
$('input:file').change(function(e) {
ValidateImageSize(this, validation_callback);
});
var ValidateImageSize = function (input, callback) {
var reader = new FileReader();
reader.onload = function (e) {
var img = new Image();
img.onload = function (e) {
var isValid = this.height == 40 && this.width == 40 ? true : false;
callback(isValid);
};
img.src = e.target.result;
};
reader.readAsDataURL(input.files[0]);
};