javascript FileReader get name? - javascript

I'm working on a simple script for my site to upload images. I have a multiple file input <input type = 'file' name = 'files[]' id = 'hiddenFile' multiple> that is being triggered by a div click. When I queue the files, I want to be able to delete one. I know I can loop through the $('#hiddenFile').val() and splice to get the name out but I'm having an issue with figuring out the file name. When I assign the file to a new img container, how do I get the name? I've tried console.log(f.name) and a few variations but it returns an undefined error. Here are my scripts. I think I'm pretty close but this is something I'm learning as I go. Thanks!
function readURL(input) {
var files = $('#hiddenFile')[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) {
console.log(f.name); //how can I get the
//file name here to add it to the image as an attribute?
$("<img src = '"+e.target.result+"' class = 'addedImg'>").appendTo("#imgBox");
};
reader.readAsDataURL(f);
}
}
$(document).ready(function(){
$(document).on('click', '#addBtn', function(e){
e.preventDefault();
$('#hiddenFile').click();
});
});

Try using change event , defining f within an IIFE , setting title attribute value to f.name
$(document).ready(function() {
$(document).on('click', '#addBtn', function(e) {
e.preventDefault();
$('#hiddenFile').click();
});
$("#hiddenFile").change(function(event) {
var files = this.files;
var i = 0,
len = files.length;
(function readFile(n) {
var reader = new FileReader();
var f = files[n];
reader.onload = function(e) {
console.log(f.name);
$("<img src=" + e.target.result + " class=addedImg title=" + f.name + ">")
.appendTo("#imgBox");
// if `n` is less than `len` ,
// call `readFile` with incremented `n` as parameter
if (n < len -1) readFile(++n)
};
reader.readAsDataURL(f); // `f` : current `File` object
}(i)); // `i` : `n` within immediately invoked function expression
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="addBtn">click</div>
<input type="file" style="display:none" id="hiddenFile" multiple />
<div id="imgBox"></div>

The FileReader object itself does not have access to the file name. You get the file name while you're iterating over the files list as you are doing in your for loop.
var reader = new FileReader();
reader.onload = function (e) {
//update image src or something
};
for (var i = 0, f; f = files[i]; i++) {
reader.readAsDataURL(f); //updates image src or something
//additional method to do something with file name goes here
}
And if you really want to have one method that does those two things in the for loop, then you can wrap it all up in a closure like #ebidel does in his answer here - Get filename after filereader asynchronously loaded a file#answer-12547471.

Related

Uncaught TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'

I wrote a function to read HTML from a file and set the innerHTML of a certain div to equal the HTML inside the file, as a kind of save/load system. This used to work fine, however after a browser update I am getting the error seen in the title.
HTML:
<div id="target">
<button onclick="saveDiv()">Save</button>
<button onclick="loadDiv()">Load</button>
<input id="file" type="file" style="hidden">
<input>
</div>
JS:
const div = document.getElementById('target')
function saveDiv() {
var divContent = div.innerHTML.toString();
var ran = (Math.random() + 1).toString(36).substr(2, 8)
var fileName = `${ran}.txt`;
download(fileName, divContent);
}
function download(name, content) {
var e = document.createElement('a');
e.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content));
e.setAttribute('download', name);
e.style.display = 'none';
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
function loadActors() {
document.getElementById('file').click();
var file = document.getElementById('file').files[0];
var r = new FileReader();
r.onload = (function(reader) {
return function() {
var contents = reader.result;
div.innerHTML = contents;
}
})(r);
r.readAsText(file);
}
I think what may be happening is that the FileReader is trying to read the file before the user has selected it, but I'm not exactly sure. Anyone know what may be happening here?
Edit: Seems that if I select the file after the error then click the load button again it runs fine. How would I make it only run after the user has selected the file?

Get file names while displaying and before uploading on server using html and jquery

I am selecting multiple images using html tag 'input file multiple html' as below.
#Html.TextBoxFor(model => model.files, "",
new {#id = "filesToUploadID", #type = "file", #multiple = "multiple" })
<div class="col-md-10" id="selectedFiles"></div>
Then in javascript, I attached 'onchange' event listner to the above tag. When I select multiple images, I get all the attached images to the tag using jquery. But I need image file names as well. While getting image file names, I get only one file name poplulated in my html along with image using jquery.
jquery/ javascript is below
document.addEventListener("DOMContentLoaded", init, false);
function init() {
document.querySelector('#filesToUploadID').addEventListener('change', handleFileSelect, false);
selDiv = document.querySelector("#selectedFiles");
}
function handleFileSelect(e) {
debugger;
NameArray = [];
if (!e.target.files) return;
selDiv.innerHTML = "";
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
var f = files[i];
NameArray.push(f.name);
var reader = new FileReader();
reader.onload = function (e) {
var html = "<img src='" + e.target.result + "' />";// + "<div>" + + "</div>";//+ "<br clear=\"left\"/>";
$(selDiv).append($(html));
//selDiv.innerHTML += html;
}
reader.readAsDataURL(f);
}
}
I tool help from this link and implemented both ways but could not succeed.
All images names are relevant to the images. What I am getting is like this
It's source code is
I have to assign id's based on image names that's why it is important to get relevant image names. Any lead to the topic will be high appreciated.
Thank you.
var f = files[i];
var fileName = e.target.f.name

multiplie image upload url and file name is not working

my problem is when I select the multiple images it displaying correct, and I am storing this in one array, from that array I need to get the image name. right now it's working but in setOfImages array all image name is same. i need to take the image URL also when i put that setOfImages array in map function that URL are get repeating this are two problems I am facing if not clear put console.log(setOfImages) and console.log(imageUrl),
imagetrigger(e){
var setOfImages =[], imageUrl=[];
for (var i = 0; i < e.target.files.length; i++){
var file = e.target.files[i];
if(!file.type.match('image'))
continue;
var reader = new FileReader();
reader.onload = function(e){
setOfImages.push({
fileName:file.name,
image:e.target.result.split(',')[1]
});
$('.image').remove();
for(var j = 0; j<setOfImages.length; j++) {
$('.placeholder').prepend('<div class="image"><img src="data:image/jpeg;base64,'+ setOfImages[j].image +'" /></div>');
}
setOfImages.map(function(){
imageUrl.push(el.fileName);
})
console.log(imageUrl)
}
reader.readAsDataURL(file);
}
}
Just add parameter el to your map.
setOfImages.map(function(){
imageUrl.push(el.fileName);
})
Change like this.
setOfImages.map(function(el){
imageUrl.push(el.fileName);
})

How To Remove selected file in Javascript/Jquery

I have a form that allows users to upload multiple images. Users has an option to remove Images one by one if they don't want to upload that particular image.
Now, How to remove the value from the file type of the one that they removed (e.g. didn't want to upload)?
I have tried using ($('input').val("")) but it works only for single image not for multiple images. If I used this for multiple image then all uploaded images value become empty instead of that particular image that user want to remove.. Below is my Code:-
HTML
<input type="file" id="files2" name="cert_img" multiple>
<output id="list2"></output>
Javascript
var count2=0;
function handleFileSelect2(evt) {
var $fileUpload = $("input#files2[type='file']");
count2=count2+parseInt($fileUpload.get(0).files.length);
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function (theFile) {
return function (e) {
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" id="image_X" src="', e.target.result, '" title="', escape(theFile.name), '"/><span class="remove_img_preview"></span>'].join('');
document.getElementById('list2').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
$('#files2').change(function(evt){
handleFileSelect2(evt);
});
$('#list2').on('click', '.remove_img_preview',function () {
$(this).parent('span').remove();
//$('input').val("");
});
Thanks in advance..
According to this question you can't change FileList content because it is readonly.
But if you want to remove a file of FileList, you can create a new object and set to it files that you want to upload. Then use created object to upload files. Run my example and select multiple files. Then click on any file that you want to delete. After delete files, see browser console.
var files;
$("#files").on("change", function(e){
files = $("#files")[0].files;
$.each(files, function(index, value){
$("ol").append("<li data-index='"+index+"'>"+ value.name +"</li>");
});
});
$(document).on("click", "li", function(){
var newFiles = {};
var index = $(this).index();
$("li:nth-child(" + (index + 1) + ")").remove();
$("li").each(function(index, element){
var dataIndex = $(element).attr("data-index");
newFiles[index] = files[dataIndex];
});
console.log(newFiles);
});
li:hover {
color: red;
cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="files" multiple>
<ol></ol>

Handle multiple uploaded html file

My task is to upload multiple html files, and copy their content in my html.
And here is the html part:
<input type="file" id="fi" onChange="xx();" multiple>UPLOAD</span>
JavaScript part:
function xx (){
var fi = document.getElementById('fi').files[0];
reader.onload = function (e){
var reader = new FileReader();
var inn = document.getElementById("main_text");
inn.innerHTML="";
var inner ="";
inner += this.result;
inn.innerHTML ="<div class='paper'>"+inner+"</div>";
<!--codes-->
}
reader.readAsText(fi);
}
I've already deleted useless parts in my code. Originally it can only handle single file. Then I added multiple attribute in html input code.
It seems that in this line, the last files[0]decides which file to read.
var fi = document.getElementById('fi').files[0];
How can I modify it to archive the goal of handling multiple html pages in uploading functions?
Thanks alot!
You have to iterate over the files :
function xx (){
var fi = document.getElementById('fi').files;
var inn = document.getElementById("main_text");
var div = document.createElement('div');
div.className = 'paper';
inn.appendChild(div);
for (var i=0; i<fi.length; i++) {
var reader = new FileReader();
reader.onload = function (e){
var txt = document.createTextNode(this.result);
div.appendChild(txt);
}
reader.readAsText(fi[i]);
}
}

Categories