Filereader: Multiple file input ends with only one image as preview - javascript

Trying to figure out how to input multiple files at once and arrange them to divs. In result, only the last image of the array appears.
HTML:
<input type="file" id="imageinput" accept="image/*" onchange="handleFiles(files)" multiple>
<div class="cube-layout-1">
<div id="preview1"></div>
<div id="preview2"></div>
<div id="preview3"></div>
<div id="preview4"></div>
<div id="preview5"></div>
<div id="preview6"></div>
</div>
Javascript:
var j=0;
function counter() {
j++;
return j;
}
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var count = counter();
var preview = document.getElementById("preview"+count);
var reader = new FileReader();
reader.onload = (function (preview) {
return function () {
preview.style.backgroundImage = "url(" + reader.result + ")";
}
})(preview);
reader.readAsDataURL(file);
}
}
For example, if I choose 3 images at once, the first two divs get an empty background image and only the last div gets the image.
I know it has something to do with the reader.onload event, which triggers only when the loop ends....but how can I achieve what I am aiming for? Thanks in advance!

Check out my code try using it, I solved the Async issue, as I needed to add file name along with the preview.
function readURL(input) {
var file = document.getElementById("article_file").value;
console.log(file);
var originalname = file.replace(/C:\\fakepath\\/i, '');
console.log(name);
if (DST()) {
// Daylight Savings, EDT is UTC-4
var offset = "-4";
} else {
// Not Daylight Savings, EST is UTC-5
var offset = "-5";
}
var today = calcTime(offset);
var month = today.getMonth() + 1;
// appends 0 to monthes under 10
if (month < 10)
month = "0" + month.toString();
if ($('table.appendo.image-uploader tbody tr').length > 2)
$('table.appendo.image-uploader tbody tr').each(function (i, ele) {
if(i==1)
{
$('#image-preview-path').attr('src','src="/images/tp.gif"');
$('#image-path').attr('value','');
}
else if (i > 1)
{
$(ele).remove();
}
});
$('.upload-article').attr('name', 'Filedata[]');
var files = $('#article_file')[0].files;
var name = [];
var extension = ['.jpg','jpeg','.gif','.png'];
var flag = 1;
name['invalid'] = 'invalid';
for (var z = 0; z < files.length; z++){
var ext = (files[z].name.substr(-4)).toLowerCase();
if($.inArray(ext, extension) != -1){
} else {
flag = 2;
}
}
var count = files.length;
if(count <= '6') {
if(flag == 1) {
for (var x = 0; x < files.length; x++)
{
if (x == 0) {
var file = files[x];
var hello = file['name'].replace(/\s/g, '');
var file_name = hello.replace(/[^.a-z0-9_-\s]/gi, '').replace(/[_\s]_/g, '-');
name[file['size']] = file_name;
console.log(files[x]);
var reader = new FileReader();
reader.addEventListener('load', function (e) {
console.log(e)
$('#image-preview-path').attr('src', e.target.result);
$('#image-path').attr('value', "/images/uploads/" + today.getFullYear() + "/" + month + "/" + today.getDate() + "/" + name[e.total]);
});
reader.onerror = function (event) {
console.error("File could not be read! Code " + event.target.error.code);
};
reader.readAsDataURL(file);
} else {
var file = files[x];
var hello = file['name'].replace(/\s/g, '');
var file_name = hello.replace(/[^.a-z0-9_-\s]/gi, '').replace(/[_\s]_/g, '-');
name[file['size']] = file_name;
console.log(files[x]);
var reader = new FileReader();
reader.addEventListener('load', function (e) {
console.log(e)
if ($('table.appendo>tbody:eq(0)>tr').length - 1 > 0)
index = $('table.appendo>tbody:eq(0)>tr').length - 1
else
index = 'invalid';
var table = $('table.appendo tbody tr:eq(1)').clone();
table.find('img').attr('id', 'image-preview-path');
table.find('img').attr('src', e.target.result);
table.find('input').attr('id', 'image-path');
table.find('input').attr('value', "/images/uploads/" + today.getFullYear() + "/" + month + "/" + today.getDate() + "/" + name[e.total]);
$('table.appendo.image-uploader tbody').append(table);
});
reader.onerror = function (event) {
console.error("File could not be read! Code " + event.target.error.code);
};
reader.readAsDataURL(file);
}
}
} else {
alert('Not a valid file extension.');
$('#article_file').val("");
}
} else {
alert('You have attempted to queue too many files.\nYou may select six file.');
$('#article_file').val("");
}
}

