w3schools read por manejo linea leer example ejemplo archivos archivo javascript html5 drag-and-drop filelist

javascript - read - ¿Cómo elimino un archivo de FileList?



manejo de archivos en javascript (10)

Como estamos en el reino HTML5, esta es mi solución. Lo esencial es que inserte los archivos en una matriz en lugar de dejarlos en una Lista de archivos, y luego usando XHR2, inserta los archivos en un objeto FormData. Ejemplo a continuación.

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."));

Estoy construyendo una aplicación web "arrastrar y soltar para subir" usando HTML5, y dejo caer los archivos en un div y, por supuesto, obtengo el objeto dataTransfer, que me da FileList .

Ahora quiero eliminar algunos de los archivos, pero no sé cómo, o si es posible.

Preferentemente, me gustaría simplemente eliminarlos de FileList; No tengo ningún uso para ellos. Pero si eso no es posible, ¿debería escribir cheques en código que interactúe con FileList? Eso parece engorroso.


Es posible que desee crear una matriz y usarla en lugar de la lista de archivos de solo lectura.

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

Después de ese punto, cargue contra su lista en lugar de la lista incorporada. No estoy seguro del contexto en el que está trabajando, pero estoy trabajando con un plugin jquery que encontré y lo que tuve que hacer fue tomar el código fuente del complemento y ponerlo en la página usando las etiquetas <script> . Luego, por encima de la fuente, agregué mi matriz para que pueda actuar como una variable global y el complemento pueda hacer referencia a ella.

Entonces solo se trataba de cambiar las referencias.

Creo que esto también te permitirá agregar arrastrar y soltar como nuevamente, si la lista incorporada es de solo lectura, ¿de qué otra forma podrías obtener los archivos eliminados en la lista?

:))


Esta pregunta ya fue marcada como respondida, pero me gustaría compartir información que podría ayudar a otros a usar FileList.

Sería conveniente tratar FileList como una matriz, pero los métodos como sort, shift, pop y slice no funcionan. Como otros han sugerido, puede copiar FileList a una matriz. Sin embargo, en lugar de utilizar un bucle, hay una solución simple de una línea para manejar esta conversión.

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

Probado OK en FF, Chrome e IE10 +


Esto es improvisado, pero tuve el mismo problema que resolví de esta manera. En mi caso, estaba cargando los archivos a través de la solicitud XMLHttp, así que pude publicar los datos clonados de FileList a través de los formularios adjuntos. La funcionalidad es que puede arrastrar y soltar o seleccionar múltiples archivos tantas veces como desee (seleccionar nuevamente los archivos no reiniciará FileList clonado), eliminar cualquier archivo que desee de la lista de archivos (clonados) y enviar a través de xmlhttprequest lo que sea dejado allí. Esto es lo que hice. Es mi primer post aquí, así que el código es un poco complicado. Lo siento. Ah, y tuve que usar jQuery en lugar de $, ya que estaba en el script de Joomla.

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

Ahora el html y los estilos para esto. Soy bastante novato, pero todo esto realmente funcionó para mí y me tomó un tiempo darme cuenta.

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

Los estilos para eso. ¡Tuve que marcar algunos de ellos! Importante para anular el comportamiento de 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; }

Espero que esto ayude.


He encontrado una solución muy rápida y breve para esto. Probado en muchos navegadores populares (Chrome, Firefox, Safari);

En primer lugar, debe convertir FileList en una matriz

var newFileList = Array.from(event.target.files);

para eliminar el elemento particular usa esto

newFileList.splice(index,1);


Puede haber una forma más elegante de hacerlo, pero esta es mi solución. Con Jquery

fileEle.value = ""; var parEle = $(fileEle).parent(); var newEle = $(fileEle).clone() $(fileEle).remove(); parEle.append(newEle);

Básicamente, calzas el valor de la entrada. Clonarlo y poner el clon en lugar del anterior.


Sé que esta es una vieja pregunta, pero ocupa un lugar destacado en los motores de búsqueda con respecto a este tema.

las propiedades del objeto FileList no se pueden eliminar, pero al menos en Firefox se pueden modificar . Mi solución a este problema fue agregar una propiedad IsValid=true para aquellos archivos que pasaron la verificación e IsValid=false para aquellos que no lo hicieron.

luego simplemente recorro la lista para asegurarme de que solo las propiedades con IsValid=true se agregan a FormData .


Si desea eliminar solo varios de los archivos seleccionados, no puede. El FileList que está vinculado contiene una nota:

La interfaz HTMLInputElement [HTML5] tiene un atributo FileList solo lectura , [...]
[énfasis mío]

Leyendo un poco del borrador de trabajo de HTML 5, me encontré con las API del elemento de input común . Parece que puede eliminar toda la lista de archivos estableciendo la propiedad de value del objeto de input en una cadena vacía, como:

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

Por cierto, el artículo Uso de archivos de aplicaciones web también podría ser de interés.


Si se dirige a navegadores de hoja perenne (Chrome, Firefox, Edge, pero también funciona en Safari 9+) o puede pagar un relleno múltiple, puede convertir FileList en una matriz usando Array.from() esta manera:

let fileArray = Array.from(fileList);

Entonces es fácil manejar la matriz de File como cualquier otra matriz.


Si tiene la suerte de enviar una solicitud a la base de datos con los archivos y tiene los archivos que desea enviar en su DOM

simplemente puede verificar si el archivo en la lista de archivos está presente en su DOM y, por supuesto, si no lo está, simplemente no envíe ese elemento a de DB.