问题
How to remove one specific selected file from input file control?
I have an input file control with the option to select multiple files; however, I want to validate a file and if it has an wrong extension then I should remove that file from the file control itself, is it possible?
I tried as below
<input type=\"file\" name=\"fileToUpload\" id=\"fileToUpload\" multiple/>
<script> $(\"#fileToUpload\")[0].files[0] </script>
Below is the screenshot of the object but I am not able to modify it
回答1:
As other people pointed out, FileList is read only. You can get around this by pushing those files into a separate Array
though. You can then do whatever you want with that curated list of files. If uploading them to a server is the goal, you can use the FileReader API.
Below is a round about way of completely avoiding needing to modify the FileList
.
Steps:
- Add normal file input change event listener
- Loop through each file from change event, filter for desired validation
- Push valid files into separate array
- Use
FileReader
API to read files locally - Submit valid, processed files to server
Event handler and basic file loop code:
var validatedFiles = [];
$("#fileToUpload").on("change", function (event) {
var files = event.originalEvent.target.files;
files.forEach(function (file) {
if (file.name.matches(/something.txt/)) {
validatedFiles.push(file); // Simplest case
} else {
/* do something else */
}
});
});
Below is a more complicated version of the file loop that shows how you can use the FileReader
API to load the file into the browser and optionally submit it to a server as a Base64 encoded blob.
files.forEach(function (file) {
if (file.name.matches(/something.txt/)) { // You could also do more complicated validation after processing the file client side
var reader = new FileReader();
// Setup listener
reader.onload = (function (processedFile) {
return function (e) {
var fileData = { name : processedFile.name, fileData : e.target.result };
// Submit individual file to server
$.post("/your/url/here", fileData);
// or add to list to submit as group later
validatedFiles.push(fileData);
};
})(file);
// Process file
reader.readAsDataURL(file);
} else {
/* still do something else */
}
});
A note of caution about using FileReader
API. Base64 encoding a file will increase its size by around 30%. If that isn't acceptable you will need to try something else.
回答2:
I thought that I should add my comment here as well here (I've answered here: JavaScript delete File from FileList to be uploaded)
I found a workaround. This will not require AJAX for the request at all and the form can be sent to the server. Basically you could create an hidden
or text
input and set it's value
attribute to the base64 string created after processing the file selected.
<input type=hidden value=${base64string} />
You will probably consider the idea to create multiple input file instead of input text
or hidden
. This will not work as we can't assign a value to it.
This method will include the input file in the data sent to the database and to ignore the input file you could:
- in the back-end don't consider the field;
- you can set the
disabled
attribute to the input file before serialising the form; - remove the DOM element before sending data.
When you want to delete a file just get the index of the element and remove the input element (text or hidden) from the DOM.
Requirements:
- You need to write the logic to convert files in base64 and store all files inside an array whenever the input file trigger the
change
event.
Pros:
- This will basically give you a lot of control and you can filter, comparing files, check for file size, MIME type, and so on..
回答3:
html
<input id="fileInput" name="fileInput" type="file" />
<input onclick="clearFileInput()" type="button" value="Clear" />
javascript
function clearFileInput(){
var oldInput = document.getElementById("fileInput");
var newInput = document.createElement("input");
newInput.type = "file";
newInput.id = oldInput.id;
newInput.name = oldInput.name;
newInput.className = oldInput.className;
newInput.style.cssText = oldInput.style.cssText;
// copy any other relevant attributes
oldInput.parentNode.replaceChild(newInput, oldInput);
}
来源:https://stackoverflow.com/questions/19060378/how-to-remove-one-specific-selected-file-from-input-file-control