I'm trying to make a file uploader for my blog system which would just let users drop files in it and it would automatically upload them to server. Strangely (for me), console.log outputs dataArray before it gets filled, while calling it after a timeout outputs it correctly.
For example, if I drop 4 files on my drop area, I would get this:
[]
[file1, file2, file3, file4]
Then I drop 4 more files without uploading/refreshing and I get:
[file1, file2, file3, file4]
[file1, file2, file3, file4, file5, file6, file7, file8]
So my script is working asynchronously for some reason? Can somebody tell me what I'm doing wrong here?
var dataArray = [];
$('.dropArea').bind(
{
drop: function(e)
{
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
$.each(files, function(index, file)
{
var fileReader = new FileReader();
fileReader.onload = (function(file)
{
return function(e)
{
var image = this.result;
dataArray.push({
name : file.name,
value: image
});
}
})(files[index]);
fileReader.readAsDataURL(file);
});
console.log(dataArray);
setTimeout(function() { console.log(dataArray) }, 1000);
},
});
you should console.log() in the callback.
fileReader.onload = (function(file)
{
return function(e)
{
var image = this.result;
dataArray.push({
name : file.name,
value: image
});
console.log(dataArray);
}
})(files[index]);
if you call it outside of the callback, it will run immediately after the image is starting to load instead of when the images are finished loading.
I've quickly drawn an image for clarification:
You can solve this by comparing the amount of images that is dropped and the amount of images that finished loading, like so:
var dataArray = [];
var count = 0; // amount of files dropped
var ready = 0; // amount of files finished loading
$('.dropArea').bind(
{
drop: function(e)
{
...
$.each(files, function(index, file)
{
count++; // we start handling a file here so we increment
...
fileReader.onload = (function(file)
{
return function(e)
{
...
ready++; // this image has finished loading so we increment
}
})(files[index]);
});
setTimeout(function() {
if(ready === count) {
// all images have been loaded
console.log(dataArray);
}
}, 1000);
},
});
Just as #Tim S. answered, onload event is fired when file starts loading, and it can take some time depending on file size. Here is how I solved discovering if all files are loaded.
drop: function(e)
{
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
console.log(files.length + " queued for upload");
var counter = 0;
var loaded = 0;
$.each(files, function(index, file)
{
counter++;
console.log("File #"+counter+" loading started.")
if (!files[index].type.match('image.*'))
{
$('.dropArea').html(message.error.onlyImage);
errorMessage++;
}
var fileReader = new FileReader();
fileReader.onload = (function(file, count)
{
return function(e)
{
var image = this.result;
dataArray.push({
name : file.name,
value: image
});
loaded++;
console.log("File #"+count+" loaded.");
if (loaded == files.length) {
console.log("Loading finished!");
}
}
})(files[index], counter);
fileReader.readAsDataURL(file);
});
}
And really, console log output looks like this:
4 queued for upload 9a840a0_part_2_dragndrop_2.js:25
File #1 loading started. 9a840a0_part_2_dragndrop_2.js:32
File #2 loading started. 9a840a0_part_2_dragndrop_2.js:32
File #3 loading started. 9a840a0_part_2_dragndrop_2.js:32
File #4 loading started. 9a840a0_part_2_dragndrop_2.js:32
File #2 loaded. 9a840a0_part_2_dragndrop_2.js:52
File #4 loaded. 9a840a0_part_2_dragndrop_2.js:52
File #3 loaded. 9a840a0_part_2_dragndrop_2.js:52
File #1 loaded. 9a840a0_part_2_dragndrop_2.js:52
Loading finished!
As can be seen, file #2 was loaded first because it is the smallest one, while #1 loaded last while it is the largest.
Related
Is it possible to simulate/fake the drop event using javascript only? How to test this type of event?
Take for example this dnd upload sample page , is it possible to trigger the "drop" event with a file without actually dropping a file there? Let's say clicking on a button?
I have started writing a Sukuli script that can control the mouse and do the trick but I was looking for a better solution.
EDIT
#kol answer is a good way to get rid of the drag and drop event but I still have to manually select a file from my computer. This is the bit I am interested in simulating. Is there a way to create a file variable programatically?
var fileInput = document.getElementById('fileInput'),
file = fileInput.files[0];
1. Dropping image selected by the user
I've made a jsfiddle. It's a stripped-down version of the html5demos.com page you've referred to, but:
I added an <input type="file"> tag which can be used to select an image file from the local computer, and
I also added an <input type="button"> tag with an onclick handler, which simulates the "drop file" event by directly calling the ondrop event handler of the DND-target div tag.
The ondrop handler looks like this:
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
That is, we have to pass an argument to ondrop, which
has a dataTransfer field with a files array subfield, which contains the selected File, and
has a preventDefault method (a function with no body will do).
So the onclick handler of the "Simulate drop" button is the following:
function simulateDrop() {
var fileInput = document.getElementById('fileInput'),
file = fileInput.files[0];
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
}
Test
Select an image file (png, jpeg, or gif)
Click on the "Simulate drop" button
Result
2. Dropping autogenerated test files without user interaction (GOOGLE CHROME ONLY!!!)
I've made another jsfiddle. When the page is loaded, a function gets called, which:
creates a text file into the temporary file system, and
loads and drops this text file into the target <div>; then
creates an image file into the temporary file system, and
loads and drops this image file into the target <div>.
The code of this drop-simulator function call is the following:
(function () {
var fileErrorHandler = function (e) {
var msg = "";
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = "QUOTA_EXCEEDED_ERR";
break;
case FileError.NOT_FOUND_ERR:
msg = "NOT_FOUND_ERR";
break;
case FileError.SECURITY_ERR:
msg = "SECURITY_ERR";
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = "INVALID_MODIFICATION_ERR";
break;
case FileError.INVALID_STATE_ERR:
msg = "INVALID_STATE_ERR";
break;
default:
msg = "Unknown Error";
break;
};
console.log("Error: " + msg);
},
requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
dropFile = function (file) {
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
};
if (!requestFileSystem) {
console.log("FileSystem API is not supported");
return;
}
requestFileSystem(
window.TEMPORARY,
1024 * 1024,
function (fileSystem) {
var textFile = {
name: "test.txt",
content: "hello, world",
contentType: "text/plain"
},
imageFile = {
name: "test.png",
content: "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
contentType: "image/png",
contentBytes: function () {
var byteCharacters = atob(this.content),
byteArrays = [], offset, sliceSize = 512, slice, byteNumbers, i, byteArray;
for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return byteArrays;
}
};
// Create and drop text file
fileSystem.root.getFile(
textFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + textFile.name + ")");
fileSystem.root.getFile(
textFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + textFile.name + "): " + e.toString());
};
fileWriter.write(new Blob([ textFile.content ], { type: textFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
// Create and drop image file
fileSystem.root.getFile(
imageFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + imageFile.name + ")");
fileSystem.root.getFile(
imageFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + imageFile.name + "): " + e.toString());
};
fileWriter.write(new Blob(imageFile.contentBytes(), { type: imageFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
},
fileErrorHandler
);
})();
The content of the auto-generated text file is given as a string, and the content of the image file is given as a base64-encoded string. These are easy to change. For example, the test text file can contain not just plain text, but HTML too. In this case, don't forget to change the textFile.contentType field from text/plain to text/html, and to add this content type to the acceptedTypes array and to the previewfile function. The test image can also be changed easily, you just need an image-to-base64 converter.
I had to extend the drop handler code to handle text files in addition to images:
acceptedTypes = {
'text/plain': true, // <-- I added this
'image/png': true,
'image/jpeg': true,
'image/gif': true
},
...
function previewfile(file) {
if (tests.filereader === true && acceptedTypes[file.type] === true) {
var reader = new FileReader();
if (file.type === 'text/plain') { // <-- I added this branch
reader.onload = function (event) {
var p = document.createElement("p");
p.innerText = event.target.result;
holder.appendChild(p);
}
reader.readAsText(file);
} else {
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result;
image.width = 250; // a fake resize
holder.appendChild(image);
};
reader.readAsDataURL(file);
}
} else {
holder.innerHTML += '<p>Uploaded ' + file.name + ', ' + file.size + ' B, ' + file.type;
console.log(file);
}
}
Note that after loading the jsfiddle, the autogenerated files can be listed for debugging purposes:
Result
The screenshot shows that the simulated drop inserted the content of the autogenerated text file before the autogenerated image. The HTML code of the DND-target <div> looks like this:
<div id="holder" class="">
<p>hello, world</p>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0=" width="250">
</div>
#kol answer is a good way to get rid of the drag and drop event but I
still have to manually select a file from my computer. This is the bit
I am interested in simulating. Is there a way to create a file
variable programatically? -caiocpricci2
Try this
function createFile() {
var create = ["<!doctype html><div>file</div>"];
var blob = new Blob([create], {"type" : "text/html"});
return ( blob.size > 0 ? blob : "file creation error" )
};
createFile()
I'm working on hybrid mobile app using html5/js. It has a function download zip file then unzip them. The download function is not problem but I don't know how to unzip file (using javascript).
Many people refer to zip.js but it seems only reading zip file (not unzip/extract to new folder)
Very appreciate if someone could help me !!!
Have a look at zip.js documentation and demo page. Also notice the use of JavaScript filesystem API to read/write files and create temporary files.
If the zip file contains multiple entries, you could read the zip file entries and display a table of links to download each individual file as in the demo above.
If you look the source of the demo page, you see the following code (code pasted from Github demo page for zip.js) (I've added comments to explain):
function(obj) {
//Request fileSystemObject from JavaScript library for native support
var requestFileSystem = obj.webkitRequestFileSystem || obj.mozRequestFileSystem || obj.requestFileSystem;
function onerror(message) {
alert(message);
}
//Create a data model to handle unzipping and downloading
var model = (function() {
var URL = obj.webkitURL || obj.mozURL || obj.URL;
return {
getEntries : function(file, onend) {
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(onend);
}, onerror);
},
getEntryFile : function(entry, creationMethod, onend, onprogress) {
var writer, zipFileEntry;
function getData() {
entry.getData(writer, function(blob) {
var blobURL = creationMethod == "Blob" ? URL.createObjectURL(blob) : zipFileEntry.toURL();
onend(blobURL);
}, onprogress);
}
//Write the entire file as a blob
if (creationMethod == "Blob") {
writer = new zip.BlobWriter();
getData();
} else {
//Use the file writer to write the file clicked by user.
createTempFile(function(fileEntry) {
zipFileEntry = fileEntry;
writer = new zip.FileWriter(zipFileEntry);
getData();
});
}
}
};
})();
(function() {
var fileInput = document.getElementById("file-input");
var unzipProgress = document.createElement("progress");
var fileList = document.getElementById("file-list");
var creationMethodInput = document.getElementById("creation-method-input");
//The download function here gets called when the user clicks on the download link for each file.
function download(entry, li, a) {
model.getEntryFile(entry, creationMethodInput.value, function(blobURL) {
var clickEvent = document.createEvent("MouseEvent");
if (unzipProgress.parentNode)
unzipProgress.parentNode.removeChild(unzipProgress);
unzipProgress.value = 0;
unzipProgress.max = 0;
clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.href = blobURL;
a.download = entry.filename;
a.dispatchEvent(clickEvent);
}, function(current, total) {
unzipProgress.value = current;
unzipProgress.max = total;
li.appendChild(unzipProgress);
});
}
if (typeof requestFileSystem == "undefined")
creationMethodInput.options.length = 1;
fileInput.addEventListener('change', function() {
fileInput.disabled = true;
//Create a list of anchor links to display to download files on the web page
model.getEntries(fileInput.files[0], function(entries) {
fileList.innerHTML = "";
entries.forEach(function(entry) {
var li = document.createElement("li");
var a = document.createElement("a");
a.textContent = entry.filename;
a.href = "#";
//Click event handler
a.addEventListener("click", function(event) {
if (!a.download) {
download(entry, li, a);
event.preventDefault();
return false;
}
}, false);
li.appendChild(a);
fileList.appendChild(li);
});
});
}, false);
})();
})(this);
==== UPDATED QUESTION ====
I have control over onComplete state. That's not the case. The problem is that I don't know how to remove currently uploaded item's Progress Bar. Pls, check the screenshot.
I am using a jQuery plugin for multiupload with the support of HTML5 File API located on this website named damnUploader.
File upload works fine, but I'm stuck at the point where I need to hide the uploading progress bar once the upload is finished, but do not know how to do it without any special key to tell to remove progress bar from that element.
==== UPDATED QUESTION ====
To clarify my question, here is a screenshot. 5th and 6th images are at the uploading state. 6th image is about to be finished, so once it's successfully uploaded, I want to hide that progress bar which is below that image, but without touching the other progress bars on the other items.
Here is the javascript code (just search the function where is console.log(this._id); line:
var announcements = function () {
/*** ******************** ***/
/*** 1.1 MAIN INIT METHOD ***/
function _init() {
// Main inits on document ready state
}
/*** ********************* ***/
/*** 1.2 PRIVATE FUNCTIONS ***/
function _form_upload(){
// Main form for fallbacks
var $form_form = $('#form');
// Standard input file
var $form_file_input = $('#file_uploader');
// File POST field name (for ex., it will be used as key in $_FILES array, if you using PHP)
var $form_file_fieldName = 'image-file';
// Upload url
var $form_file_url = '/announcements/form_file_upload/' + $form_file_fieldName;
// List of available thumbnail previews based on selected files
var $form_file_list = $('#form_file_list');
// File upload progress
var $form_file_progress = $('#form_file_progress');
// Settings
var $form_file_autostartOn = true;
var $form_file_previewsOn = true;
// Misc
var isImgFile = function(file) {
return file.type.match(/image.*/);
};
var imagesCount = $form_file_list.length + 1;
var templateProgress = $form_file_list.find('div.progress').remove().wrap('<div/>').parent().html()
var template = $form_file_list.html()
// File uploader init
$form_file_input.damnUploader({
// URL of server-side upload handler
url: $form_file_url,
// File POST field name
fieldName: $form_file_fieldName,
// Container for handling drag&drops (not required)
dropBox: $('html'),
// Expected response type ('text' or 'json')
dataType: 'JSON',
// Multiple selection
multiple: false
});
// Creates queue table row with file information and upload status
var createRowFromUploadItem = function(ui) {
var $row = $('<div class="col-xs-4"/>').appendTo($form_file_list);
var $progressBar = $('<div/>').addClass('progress-bar progress-bar-success').css('width', '0%').attr('aria-valuemin', 0).attr('aria-valuemax', 100);
var $pbWrapper = $('<div/>').addClass('progress').append($progressBar);
// Defining cancel button & its handler
/*
var $cancelBtn = $('<a/>').attr('href', 'javascript:').append(
$('<span/>').addClass('glyphicon glyphicon-remove')
).on('click', function() {
var $statusCell = $pbWrapper.parent();
$statusCell.empty().html('<i>cancelled</i>');
ui.cancel();
console.log((ui.file.name || "[custom-data]") + " canceled");
});
*/
// Generating preview
var $preview;
if ($form_file_previewsOn) {
if (isImgFile(ui.file)) {
// image preview (note: might work slow with large images)
$preview = $('<img/>').attr('width', 120);
ui.readAs('DataURL', function(e) {
$preview.attr('src', e.target.result);
});
} else {
// plain text preview
$preview = $('<i/>');
ui.readAs('Text', function(e) {
$preview.text(e.target.result.substr(0, 15) + '...');
});
}
} else {
$preview = $('<i class="fa fa-image"></i>');
}
// Constructing thumbnails markup
$('<div class="thumbnail"/>').append($preview).appendTo($row);
$row.find('.thumbnail').append('<button type="button" name="formImageRemove" value="imageRemove" class="btn btn-danger btn-xs" role="button" />');
$row.find('.thumbnail').prepend(loading);
$row.find('.uploading').append($pbWrapper);
$row.find('button').append('<i class="fa fa-fw fa-trash-o" />');
return $progressBar;
};
// File adding handler
var fileAddHandler = function(e) {
// e.uploadItem represents uploader task as special object,
// that allows us to define complete & progress callbacks as well as some another parameters
// for every single upload
var ui = e.uploadItem;
var filename = ui.file.name || ""; // Filename property may be absent when adding custom data
// We can replace original filename if needed
if (!filename.length) {
ui.replaceName = "custom-data";
} else if (filename.length > 14) {
ui.replaceName = filename.substr(0, 10) + "_" + filename.substr(filename.lastIndexOf('.'));
}
// Show info and response when upload completed
var $progressBar = createRowFromUploadItem(ui);
ui.completeCallback = function(success, data, errorCode) {
// Original filename
// console.log((this.file.name || "[custom-data]"));
if (success) {
// Add animation class for fadeout
$(this).find('.loading').addClass('animated fadeOutDown');
console.log(this._id);
console.log(ui);
// Add some data to POST in upload request once upload finished and new filename retrieved
ui.addPostData($form_form.serializeArray()); // from array
ui.addPostData('images[]', JSON.parse(data).file_name); // .. or as field/value pair
} else {
console.log('uploading failed. Response code is:', errorCode);
}
};
// Updating progress bar value in progress callback
ui.progressCallback = function(percent) {
$progressBar.css('width', Math.round(percent) + '%');
};
// To start uploading immediately as soon as added
$form_file_autostartOn && ui.upload();
};
var loading = function(){
return '<div class="loading">\n\t<div class="uploading animated fadeInUp">\n\t\t<img src="/assets/img/loaders/ajax-loader.gif" />\n\t</div>\n</div>';
}
// File Uploader events
$form_file_input.on({
'du.add' : fileAddHandler,
'du.limit' : function() {
console.error("File upload limit exceeded!");
},
'du.completed' : function() {
console.info('******');
console.info("All uploads completed!");
}
});
}
/*** ************************************************** ***/
/*** 1.3 MAKE PRIVATE FUNCTIONS ACCESSIBLE FROM OUTSIDE ***/
return {
init: function () {
_init();
},
form_upload:function(){
_form_upload();
}
};
}();
$(document).ready(function () {
announcements.init();
});
Make a custom event and trigger it with Jquery:
$( "#hide_loading" ).on( "done", function() {
( "#hide_loading" ).animate({
opacity: 0
}, 5000);
});
if ( success ) {
$( ".hide_loading").trigger( "loadingfade" );
}
and if you completely want to remove it from the DOM structure after the animation:
$( "#hide_loading" ).on( "loadingfade", function() {
$( ".hide_loading" ).animate({
//put animations here (don't forget cross browser compatibility)
opacity: 0,
}, 5000, function() { //this function is called when the animation is completed
$( "#hide_loading" ).remove();
});
});
(now just add the class hide_loading to your loading elements)
This article taken from here. It is simple responsive cube with rotating. Normally images are from <div id="cs-slider">img1 img2... < /div>. Now here i wanted to load these from images folder automatically. Like all images from images folder.
Here, i tried for this like below code.
$.ajax({
url: "task.php",
data: {
'files': 'images'
},
success: function (datas) {
var res = datas.split(",");
var len = (res).length;var k=0;
res.forEach(function (entry) {
if (entry != '') {
$('#cs-slider').prepend('<img src="images/'+entry+'" />');
}
k++;
if(k==len)
{
alert("hai3");
}
});
// alert(filelist);
},
error: function (req) {
alert('Error: ' + req.status);
}
});
But these are appending after page loaded.
How to solve this?
Code is attached here fiddle
if I understand correctly, all you need is onload event.
Images will be shown after loading.
var img_ = new Image();
img_.onload = function() {
$('#cs-slider').prepend('<img src="images/'+entry+'" />');
}
img_.src = '/images/'+entry;
I'm having an issue with getting the dimensions of a newly updated image element.
I'm using FileReader to display a preview of an image file on screen.
Once the filereader and associated code has finished executing, I retrieve the new dimensions of the image element so I can adjust them accordingly.
On some browsers, the info doesn't get updated straight away and I need to include a delay before I can retrieve the new dimensions. This results in the new image being resized according to the previous image's dimensions, and not its own.
How can I be sure the new image has been fully loaded?
I would have thought FileReader().onloadend would have been sufficient but apparently not. I think this is executed once the fileReader has loaded it, not when the DOM has rendered it. (Am I right?)
Then I found this question, which suggests using a timeout of 1 millisecond. This works sometimes, but not always. It seems to be down to the speed the browser is rendering the image (more-so available resources rather than filesize). Do we have no other way of detecting a change in these parameters?
HTML
<img src="#.png" alt=""/>
<input id="fileInput" type="file" accept='image/*' onChange="loadIt()" />
JS
preview = getElementsByTagName('img')[0];
function loadIt() {
var imgReader = new FileReader();
imgReader.readAsDataURL(document.getElementById('fileInput').files[0]); //read from file input
imgReader.onloadstart = function(e) {
//
}
imgReader.onload = function (imgReaderEvent) {
if (isImage()) {
preview.src = imgReaderEvent.target.result;
//
}
else {
preview.src = 'error.png';
//
}
}
imgReader.onloadend = function(e) {
setImage();
setTimeout(function(){
setImage();
}, 1);
setTimeout(function(){
setImage();
}, 2000);
//
}
};
function setImage() {
preview_w = preview.width;
preview_h = preview.height;
console.log('dimensions: '+avatar_preview_w+' x '+avatar_preview_h);
//
};
You should call preview.onload or preview.onloadend on your image to detect that it has finished loading. You're also calling your events after you readAsDataURL The code should look like this
var preview=document.getElementsByTagName("img")[0];
function loadIt() {
var imgReader=new FileReader();
imgReader.onload=function(){
if (isImage()) {
preview.src = imgReader.result;
preview.onload=setImage;
} else {
preview.src = 'error.png';
//
}
imgReader.readAsDataURL(document.getElementById('fileInput').files[0]); //read from file input
}
function setImage(){
preview_w = preview.width;
preview_h = preview.height;
console.log('dimensions: '+avatar_preview_w+' x '+avatar_preview_h);
}
You're calling imgReader.readAsDataURL before your .onload and .onloadend is set.
I do not know what some of the variables are with-in the body of your setImage();however, start here:
function loadIt() {
var preview = getElementsByTagName('img')[0],
setImage = function () {
preview_w = preview.width;
preview_h = preview.height;
console.log('dimensions: '+avatar_preview_w+' x '+avatar_preview_h);
},
imgReader = new FileReader();
imgReader.onloadstart = function(e) {};
imgReader.onload = function (imgReaderEvent) {
if (isImage()) {
preview.src = imgReaderEvent.target.result;
}
else {
preview.src = 'error.png';
};
};
imgReader.onloadend = function(e) {setImage();};
imgReader.readAsDataURL(document.getElementById('fileInput').files[0]); //read from file input
};