如何从输入文件控件中删除一个特定的选定文件?
我有一个输入文件控件,可以选择多个文件;但是,我想验证一个文件,如果它有一个错误的扩展名,那么我应该从文件控件本身删除该文件,是否可能?
我试过如下
<input type="file" name="fileToUpload" id="fileToUpload" multiple/>
<script> $("#fileToUpload")[0].files[0] </script>
下面是该对象的屏幕截图,但我无法对其进行修改
答案 0 :(得分:38)
正如其他人所指出的那样,FileList
是只读的。您可以通过将这些文件推送到单独的Array
来解决此问题。然后,您可以使用精选的文件列表执行任何操作。如果将目标上传到服务器,则可以使用FileReader
API。
以下是完全避免需要修改FileList
的方法。
步骤进行:
FileReader
API在本地读取文件事件处理程序和基本文件循环代码:
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 */
}
});
});
下面是一个更复杂的文件循环版本,它显示了如何使用FileReader
API将文件加载到浏览器中,并可选择将其作为Base64编码的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 */
}
});
关于使用FileReader
API的注意事项。 Base64编码文件将使其大小增加约30%。如果这是不可接受的,你需要尝试其他的东西。
答案 1 :(得分:4)
我认为我也应该在这里添加我的评论(我在这里回答:JavaScript delete File from FileList to be uploaded)
我找到了解决方法。这根本不需要AJAX请求,表单可以发送到服务器。基本上,您可以创建hidden
或text
输入,并将其value
属性设置为处理所选文件后创建的base64字符串。
<input type=hidden value=${base64string} />
您可能会考虑创建多个输入文件而不是输入text
或hidden
。这不起作用,因为我们无法为其赋值。
此方法将输入文件包含在发送到数据库的数据中,并忽略输入文件:
disabled
属性设置为输入文件; 如果要删除文件,只需获取元素的索引并从DOM中删除输入元素(文本或隐藏)。
<强>要求:强>
change
事件时将所有文件存储在数组中。 <强>优点:强>
答案 2 :(得分:0)
我知道这是一篇旧文章,但是我花了很长时间尝试解决此问题,所以我将发布解决方案。有一种方法可以用另一个fileList更新fileField元素的fileList,这可以通过DataTransfer完成:
let updateFileList = function (fileField, index) {
let fileBuffer = Array.from(fileField.files);
fileBuffer.splice(index, 1);
/** Code from: https://stackoverflow.com/a/47172409/8145428 */
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
for (let file of fileBuffer) { dT.items.add(file); }
fileField.files = dT.files;
}
上面的函数将fileField作为DOM对象,并删除要在fileField的fileList中删除的文件索引,并相应地更新传递的fileField。
希望这可以节省一些时间!
答案 3 :(得分:0)
基于@liamthorne4 的回答,这里是上传、列出和从列表中删除元素的有效解决方案,在 Firefox 和 Chrome 上进行了测试:
HTML:
<button onclick="uploadFile(event)">Upload files</button>
<div id="listfiles" class="view_list"></div>
<input class="hidden" type="file" id="input_file_id" onchange="fileList(event)" name="files[]" multiple>
JS:
function uploadFile(evt) {
evt.preventDefault();
$('#input_file_id').click();
}
function fileList(e) {
var files = $('#input_file_id').prop("files");
var names = $.map(files, function(val) { return val.name; });
for (n in names) {
$("#listfiles").append("<div id=preload_"+n+" title='"+names[n]+"'><p>"+names[n]+"</p><a onclick=deleteFile("+n+")>Delete</a></div>");
}
}
function deleteFile(index) {
filelistall = $('#input_file_id').prop("files");
var fileBuffer=[];
Array.prototype.push.apply( fileBuffer, filelistall );
fileBuffer.splice(index, 1);
const dT = new ClipboardEvent('').clipboardData || new DataTransfer();
for (let file of fileBuffer) { dT.items.add(file); }
filelistall = $('#input_file_id').prop("files",dT.files);
$("#preload_"+index).remove()
}
答案 4 :(得分:-9)
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);
}