Reputation: 2016
I am using a multiple file upload field <input name="filesToUpload" id="filesToUpload" type="file" multiple />
in my app.
What I want to accomplish is to list the files the users chose and than allow them to delete any of them in the list.
At the end, when the form is submitted, I send the whole data via AJAX, as binary, using the FormData
object.
It all works great, except for the delete part.
I know that the FileList
attribute is read-only, so what I did was to distribute the files as values of hidden input fields, appended to each of the li
where I list the file names. So if the user removes a li
item, the hidden input field is gone with it, and at the end, I collect all remaining by appending them to the FormData
object.
Problem is, every attempt I made to assign the files as values to the hidden inputs gave me weird results.
My code is something like this:
listFiles : function () {
var file, files, filesList, filesLength, read;
files = this.files;
filesList = $('.files');
filesLength = files.length;
// Clear the list
filesList.html('');
for ( var i = 0; i < filesLength; i++ ) {
file = files[i];
// This is to read the content of the file
read=new FileReader();
read.readAsBinaryString( file );
// When reading is finished
read.onloadend = function() {
filesList.append(
'<li>' +
'<span class="fileName">' + file.name + '</span>' +
'<a href="#" class="deleteAttachment">x</a>' +
'<input type="hidden" name="file[]" value="' + read.result +'"/>' +
'</li>');
}
}
}
I just get the data from the last file, also, the DOM is broken since the data gets printed all over the place.
Demo here => http://jsfiddle.net/zKyXC/
Upvotes: 2
Views: 8461
Reputation: 2016
I have tried various ways to implement the method described above ( assign each separate file to the value of an input[type="hidden"] field in order to allow file delete functionality ) but non of them were successful. At this moment, I do not know if this is this possible to be done at all.
However, I did manege to solve the problem with an alternative solution. Here it is in case someone else finds it useful.
Instead of using input[type="hidden"]
I used a global array where I stored the files upon receiving them. Then I remove items from that array the standard way you would remove objects from an array. At the end I append each item to the formData
object and send it to the server.
I create and fill the global array like this:
globals.files =[].slice.call( this.files );
i remove from it like this:
$.each( files, function( index, val ) {
if ( this.name === fileText ) {
globals.files.splice( index, 1 );
}
});
Note : fileText
is where I store the name of the item to be deleted.
And at the end I append it to formData
:
var formData = new FormData();
$.each( files, function( ind, val ) {
formData.append( 'files[]', this );
});
And send this as the data
property of a standard jQuery ajax call.
Upvotes: 3
Reputation: 123
if I am not wrong, only file with quotation mark "
goes wrong, if you do not escape it, value
will be cut off at the first occurence of "
and the rest part will be shown as html, so what you need is
read.result.replace(/"/g, '"');
Upvotes: 0