8

I am using HTML5's wonderful 'multiple' file select feature.

<input type="file" id="fileInput" onChange="runTest()" multiple>

I would like to display the selected filenames below the input field and make it look pretty with CSS, however...

If I run a test JS function, that 'alerts' me of the input field's value, it only shows one file regardless of me selecting 10.

function runTest() {
var fileInput = document.getElementById('fileInput').value;
alert("You selected: "+fileInput);
}

I was doing this for when I had a 'single' file input field and worked okay but now it's 'multiple', it doesn't like it.

Any suggestions?

3 Answers 3

7

Well, it seems the value, or val(), returned by the element is the name of only the last file selected. To work around this, it might be wise to use the nature of the multiple-change events:

$('input:file[multiple]').change(
    function(){
        $('ul').append($('<li />').text($(this).val()));
    });

JS Fiddle demo.

And either output the names to a list (as in the example), or append the latest value to an array, or, possibly, use/create hidden inputs to store the filenames as you feel would best suit your application.

To access the file-names (as well as last modified date, file-size...) you can (tested in Chromium 12/Ubuntu 11.04) use the following:

$('input:file[multiple]').change(
    function(e){
        console.log(e.currentTarget.files);
    });

JS Fiddle demo.


Edited to make the above slightly more useful and, hopefully, demonstrative:

$('input:file[multiple]').change(
    function(e){
        console.log(e.currentTarget.files);
        var numFiles = e.currentTarget.files.length;
            for (i=0;i<numFiles;i++){
                fileSize = parseInt(e.currentTarget.files[i].fileSize, 10)/1024;
                filesize = Math.round(fileSize);
                $('<li />').text(e.currentTarget.files[i].fileName).appendTo($('#output'));
                $('<span />').addClass('filesize').text('(' + filesize + 'kb)').appendTo($('#output li:last'));
            }
    });

JS Fiddle demo.

The final code-block updated, due to changes in Webkit, Chrome 24 (though possibly from earlier), by nextgentech in comments, below:

$('input:file[multiple]').change(
    function(e){
        console.log(e.currentTarget.files);
        var numFiles = e.currentTarget.files.length;
            for (i=0;i<numFiles;i++){
                fileSize = parseInt(e.currentTarget.files[i].size, 10)/1024;
                filesize = Math.round(fileSize);
                $('<li />').text(e.currentTarget.files[i].name).appendTo($('#output'));
                $('<span />').addClass('filesize').text('(' + filesize + 'kb)').appendTo($('#output li:last'));
            }
    });

JS Fiddle demo.

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

5 Comments

Thanks David, I used this but still didn't manage to get it to produce all files, weird. I have actually just read an article on HTML5 (html5rocks.com/en/tutorials/file/dndfiles) which if applied, would be much better for me. Without doubt thou', your code actually helped me with another issue I was having elsewhere, so thanks...
Really? It worked consistently in Chromium, albeit that's no guarantee of other browsers' behaviour. Anyway, I'm glad to have been of (some) help, if I get a chance I'll try and look further into this.
Updated Fiddle to account for Chrome/Chromium changes in file attributes (fileSize is now size, fileName is now name) as of at least v24 (possibly earlier).
I can see a potential problem with the above, are the listed file still form submission elements when you re-select new files with the fileuploader?
it would be nice if you could also put (X) sign to remove some of the selected files.
0

Set a break point on the alert call and take a look at the contents of the variable fileInput, see if there is another property that contains all of the file names.

Comments

0

Excellent code but object needs to be empty for each change:

$('input:file[multiple]').change(
function(e){
    $('#output').empty();
    console.log(e.currentTarget.files);
    var numFiles = e.currentTarget.files.length;
        for (i=0;i<numFiles;i++){
            fileSize = parseInt(e.currentTarget.files[i].fileSize, 10)/1024;
            filesize = Math.round(fileSize);
            $('<li />').text(e.currentTarget.files[i].fileName).appendTo($('#output'));
            $('<span />').addClass('filesize').text('(' + filesize + 'kb)').appendTo($('#output li:last'));
        }
});

Thank you David...

1 Comment

how to remove a selected file?

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.