Got the solution insted of:
return function () { preview.style.backgroundImage = "url(" + reader.result + ")";}
it should be:
return function (e) { preview.style.backgroundImage = "url(" + e.target.result + ")";}

Related

Dropzone Js get file data (csv. xlsx) before Uploading

I'm new to Dropzone Js and i want to upload a file, process data to json then upload to my Flask server.
i appreciate any kind of help, thanks.
var id = '#kt_dropzone_4';
// set the preview element template
var previewNode = $(id + " .dropzone-item");
previewNode.id = "";
var previewTemplate = previewNode.parent('.dropzone-items').html();
previewNode.remove();
var myDropzone4 = new Dropzone(id, { // Make the whole body a dropzone
url: "/Upload", // Set the url for your upload script location
headers: {
'x-csrftoken': $('#csrf_Upload').val()
},
method: "post",
parallelUploads: 5,
acceptedFiles: ".xls, .xlsx, .csv",
previewTemplate: previewTemplate,
maxFilesize: 2, // Max filesize in MB
autoQueue: false, // Make sure the files aren't queued until manually added
previewsContainer: id + " .dropzone-items", // Define the container to display the previews
clickable: id +
" .dropzone-select" // Define the element that should be used as click trigger to select files.
});
myDropzone4.on("addedfile", function (file) {
// Hookup the start button
file.previewElement.querySelector(id + " .dropzone-start").onclick = function () {
myDropzone4.enqueueFile(file);
};
$(document).find(id + ' .dropzone-item').css('display', '');
$(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'inline-block');
//remove duplicates
if (this.files.length) {
var i, len;
for (i = 0, len = this.files.length; i < len - 1; i++) // -1 to exclude current file
{
if (this.files[i].name === file.name && this.files[i].size === file.size && this.files[i]
.lastModifiedDate.toString() === file.lastModifiedDate.toString()) {
this.removeFile(file);
$('#muted-span').text('Duplicates are not allowed').attr('class', 'kt-font-danger kt-font-bold').hide()
.fadeIn(1000)
setTimeout(function () {
$('#muted-span').hide().text('Only Excel and csv files are allowed for upload')
.removeClass('kt-font-danger kt-font-bold').fadeIn(500);
}, 2500);
}
}
}
});
// Update the total progress bar
myDropzone4.on("totaluploadprogress", function (progress) {
$(this).find(id + " .progress-bar").css('width', progress + "%");
});
myDropzone4.on("sending", function (file, response) {
console.log(file)
console.log(response)
// Show the total progress bar when upload starts
$(id + " .progress-bar").css('opacity', '1');
// And disable the start button
file.previewElement.querySelector(id + " .dropzone-start").setAttribute("disabled", "disabled");
});
// Hide the total progress bar when nothing's uploading anymore
myDropzone4.on("complete", function (progress) {
var thisProgressBar = id + " .dz-complete";
setTimeout(function () {
$(thisProgressBar + " .progress-bar, " + thisProgressBar + " .progress, " + thisProgressBar +
" .dropzone-start").css('opacity', '0');
}, 300)
});
// Setup the buttons for all transfers
document.querySelector(id + " .dropzone-upload").onclick = function () {
myDropzone4.enqueueFiles(myDropzone4.getFilesWithStatus(Dropzone.ADDED));
};
// Setup the button for remove all files
document.querySelector(id + " .dropzone-remove-all").onclick = function () {
$(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'none');
myDropzone4.removeAllFiles(true);
};
// On all files completed upload
myDropzone4.on("queuecomplete", function (progress) {
$(id + " .dropzone-upload").css('display', 'none');
});
// On all files removed
myDropzone4.on("removedfile", function (file) {
if (myDropzone4.files.length < 1) {
$(id + " .dropzone-upload, " + id + " .dropzone-remove-all").css('display', 'none');
}
});
I have not found yet a way to get the uploaded data from dropzonejs. I tried to read the file with FileReader but it's not a binary data (correct me if i'm wrong).
I need to process data on myDropzone4.on("addedfile", function (file){})
and return it as a json format if possible.
I found an answer for it, I just needed to find the input type file.when using dropzone.js either you find the input type file in the html page or in their javascript file, where i found that the input type file was being created with a class to hide this element :
var setupHiddenFileInput = function setupHiddenFileInput() {
if (_this3.hiddenFileInput) {
_this3.hiddenFileInput.parentNode.removeChild(_this3.hiddenFileInput);
}
_this3.hiddenFileInput = document.createElement("input");
_this3.hiddenFileInput.setAttribute("type", "file");
_this3.hiddenFileInput.setAttribute("id", "123");
if (_this3.options.maxFiles === null || _this3.options.maxFiles > 1) {
_this3.hiddenFileInput.setAttribute("multiple", "multiple");
}
// _this3.hiddenFileInput.className = "dz-hidden-input";
}
so i gave it an id and bind an event to the input then i read the file with two functions depends on the format of the file uploaded, for csv files to json :
function getText(fileToRead) {
var reader = new FileReader();
reader.readAsText(fileToRead);
reader.onload = loadHandler;
reader.onerror = errorHandler;
}
function loadHandler(event) {
var csv = event.target.result;
process(csv);
}
function process(csv) {
// Newline split
var lines = csv.split("\n");
result = [];
var headers = lines[0].split(",");
for (var i = 1; i < lines.length - 1; i++) {
var obj = {};
//Comma split
var currentline = lines[i].split(",");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
console.log(result);
}
function errorHandler(evt) {
if (evt.target.error.name == "NotReadableError") {
alert("Canno't read file !");
}
}
Read excel files (xls,xlsx) format to json format:
var ExcelToJSON = function () {
this.parseExcel = function (file) {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
workbook.SheetNames.forEach(function (sheetName) {
// Here is your object
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[
sheetName]);
var json_object = JSON.stringify(XL_row_object);
console.log(JSON.parse(json_object));
jQuery('#xlx_json').val(json_object);
})
};
reader.onerror = function (ex) {
console.log(ex);
};
reader.readAsBinaryString(file);
};
};
the event that will detect change on the input, detect file format then use one of those to get the result in a JSON format:
$(document).ready(function () {
$('input[type="file"]').on('change', function (e) {
// EXCEL TO JSON
var files = e.target.files;
console.log(files)
var xl2json = new ExcelToJSON();
xl2json.parseExcel(files[0]);
var fileName = e.target.files[0].name;
console.log('The file "' + fileName + '" has been selected.');
// CSV TO JSON
var files = e.target.files;
if (window.FileReader) {
getText(files[0]);
} else {
alert('FileReader are not supported in this browser.');
}
});
});
I hope this helps i'm using dropzonejs with keenthemes implementation.

