I was doing some tests on html 5 file upload with jquery and ran into something strange (at least to me). I was trying to get the list of files that had been selected in the file control :
<html><head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
</head>
<body>
<input type="file" multiple="multiple" id="inputFile" name="inputFile">
<button onclick="buttonClicked()" type="button">upload</button>
<script type="text/javascript">//<![CDATA[
function buttonClicked() {
console.log($("#inputFile").val()); // depending on the browser, gives either the file name, either the full path, but only for the first file
console.log($("#inputFile").files); // gives undefined
console.log($("#inputFile").attr("files")); // gives undefined
console.log($("#inputFile").get()); // according to the jquery documentation, give the dom element...
console.log($("#inputFile").get().files); // ...but strangely, files is undefined
console.log($("#inputFile")[0].files); // on the other hand, this gives me the list of files
}
//]]>;
</script>
</body></html>
So first I was expecting that $(“#inputFile”).val() would give me that least, too bad that’s not the case. So I tried variations on input.files, without really expecting it to work because it didn’t seem to fit a jquery object (but hey, you never know). So I tried to get the underlying dom element from jquery to access the files item. And that’s where it get strange because it’s undefined as well. On the other hand$(“#inputFile”)[0].files gives the expected result.
[Edit]
And then, as often, while typing that question, I found the solution myself. I’ll leave it here anyway, so anyone who struggle on that has a chance to solve it also. It basically goes on RRTFM, like Really RTFM :
All of the matched DOM nodes are returned by this call, contained in a
standard array
That means, even if there is only one element. So the call:
console.log($("#inputFile").get());
Was returning an array with one element, and of course arrays don’t have a files property. It should have been:
console.log($("#inputFile").get(0));
console.log($("#inputFile").get()[0]); // or this one, but that's a bit silly
The problem is, besides the fact that
.get()returns an array (.get(0)gives you the first element) that you use.attr()instead of.prop().If you want
elem.files, the jQuery way to access it is$(elem).prop('files').When using
.attr()that corresponds to a call to.getAttribute()which is usually not what you want for properties such asfilesorchecked. jQuery sometimes automatically switches to properties, e.g. forchecked, but of course it cannot cover every single property.So, what you finally want to use, is
$('#inputFile').prop('files')or$("#inputFile").get(0).files. However, the latter will throw an error if your selector did not match anything.