2

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();
    });
});

enter image description here

2
  • Have you tried adding a break point in the debugger and seeing what properties are in the object Commented Feb 10, 2016 at 16:21
  • Use "this" reference, "f" is not defined once that fires, it's an event that fires later. Or pass something else to that function. Whatever you end up needing. Commented Feb 10, 2016 at 16:39

2 Answers 2

5

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>

Sign up to request clarification or add additional context in comments.

1 Comment

Amazing. I guess I was close but far. I still have a lot to learn about this but this is a great help. Thank you very much!
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.