Hi, is it possible to convert Blob/Base64 to fileURI format using javascript/angularjs and ionic1.

I am trying to capture images using cordovaCamera and imagePicker then remove the EXIF data and create a copy of the image that I get after the metadata is removed.
In the following code I get image file in Blob format which I pass to resolveLocalFileSystemURL but unable to proceed as resolveLocalFileSystemURL does not accept blob or base64 data so is it possible to convert Blob/Base64 to fileURI format. Or is there any alternative to solve this.
In html:
<input id="erd" type="file"/>
In controllers.js :
var input = document.querySelector('#erd');
input.addEventListener('change', load);
function load(){
var fr = new FileReader();
fr.onload = process;
fr.readAsArrayBuffer(this.files[0]);
console.log(" onload "+URL.createObjectURL(this.files[0]));
}
function process(){
var dv = new DataView(this.result);
var offset = 0, recess = 0;
var pieces = [];
var i = 0;
if (dv.getUint16(offset) == 0xffd8){
offset += 2;
var app1 = dv.getUint16(offset);
offset += 2;
while (offset < dv.byteLength){
if (app1 == 0xffe1){
pieces[i] = {recess:recess,offset:offset-2};
recess = offset + dv.getUint16(offset);
i++;
}
else if (app1 == 0xffda){
break;
}
offset += dv.getUint16(offset);
var app1 = dv.getUint16(offset);
offset += 2;
}
if (pieces.length > 0){
var newPieces = [];
pieces.forEach(function(v){
newPieces.push(this.result.slice(v.recess, v.offset));
}, this);
newPieces.push(this.result.slice(recess));
var br = new Blob(newPieces, {type: 'image/jpeg'});
console.log(" pieces.length "+URL.createObjectURL(br));
$scope.strimg=URL.createObjectURL(br).toString();
//var file = new File(URL.createObjectURL(br), "uploaded_file.jpg", { type: "image/jpeg", lastModified: Date.now() });
var myFile = blobToFile(br, "my-image.jpg");
console.log('myFile'+JSON.stringify(myFile));
$scope.strimg = myFile;
createFileEntry($scope.strimg);
}
}
}
function blobToFile(theBlob,fileName){
console.log('theBlob'+theBlob+fileName);
var b = theBlob;
b.lastModifiedDate = new Date();
b.name = fileName; //Cast to a File() type
return theBlob;
}
function createFileEntry(fileURI) {
window.resolveLocalFileSystemURL(fileURI, copyFile, fail);
}
// 5
function copyFile(fileEntry) {
console.log(" copyFile "+fileEntry);
var name = fileEntry.fullPath.substr(fileEntry.fullPath.lastIndexOf('/') + 1);
var newName = name;
$scope.filepathnew="file:///storage/emulated/0/Android/data/com.offermanagement.system/files/";
window.resolveLocalFileSystemURL($scope.filepathnew, function(fileSystem2) {
fileEntry.copyTo(
fileSystem2,
newName,
onCopySuccess,
fail
);
},
fail);
}
function onCopySuccess(entry) {
$scope.$apply(function () {
$rootScope.profilepic=entry.nativeURL;
$rootScope.images.push(entry.nativeURL);
$rootScope.items.push({src:entry.nativeURL,sub:'' });
});
}
function fail(error) {
console.log("fail: " + error.code);
}
I get the following error for the above code
"Uncaught TypeError: Wrong type for parameter "uri" of resolveLocalFileSystemURI: Expected String, but got Blob."

