jQuery loop on multiple input.files - javascript

I need to loop this on a multiple file input:
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_0')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
I tried this, but it does not work:
var fileCount = 0;
$("input[name='files[]']").each(function() {
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_'+fileCount)
.attr('src', e.target.result)
.css("display","block");
};
reader.readAsDataURL(input.files[fileCount]);
fileCount++;
});
alert() on fileCount output is a one time 0 on multiple file selection. no further alerts. If I take numbers instead of the fileCount var in code, it works at position. r.g. input.files[2] ...
Any idea?

When you do this: $("input[name='files[]']").each(function() { you are actually getting any elements that match the selector. In this case, you get your single multi file input (which is why you only see 1 alert. What you want to do is iterate over the files.
This page has code to do pretty much exactly what you want. I recommend you check it out:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
To apply it to your situation, you would do something like this:
var files = $('#files')[0].files; //where files would be the id of your multi file input
//or use document.getElementById('files').files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_'+fileCount)
.attr('src', e.target.result)
.css("display","block");
};
reader.readAsDataURL(f);
}

Related

FileReader reads only one file when multiple dropped

I am coding and form with and struggle tor ead each file. What i am getting is onlz one file being read.
Code below does log each iteration (console.log(i)), but does read and log only the last file, no matter what if read as dataURL or as Text
fileInput.on('change',function(){
var files= fileInput.prop('files');
console.log(files);
for(var i = 0; i < files.length; i++){
var reader = new FileReader();
console.log(i);
reader.onload = function(){
console.log(reader.result);
}
reader.readAsDataURL(files[i]);
}
});
I need each of multiple file to be logged in console. Thanks in advace
use let instead of var to properly scope the variable to the loop:
for (let i = 0; i < files.length; i++) { // Use let here
var reader = new FileReader();
console.log(i);
reader.onload = function() {
console.log(reader.result);
}
reader.readAsDataURL(files[i]);
}
You should use let instead of var for reader variable, since var is function scoped.
Didn't you forget the multiple attribute on the input element?

Javascript: Remove \n\t character from text after file upload

I'm trying to upload a file but in the file include a new line and white spaces in it.
I want to replace these new lines and white space character from my file before processing
I trying following but not working
onFileChange(event){
let files = event.target.files;
let f = files[0];
let reader = new FileReader();
reader.onload = (function (theFile) {
return function (e) {
console.log(e.target.result.replace(/(?:\r\n|\r|\n)/g, ''));
}
})(f);
}
Above .replace function working on the normal string but not on uploaded file string.
Looks like your missing a line that actually reads the file. Add reader.readAsDataURL(f) at the end of the function. Also you can get rid of the closure.
onFileChange(event){
let files = event.target.files;
let f = files[0];
let reader = new FileReader();
reader.onload = function (e) {
console.log(e.target.result.replace(/(?:\r\n|\r|\n)/g, ''));
};
reader.readAsText(f)
}

Getting the content of each file in multiple file input using jquery

I need to fetch the content of each file in multiple file input using jquery and based on the file content i need to do some modifications in my page. Here is the code I have written to do the same. Here what is happening is If I select 3 files I am getting the content of 3rd file alone. If I use the index number instead of looping I am able to get the contents But If I use looping I am getting the last files content alone. Could someone explain me whats wrong with it ?
<input type="file" name="xsd" id="xsd" multiple="multiple">
$('#xsd').change(function(){
input = document.getElementById('xsd');
for(var i = 0; i < input.files.length ; i++)
{
file = input.files[i];
fr = new FileReader();
fr.readAsText(file);
fr.onload = function(e) {
var filecontent = fr.result;
// My logic here
}
}
});
Your problem is that the onload function is getting it's "fr" from a closure.
You can create a separate closure for each of the onload-callbacks by using an immediately-invoked anonymous function like this:
$('#file').change(function(){
input = document.getElementById('file');
for(var i = 0; i < input.files.length ; i++)
{
(function(i) {
var file = input.files[i];
var fr = new FileReader();
fr.onload = function(e) {
var filecontent = fr.result;
// My logic here
}
fr.readAsText(file);
})(i);
}
});

How to get the filename from the Javascript FileReader?

I'm using the Javascript FileReader to load an image in the browser:
e = e.originalEvent;
e.dataTransfer.dropEffect = 'copy';
this.documentFile = e.dataTransfer.files[0];
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
}
};
reader.readAsDataURL(this.documentFile);
This works fine. I now want to get the original filename of the image, but I've got no clue how and looking around the internet I can't find anything either?
Does anybody know how I can get the filename through the FileReader? All tips are welcome!
This is prob not the best solution, BUT it worked for me.
var reader = new FileReader();
reader.fileName = file.name // file came from a input file element. file = el.files[0];
reader.onload = function(readerEvt) {
console.log(readerEvt.target.fileName);
};
Not the best answer, but a working one.
I just faced the same issue, here's how I fixed it:
Using FileReader
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // event is from the HTML input
console.log(event.target.files[0].name);
The selected answer will work, but I personally prefer to prevent assigning unknown properties to existing objects.
What I do is using the built-in Map object to store connections between FileReader and its File. It works great, because Map allows the key to be anything, even an object.
Consider this example with drag&drop on the window, where multiple files can be dropped at the same time:
// We will store our FileReader to File connections here:
const files = new Map();
window.addEventListener('drop', e => {
e.preventDefault();
for (const file of e.dataTransfer.files) {
const reader = new FileReader();
files.set(reader, file);
reader.addEventListener('load', e => {
// Getting the File from our Map by the FileReader reference:
const file = files.get(e.target);
console.log(`The contents of ${file.name}:`);
console.log(e.target.result);
// We no longer need our File reference:
files.delete(e.target);
});
reader.readAsText(file);
}
});
window.addEventListener('dragover', e => {
e.preventDefault();
});
And voilĂ , we made it without altering our FileReader objects!
I got the filename and filesize through the FileReader this way
First of all, the reader is a javascript FILE API specification that is so useful to read files from disc.
In your example the file is readed by readAsDataURL.
reader.readAsDataURL(this.documentFile);
var name = this.documentFile.name;
var size = this.documentFile.size;
I tried on my site where use this.files[0] instead and worked fine to catch the name and the size with jQuery into an input element.
reader.readAsDataURL(this.files[0]);
$("#nombre").val(this.files[0].name);
$("#tamano").val(this.files[0].size);
I tried the solution of #Robo Robok but was unable to get this to work in my Angular Application. With this as inspiration I came up with the following and wonder if this is a correct approach. Me, I'm a bit skeptic because each upload gets there own FileReader
export class ImageFileUpload {
imageData: any;
imageName!: string;
fileReader!: FileReader;
}
selectedFiles!: FileList | null;
previews: Array<ImageFileUpload> = [];
uploadRenewals(event: any) { // event of html
const target = event.target as HTMLInputElement;
this.selectedFiles = target.files;
if (this.selectedFiles) {
const numberOfFiles = this.selectedFiles.length;
for (let i = 0; i < numberOfFiles; i++) {
const currentSelectedFile = this.selectedFiles[i];
const newImageFile = new ImageFileUpload();
newImageFile.imageName = currentSelectedFile.name;
newImageFile.fileReader = new FileReader();
newImageFile.fileReader.onload = (e: any) => {
newImageFile.imageData = e.target.result;
};
newImageFile.fileReader.readAsDataURL(currentSelectedFile);
this.previews.push(newImageFile);
}
}
}
}
HTML Page
<input #fileInput (change)="uploadRenewals($event)" multiple type="file">
<div class="slider">
<div *ngFor="let preview of previews; let idx = index">
<img [src]="preview.imageData" [alt]="preview.imageName">
</div>
</div>
One other way is to modify the FileReader() object instance with your own desired property. Adding a key like reader.myOwnFileName gets you access to that in the onload callback.
const reader = new FileReader();
reader.onload = function() {
console.log("Loaded file '" + reader.myOwnFileName + "' contents: ");
console.log(reader.result); // output file contents of chosen file.
};
reader.readAsText(this.files[0]); // use readAsText(), readAsDataURL() or other method.
// make your own key on the object instance:
reader.myOwnFileName = this.files[0].name;
If you want the filename to a variable:
var filename;
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
filename = reader.result;
}
};
reader.readAsDataURL(this.documentFile);
If you want it to run in a function:
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
myfunctionafter(reader.result);
}
};
reader.readAsDataURL(this.documentFile);
If you want to get the info out inside another function:
var reader = new FileReader();
var filename = reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
return reader.result;
}
};
reader.readAsDataURL(this.documentFile);
There might be a problem when your reader.onloadend might finish before the function you are running it from. Then you should do two functions and trigger the myfunctionafter(reader.result); from inside
Or you could simply get the src after
var filename = $('#theImage').attr('src');

FileReader: Object is not a function

My code -
$selectFile = $('<input type="file">');
$selectFile.click(function () {
this.value = null;
});
$selectFile.change(function(event){
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onloadend(function(e){
alert(e.result);
});
});
I am getting object is not a function error at reader.onloadend line.
Can anyone help please.
You need to change your onloadend method to onload. Also you need to set it to a function, not a parameter. To get the url/data you want use e.target.result not just e.result. Finally, I'd place the readAsDataURL after setting the method to make sure that it fires.
$selectFile.change(function(event){
var reader = new FileReader();
reader.onload = function(e){
alert(e.target.result);
};
reader.readAsDataURL(event.target.files[0]);
});
DEMO

Categories