ファイルリストからファイルを削除するにはどうすればよいですか
-
01-10-2019 - |
質問
私はHTML5を使用してドラッグアンドドロップツーアプロードのWebアプリケーションを構築しています。ファイルをDIVにドロップし、もちろんDatAtransferオブジェクトを取得しています。 フィルリスト.
今、私はいくつかのファイルを削除したいのですが、どのように、またはそれが可能かどうかはわかりません。
できれば、フィルリストからそれらを削除するだけです。私は彼らには役に立たない。しかし、それが不可能な場合は、代わりにフィルリストと対話するコードでチェックインコードを書き込む必要がありますか?それは面倒です。
解決
選択したファイルのいくつかのみを削除する場合:できません。 APIワーキングドラフトをファイルします あなたはメモを含むにリンクされています:
HTMLInputElement
インターフェイス[HTML5]があります 読んでくださいFileList
属性、 […
私の強調
HTML 5ワーキングドラフトを少し読んで、私は出会いました 一般 input
要素API. 。削除できるようです 全体 設定によるファイルリスト value
のプロパティ input
次のような空の文字列にオブジェクトします
document.getElementById('multifile').value = "";
ところで、記事 Webアプリケーションのファイルを使用します また、興味深いかもしれません。
他のヒント
この質問はすでにマークされていますが、他の人がフィルリストの使用に役立つ可能性のある情報を共有したいと思います。
フィルリストを配列として扱うのは便利ですが、並べ替え、シフト、ポップ、スライスなどの方法は機能しません。他の人が示唆しているように、フィルリストを配列にコピーすることができます。ただし、ループを使用するのではなく、この変換を処理する簡単な1行ソリューションがあります。
// fileDialog.files is a FileList
var fileBuffer=[];
// append the file list to an array
Array.prototype.push.apply( fileBuffer, fileDialog.files ); // <-- here
// And now you may manipulated the result as required
// shift an item off the array
var file = fileBuffer.shift(0,1); // <-- works as expected
console.info( file.name + ", " + file.size + ", " + file.type );
// sort files by size
fileBuffer.sort(function(a,b) {
return a.size > b.size ? 1 : a.size < b.size ? -1 : 0;
});
FF、Chrome、およびIE10+でOKをテストしました
Evergreenブラウザー(Chrome、Firefox、Edge、Safari 9+でも動作します)をターゲットにしている場合、またはPolyFillを購入できる場合は、フィルリストを使用して配列に変えることができます。 Array.from()
このような:
let fileArray = Array.from(fileList);
その後、の配列を簡単に処理できます File
他の配列と同じです。
私たちはHTML5の領域にいるので、これが私の解決策です。要点は、ファイルをフィルリストに置いたままにしてからXHR2を使用して、ファイルをFormDataオブジェクトにプッシュするのではなく、アレイにファイルをプッシュすることです。以下の例。
Node.prototype.replaceWith = function(node)
{
this.parentNode.replaceChild(node, this);
};
if(window.File && window.FileList)
{
var topicForm = document.getElementById("yourForm");
topicForm.fileZone = document.getElementById("fileDropZoneElement");
topicForm.fileZone.files = new Array();
topicForm.fileZone.inputWindow = document.createElement("input");
topicForm.fileZone.inputWindow.setAttribute("type", "file");
topicForm.fileZone.inputWindow.setAttribute("multiple", "multiple");
topicForm.onsubmit = function(event)
{
var request = new XMLHttpRequest();
if(request.upload)
{
event.preventDefault();
topicForm.ajax.value = "true";
request.upload.onprogress = function(event)
{
var progress = event.loaded.toString() + " bytes transfered.";
if(event.lengthComputable)
progress = Math.round(event.loaded / event.total * 100).toString() + "%";
topicForm.fileZone.innerHTML = progress.toString();
};
request.onload = function(event)
{
response = JSON.parse(request.responseText);
// Handle the response here.
};
request.open(topicForm.method, topicForm.getAttribute("action"), true);
var data = new FormData(topicForm);
for(var i = 0, file; file = topicForm.fileZone.files[i]; i++)
data.append("file" + i.toString(), file);
request.send(data);
}
};
topicForm.fileZone.firstChild.replaceWith(document.createTextNode("Drop files or click here."));
var handleFiles = function(files)
{
for(var i = 0, file; file = files[i]; i++)
topicForm.fileZone.files.push(file);
};
topicForm.fileZone.ondrop = function(event)
{
event.stopPropagation();
event.preventDefault();
handleFiles(event.dataTransfer.files);
};
topicForm.fileZone.inputWindow.onchange = function(event)
{
handleFiles(topicForm.fileZone.inputWindow.files);
};
topicForm.fileZone.ondragover = function(event)
{
event.stopPropagation();
event.preventDefault();
};
topicForm.fileZone.onclick = function()
{
topicForm.fileZone.inputWindow.focus();
topicForm.fileZone.inputWindow.click();
};
}
else
topicForm.fileZone.firstChild.replaceWith(document.createTextNode("It's time to update your browser."));
これについては非常に迅速かつ短い回避策を見つけました。多くの人気のあるブラウザ(Chrome、Firefox、Safari)でテストされました。
まず、フィルリストを配列に変換する必要があります
var newFileList = Array.from(event.target.files);
特定の要素を削除するには、これを使用してください
newFileList.splice(index,1);
これは古い質問であることは知っていますが、この問題に関して検索エンジンで高いランク付けです。
のプロパティ フィルリスト オブジェクトは削除することはできませんが、少なくともFirefoxでは削除できません それらを変更することができます. 。私の回避策この問題は、プロパティを追加することでした IsValid=true
チェックに合格したファイルに IsValid=false
そうではなかった人たちに。
次に、リストをループして、プロパティのみが IsValid=true
に追加されます formdata.
これを行うためのよりエレガントな方法があるかもしれませんが、ここに私の解決策があります。 jqueryと
fileEle.value = "";
var parEle = $(fileEle).parent();
var newEle = $(fileEle).clone()
$(fileEle).remove();
parEle.append(newEle);
基本的に、入力の値を削除します。それをクローンして、古いものの代わりにクローンを置きます。
これは非常に重要ですが、このように解決したのと同じ問題がありました。私の場合、XMLHTTPリクエストを介してファイルをアップロードしていたので、FormData Appendingを介してFilelist Clonedデータを投稿することができました。 機能とは、複数のファイルを何度もドラッグアンドドロップまたはドロップまたはドロップまたは選択できるだけ(ファイルを再度選択することでクローン化されたフィルリストがリセットされません)、必要なファイルリストから必要なファイルを削除し、XMLHTTPREQUESTを介して送信できます。そこに残った。 これが私がしたことです。ここでの私の最初の投稿なので、コードは少し面倒です。ごめん。ああ、そして私はJoomlaスクリプトのように$の代わりにjqueryを使用する必要がありました。
// some global variables
var clon = {}; // will be my FileList clone
var removedkeys = 0; // removed keys counter for later processing the request
var NextId = 0; // counter to add entries to the clone and not replace existing ones
jQuery(document).ready(function(){
jQuery("#form input").change(function () {
// making the clone
var curFiles = this.files;
// temporary object clone before copying info to the clone
var temparr = jQuery.extend(true, {}, curFiles);
// delete unnecessary FileList keys that were cloned
delete temparr["length"];
delete temparr["item"];
if (Object.keys(clon).length === 0){
jQuery.extend(true, clon, temparr);
}else{
var keysArr = Object.keys(clon);
NextId = Math.max.apply(null, keysArr)+1; // FileList keys are numbers
if (NextId < curFiles.length){ // a bug I found and had to solve for not replacing my temparr keys...
NextId = curFiles.length;
}
for (var key in temparr) { // I have to rename new entries for not overwriting existing keys in clon
if (temparr.hasOwnProperty(key)) {
temparr[NextId] = temparr[key];
delete temparr[key];
// meter aca los cambios de id en los html tags con el nuevo NextId
NextId++;
}
}
jQuery.extend(true, clon, temparr); // copy new entries to clon
}
// modifying the html file list display
if (NextId === 0){
jQuery("#filelist").html("");
for(var i=0; i<curFiles.length; i++) {
var f = curFiles[i];
jQuery("#filelist").append("<p id=\"file"+i+"\" style=\'margin-bottom: 3px!important;\'>" + f.name + "<a style=\"float:right;cursor:pointer;\" onclick=\"BorrarFile("+i+")\">x</a></p>"); // the function BorrarFile will handle file deletion from the clone by file id
}
}else{
for(var i=0; i<curFiles.length; i++) {
var f = curFiles[i];
jQuery("#filelist").append("<p id=\"file"+(i+NextId-curFiles.length)+"\" style=\'margin-bottom: 3px!important;\'>" + f.name + "<a style=\"float:right;cursor:pointer;\" onclick=\"BorrarFile("+(i+NextId-curFiles.length)+")\">x</a></p>"); // yeap, i+NextId-curFiles.length actually gets it right
}
}
// update the total files count wherever you want
jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
});
});
function BorrarFile(id){ // handling file deletion from clone
jQuery("#file"+id).remove(); // remove the html filelist element
delete clon[id]; // delete the entry
removedkeys++; // add to removed keys counter
if (Object.keys(clon).length === 0){
jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
jQuery("#fileToUpload").val(""); // I had to reset the form file input for my form check function before submission. Else it would send even though my clone was empty
}else{
jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
}
}
// now my form check function
function check(){
if( document.getElementById("fileToUpload").files.length == 0 ){
alert("No file selected");
return false;
}else{
var _validFileExtensions = [".pdf", ".PDF"]; // I wanted pdf files
// retrieve input files
var arrInputs = clon;
// validating files
for (var i = 0; i < Object.keys(arrInputs).length+removedkeys; i++) {
if (typeof arrInputs[i]!="undefined"){
var oInput = arrInputs[i];
if (oInput.type == "application/pdf") {
var sFileName = oInput.name;
if (sFileName.length > 0) {
var blnValid = false;
for (var j = 0; j < _validFileExtensions.length; j++) {
var sCurExtension = _validFileExtensions[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if (!blnValid) {
alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
return false;
}
}
}else{
alert("Sorry, " + arrInputs[0].name + " is invalid, allowed extensions are: " + _validFileExtensions.join(" or "));
return false;
}
}
}
// proceed with the data appending and submission
// here some hidden input values i had previously set. Now retrieving them for submission. My form wasn't actually even a form...
var fecha = jQuery("#fecha").val();
var vendor = jQuery("#vendor").val();
var sku = jQuery("#sku").val();
// create the formdata object
var formData = new FormData();
formData.append("fecha", fecha);
formData.append("vendor", encodeURI(vendor));
formData.append("sku", sku);
// now appending the clone file data (finally!)
var fila = clon; // i just did this because I had already written the following using the "fila" object, so I copy my clone again
// the interesting part. As entries in my clone object aren't consecutive numbers I cannot iterate normally, so I came up with the following idea
for (i = 0; i < Object.keys(fila).length+removedkeys; i++) {
if(typeof fila[i]!="undefined"){
formData.append("fileToUpload[]", fila[i]); // VERY IMPORTANT the formdata key for the files HAS to be an array. It will be later retrieved as $_FILES['fileToUpload']['temp_name'][i]
}
}
jQuery("#submitbtn").fadeOut("slow"); // remove the upload btn so it can't be used again
jQuery("#drag").html(""); // clearing the output message element
// start the request
var xhttp = new XMLHttpRequest();
xhttp.addEventListener("progress", function(e) {
var done = e.position || e.loaded, total = e.totalSize || e.total;
}, false);
if ( xhttp.upload ) {
xhttp.upload.onprogress = function(e) {
var done = e.position || e.loaded, total = e.totalSize || e.total;
var percent = done / total;
jQuery("#drag").html(Math.round(percent * 100) + "%");
};
}
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var respuesta = this.responseText;
jQuery("#drag").html(respuesta);
}
};
xhttp.open("POST", "your_upload_handler.php", true);
xhttp.send(formData);
return true;
}
};
これでHTMLとスタイルがあります。私はかなり初心者ですが、これはすべて私のために働いていて、それを理解するのにしばらく時間がかかりました。
<div id="form" class="formpos">
<!-- Select the pdf to upload:-->
<input type="file" name="fileToUpload[]" id="fileToUpload" accept="application/pdf" multiple>
<div><p id="drag">Drop your files here or click to select them</p>
</div>
<button id="submitbtn" onclick="return check()" >Upload</button>
// these inputs are passed with different names on the formdata. Be aware of that
// I was echoing this, so that's why I use the single quote for php variables
<input type="hidden" id="fecha" name="fecha_copy" value="'.$fecha.'" />
<input type="hidden" id="vendor" name="vendorname" value="'.$vendor.'" />
<input type="hidden" id="sku" name="sku" value="'.$sku.'"" />
</div>
<h1 style="width: 500px!important;margin:20px auto 0px!important;font-size:24px!important;">File list:</h1>
<div id="filelist" style="width: 500px!important;margin:10px auto 0px!important;">Nothing selected yet</div>
そのためのスタイル。私はそれらのいくつかをマークしなければなりませんでした!Joomlaの動作を無効にするために重要です。
.formpos{
width: 500px;
height: 200px;
border: 4px dashed #999;
margin: 30px auto 100px;
}
.formpos p{
text-align: center!important;
padding: 80px 30px 0px;
color: #000;
}
.formpos div{
width: 100%!important;
height: 100%!important;
text-align: center!important;
margin-bottom: 30px!important;
}
.formpos input{
position: absolute!important;
margin: 0!important;
padding: 0!important;
width: 500px!important;
height: 200px!important;
outline: none!important;
opacity: 0!important;
}
.formpos button{
margin: 0;
color: #fff;
background: #16a085;
border: none;
width: 508px;
height: 35px;
margin-left: -4px;
border-radius: 4px;
transition: all .2s ease;
outline: none;
}
.formpos button:hover{
background: #149174;
color: #0C5645;
}
.formpos button:active{
border:0;
}
これが役立つことを願っています。
ファイルを使用してデータベースにPOSTリクエストを送信する運があり、DOMに送信したいファイルがある場合
ファイルリスト内のファイルがDOMに存在するかどうかを確認できます。もちろん、その要素をDE DBに送信しないだけではないかどうかを確認できます。
@nicholas Anderson Simple and Straightに感謝します。これは、jqueryを使用して私のコードで適用され、動作しているコードです。
HTML。
<input class="rangelog btn border-aero" id="file_fr" name="file_fr[]" multiple type="file" placeholder="{$labels_helpfiles_placeholder_file}">
<span style="cursor: pointer; cursor: hand;" onclick="cleanInputs($('#file_fr'))"><i class="fa fa-trash"></i> Empty chosen files</span>
JSコード
function cleanInputs(fileEle){
$(fileEle).val("");
var parEle = $(fileEle).parent();
var newEle = $(fileEle).clone()
$(fileEle).remove();
$(parEle).prepend(newEle);
}
Arrayを作成し、読み取り専用のフィルリストの代わりに使用することをお勧めします。
var myReadWriteList = new Array();
// user selects files later...
// then as soon as convenient...
myReadWriteList = FileListReadOnly;
その時点で、ビルトインリストの代わりにリストに対してアップロードします。あなたが作業しているコンテキストはわかりませんが、私が見つけたjQueryプラグインを使用して作業しています。 <script>
タグ。次に、ソースの上にアレイを追加して、グローバル変数として機能し、プラグインがそれを参照できるようにしました。
その後、参照を交換するだけの問題でした。
これにより、ビルドインリストが読み取り専用である場合、ドラッグアンドドロップを再び追加できると思います。
:))
入力のタイプをテキストに変更してファイルに戻します。D