count number entry in a CSV file using javascript in mvc

I am trying to check the file extension and count number of entry in the CSV file. At the moment the file extension check worked. My problem is the count of number row in the CSV at the moment when i run the code the count is 1 but the file selected has more than one entry. Any help please
HTML
<input type="file" name="attachmentcsv" onchange="ValidateSingleInput(this);" class="form-control" id="attachmentcsv" />
JavaScript
var _validFileExtensions = [".csv", ".CSV"];
function ValidateSingleInput(oInput) {
if (oInput.type == "file") {
var sFileName = oInput.value;
var lines = sFileName.split('\r').length;
// Check if the CSV file is valid and count the number of entry
if (sFileName.length > 0) {
var blnValid = false;
for (var j = 0; j < _validFileExtensions.length; j++) {
var sCurExtension = _validFileExtensions[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
// show row count in the CVS file. Error is here
alert("CVS file has " + lines + " Numbers");
blnValid = true;
break;
}
}
if (!blnValid) {
alert("Sorry the file, " + sFileName + " selected is invalid, file extensions allowed are: " + _validFileExtensions.join(" , "));
oInput.value = "";
return false;
}
}
}
return true;
}
code below works for me
document.getElementById('attachmentcsv').addEventListener('change', readSingleFile, false);
function readSingleFile(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function (e) {
var contents = e.target.result;
var lines = contents.split("\n").length;
// Remove header count
var mobileEntryCount= lines -1
if (mobileEntryCount <= 1) {
$('#csvcount').css('display', 'block');
$('#csvcount').text('CSV File Selected has ' + mobileEntryCount + ' Mobile Number Saved');
} else {
$('#csvcount').css('display', 'block');
$('#csvcount').text('CSV File Selected has ' + mobileEntryCount + ' Mobiles Number Saved');
}
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}

Progress event listeners to load thumbnails one at a time

I am working on around 40 Large images each of size 9000KB.
i have below code ,all images are loading at a time which makes my screen to freeze,I want that my control will wait until the first image is successfully progress then loads completely then move on to the next one.any idea is helpful..
//dropping around 40 images
dropbox.addEventListener("drop", dropUpload, false);
function dropUpload(event) {
noop(event);
var dropMethod = event.dataTransfer;
var classicMethod = event.target;
var dropedFiles = (dropMethod == undefined) ? classicMethod.files: dropMethod.files;
for ( var i = 0; i < dropedFiles.length; i++) {
addFilesToUpload(dropedFiles[i]);
}
}
function addFilesToUpload(file) {
var li = document.createElement("li"), div = document.createElement("div"), img, progressBarContainer = document
.createElement("div"), progressBar = document.createElement("div"), tBody;
li.appendChild(div);
progressBarContainer.className = "progress-bar-container";
progressBar.className = "progress-bar";
progressBar.setAttribute("id", "proBar_" + (indexN++));
progressBarContainer.appendChild(progressBar);
li.appendChild(progressBarContainer);
var reader = new FileReader();
reader.onerror = function(event) {
alert("couldn't read file " + event.target.error.code);
};
// Present file info and append it to the list of files
fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";
fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10)
+ " kb</div>";
fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";
div.innerHTML = fileInfo;
if (reader !== "undefined" && (/image/i).test(file.type)) {
img = document.createElement("img");
img.setAttribute("class", "thumb");
img.setAttribute("id", "img_" + (indexN++));
reader.onload = (function(img, li) {
return function(evt) {
img.src = evt.target.result;
img.file = file;
};
}(img, li));
reader.readAsDataURL(file);
}
reader.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
}
}, false);
reader.addEventListener("load", function() {
progressBarContainer.className += " uploaded";
progressBar.innerHTML = "";
}, false);
tBody = getTableBodyLayout(img, li);
document.getElementById("images_table").appendChild(tBody);
}
You can change addFilesToUpload() to take a callback when the file is done and change dropUpload() to initiate one at a time.
function dropUpload(event) {
noop(event);
var dropMethod = event.dataTransfer;
var classicMethod = event.target;
var dropedFiles = (dropMethod == undefined) ? classicMethod.files: dropMethod.files;
var filesDone = 0;
// local function to process the next file
function next() {
if (filesDone < dropedFiles.length) {
addFilesToUpload(dropedFiles[filesDone++], next);
}
}
// do the first one
next();
}
function addFilesToUpload(file, doneCallback) {
var li = document.createElement("li"), div = document.createElement("div"), img, progressBarContainer = document
.createElement("div"), progressBar = document.createElement("div"), tBody;
li.appendChild(div);
progressBarContainer.className = "progress-bar-container";
progressBar.className = "progress-bar";
progressBar.setAttribute("id", "proBar_" + (indexN++));
progressBarContainer.appendChild(progressBar);
li.appendChild(progressBarContainer);
var reader = new FileReader();
reader.onerror = function(event) {
alert("couldn't read file " + event.target.error.code);
};
// Present file info and append it to the list of files
fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";
fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10)
+ " kb</div>";
fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";
div.innerHTML = fileInfo;
if (reader !== "undefined" && (/image/i).test(file.type)) {
img = document.createElement("img");
img.setAttribute("class", "thumb");
img.setAttribute("id", "img_" + (indexN++));
reader.onload = (function(img, li) {
return function(evt) {
img.src = evt.target.result;
img.file = file;
// call the callback to tell the caller that this file is done now
doneCallback();
};
}(img, li));
reader.readAsDataURL(file);
}
reader.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
}
}, false);
reader.addEventListener("load", function() {
progressBarContainer.className += " uploaded";
progressBar.innerHTML = "";
}, false);
tBody = getTableBodyLayout(img, li);
document.getElementById("images_table").appendChild(tBody);
}
If you want to wait to proceed to the next image until each image has loaded, then you could change the reader.onload handler to this:
reader.onload = (function(img, li) {
return function(evt) {
img.onload = function() {
// call the callback to tell the caller that this file is done now
doneCallback();
};
img.src = evt.target.result;
img.file = file;
};
}(img, li));

