Вопрос

Я наращиваю веб-приложение Drag-and-To-to-upload, используя HTML5, и я бросаю файлы в div и, конечно, выбирая объект dataTransfer, который дает мне Филиал.

Теперь я хочу удалить некоторые файлы, но я не знаю, как, или если это даже возможно.

Предпочтительно я хотел бы просто удалить их из филиста; Я не использовал для них. Но если это невозможно, следует ли я вместо этого написать в чеках в коде, который взаимодействует с филистом? Это кажется громоздким.

Это было полезно?

Решение

Если вы хотите удалить только несколько выбранных файлов: вы не можете. То Файл API Рабочий проект Вы подключены к примечанию:

То HTMLInputElement Интерфейс [HTML5] имеет retonly FileListатрибут, [...
Упор мой

Чтение немного рабочего проекта HTML 5, я наткнулся на Общий input Элемент API. Отказ Похоже, вы можете удалить весь Список файлов, установив value свойство input объект к пустой строке, как:

document.getElementById('multifile').value = "";

Кстати, статья Использование файлов из веб-приложений может также представлять интерес.

Другие советы

Этот вопрос уже был отмечен, но я хотел бы поделиться некоторой информацией, которая может помочь другим с использованием FileList.

Было бы удобно лечить филиал в качестве массива, но методы, такие как сортировка, смена, поп и ломтик не работают. Как предложили другие, вы можете скопировать филиал на массив. Однако, вместо того, чтобы использовать петлю, есть простое решение одно строки для обработки этого преобразования.

 // 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 +

Если вы нацеливаете вечнозеленые браузеры (Chrome, Firefox, Edge, но и работает в Safari 9+) или вы можете позволить себе полифилл, вы можете превратить филиал в массив, используя 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 добавления. Функциональность состоит в том, что вы можете перетаскивать или выбирать несколько файлов столько раз, сколько вы хотите (выбирая файлы, снова не сбросит клонированный файл файлы), удалите любой файл, который вы хотите из (клонированного) списка файлов, и отправьте через XMLHTTPREQUEST оставил там. Это то, что я сделал. Это мой первый пост здесь, поэтому код немного грязно. Извиняюсь. Ах, и мне пришлось использовать jQuery вместо $, как это было в Joomla Script.

// 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;
}

Надеюсь, это поможет.

Если вам повезет отправлять запрос на почту в базу данных с файлами, и у вас есть файлы, которые вы хотите отправить в свой DOM

Вы можете просто проверить, присутствует ли файл в списке файлов в вашем DOM, и, конечно, если вы не просто не отправляете этот элемент DE DB.

Спасибо @nicholas Anderson Простой и прямой, вот ваш код применяется и работает в моем коде, используя 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);
}

Возможно, вы пожелаете создать массив и использовать это вместо FileList только для чтения.

var myReadWriteList = new Array();
// user selects files later...
// then as soon as convenient... 
myReadWriteList = FileListReadOnly;

После этого точка сделайте вашу загрузку против вашего списка вместо встроенного списка. Я не уверен в контексте, в котором вы работаете, но я работаю с плагином jQuery, который я нашел, и что мне нужно было сделать, это взять источник плагина и положить его на страницу, используя <script> Теги. Затем выше источника я добавил свой массив, чтобы он мог действовать как глобальная переменная, и плагин может ссылаться на него.

Тогда это было просто вопрос обменивания ссылок.

Я думаю, что это позволит вам также добавить перетаскивание как раз, если встроенный список - только чтение, то, как еще вы можете получить отброшенные файлы в список?

:))

Я просто изменил тип ввода в текст и обратно в файл: D

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top