Reputation: 510
I want to list selected file from file input.
<div class="fileUpload myButton">
<span>Upload</span>
<input type="file" name="imageURL[]" id="imageURL" multiple="" class="file" />
</div>
<div id="file-list">
</div>
I have this code
(function () {
var filesUpload = document.getElementById("imageURL"),z
fileList = document.getElementById("file-list");
function uploadFile (file) {
var li = document.createElement("li"),
div = document.createElement("div"),
reader,
xhr,
fileInfo;
li.appendChild(div);
// Present file info and append it to the list of files
fileInfo = "<div class=\"neutral\">File: <strong>" + file.name + "</strong> with the size <strong>" + parseInt(file.size / 1024, 10) + "</strong> kb is in queue.</div>";
div.innerHTML = fileInfo;
fileList.appendChild(div);
}
function traverseFiles (files) {
if (typeof files !== "undefined") {
for (var i=0, l=files.length; i<l; i++) {
uploadFile(files[i]);
}
}
else {
fileList.innerHTML = "<div class=\"neutral\">Your browser does not support Multiple File Upload, but you can still upload your file. We recommend you to upload to a more modern browser, like <a href=\"http://google.com/chrome\" target=\"_blank\">Google Chrome</a> for example.<div>";
}
}
filesUpload.addEventListener("change", function () {
traverseFiles(this.files);
}, false);
})();
But the problem is when the user selects another files it is added to the list but the old files is not uploaded when the form is submitted.
Simplified: when the user selects file1.pdf and file2.pdf The list shows file1.pdf and file2.pdf When he selects again another files file3.pdf and file4.pdf the list shows file1.pdf , file2.pdf, file3.pdf and file4.pdf But when he submit the form only file3.pdf and file4.pdf is uploaded
My question is how to remove the files which will not be uploaded from the list. OR a way to upload all the files in the list. Thanks in advance.
Upvotes: 9
Views: 11236
Reputation: 37328
Your Problem is that you manipulate the value of input multiple times. The second time someone selects a file using the html file input, the originally selected files are "overwritten" from the inputs value attribute.
You could hook into your forms submit and add the files you already stored in your html. Another way to do it would be to work with several file input elements.
So every time someone selects files and you add them to your html, hide the old file input and add a new one like this ...
adjust your html code like this:
<div class="fileUpload myButton">
<span>Upload</span>
<input type="file" class="imageUrlInput" name="imageURL[0]" id="imageURL" multiple="" class="file" />
</div>
<div id="file-list">
</div>
Adjust your Javascript like this:
function uploadFile (file) {
var li = document.createElement("li"),
div = document.createElement("div"),
reader,
xhr,
fileInfo;
li.appendChild(div);
// now here we receive the HTML input element for the files.
var currentInput = $('#imageURL');
var imageUrlInputsCount = $('.imageUrlInput').length;
// now we change the 'id' attribute of said element because id's should be unique right?
currentInput.attr('id','imageUrl_'+imageUrlInputsCount);
// now, we append a new input element with an incremented array key defined by the length of already existing input elements
currentInput.append('<input type="file" name="imageURL['+imageUrlInputsCount+']" id="imageURL" multiple="" class="file" />');
// and finally we hide the old element
currentInput.hide();
// Present file info and append it to the list of files
fileInfo = "<div class=\"neutral\">File: <strong>" + file.name + "</strong> with the size <strong>" + parseInt(file.size / 1024, 10) + "</strong> kb is in queue.</div>";
div.innerHTML = fileInfo;
fileList.appendChild(div);
}
Now make sure that in your retrieving server code (php/jsp/asp,node.js or whatever you are using) you change checking for imageURL, you iterate over imageURL since now you have several sets of imageURLs. i.e. your imageURL parameter could look like this:
imageURL = array (
0 => array(
'foo1.pdf',
'foo2.pdf',
'foo3.pdf',
),
1 => array(
'foo4.pdf',
'foo5.pdf',
'foo6.pdf',
)
3 => array(
'foo7.pdf',
'foo8.pdf',
'foo9.pdf',
)
)
Upvotes: 0
Reputation: 1525
What is happening is that the input is emptied when selecting more files, hence not uploading the previously displayed files.
SOLUTION 1: To combat this you could create a new input in the change
event handler, although this could get quite messy.
You would have to get all files from all the inputs on upload. You have not shown your actual upload code, so I cannot give an example in context:
filesUpload.on("change", function () {
traverseFiles(this.files); //Add initial files to list
create_new_input();
}
function create_new_input() {
var new_input = $('<input type="file" />'); //create file selector
new_input.on("change", function() {traverseFiles($(this).get(0).files);}); //
$('body').append(new_input); //Add this input to your page
}, false);
You will have to add all files that you receive in the traverseFiles
to the xhr. This example uses jQuery, and I would recommend that you use it all the time!
SOLUTION 2: Other wise you can empty the file list box on input changed:
filesUpload.addEventListener("change", function () {
document.getElementById('file-list').innerHTML = "";
traverseFiles(this.files);
}, false);
Good luck!
Upvotes: 4