File data from input element

In Firefox 3 it is possible to access the contents of a <input type="file"> element as in the following.
Assume a form with the following element:
<input type="file" id="myinput">
Now the data of the file selected can be accessed with:
// Get the file's data as a data: URL
document.getElementById('myinput').files[0].getAsDataURL()
Is there a cross-browser way to accomplish the same thing?
Firefox documentation for this feature:
https://developer.mozilla.org/en/nsIDOMFileList
https://developer.mozilla.org/en/nsIDOMFile
This is possible in at least Chrome, Firefox and Safari: Reading Files.
see associated jsfiddle
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
document.getElementById('byte_content').textContent = _.reduce(evt.target.result,
function(sum, byte) {
return sum + ' 0x' + String(byte).charCodeAt(0).toString(16);
}, '');
document.getElementById('byte_range').textContent =
['Read bytes: ', start + 1, ' - ', stop + 1,
' of ', file.size, ' byte file'].join('');
}
};
var blob;
if (file.slice) {
blob = file.slice(start, stop + 1);
}else if (file.webkitSlice) {
blob = file.webkitSlice(start, stop + 1);
} else if (file.mozSlice) {
blob = file.mozSlice(start, stop + 1);
}
console.log('reader: ', reader);
reader.readAsBinaryString(blob);
}
document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
}
}, false);

Categories