Asignar archivo como valor de entrada oculta

Estoy usando un campo de carga de archivos múltiples <input name="filesToUpload" id="filesToUpload" type="file" multiple /> en mi aplicación.

Lo que quiero lograr es enumerar los archivos que eligieron los usuarios y luego permitirles eliminar cualquiera de ellos en la lista. Al final, cuando se envía el formulario, envío todos los datos a través de AJAX, como binario, usando el FormData objeto.

Todo funciona muy bien, excepto por la parte de eliminación.

Yo se que el FileList El atributo es de solo lectura, por lo que lo que hice fue distribuir los archivos como valores de campos de entrada ocultos, agregados a cada uno de los li donde enumero los nombres de los archivos. Entonces, si el usuario elimina un li elemento, el campo de entrada oculto se ha ido con él, y al final, recopilo todos los restantes agregándolos al FormData objeto.

El problema es que cada intento que hice para asignar los archivos como valores a las entradas ocultas me dio resultados extraños.

Mi código es algo como esto:

listFiles : function () {
    var file, files, filesList, filesLength, read;

    files = this.files;
    filesList = $('.files');
    filesLength = files.length;

    // Clear the list
    filesList.html('');

    for ( var i = 0; i < filesLength; i++ ) {
        file = files[i];

        // This is to read the content of the file
        read=new FileReader();
        read.readAsBinaryString( file );

        // When reading is finished
        read.onloadend = function() {
           filesList.append(
                    '<li>' + 
                    '<span class="fileName">' + file.name + '</span>' + 
                    '<a href="#" class="deleteAttachment">x</a>' +
                    '<input type="hidden" name="file[]" value="' + read.result +'"/>' +
                    '</li>');
         }
     }
  }

Acabo de obtener los datos del último archivo, además, el DOM está roto ya que los datos se imprimen por todas partes.

Demostración aquí => http://jsfiddle.net/zKyXC/

preguntado el 22 de mayo de 12 a las 09:05

¿Encontraste una solución adecuada sobre este asunto? -

2 Respuestas

He intentado varias formas de implementar el método descrito anteriormente (asignar cada archivo separado al valor de un campo de entrada [tipo = "oculto"] para permitir la funcionalidad de eliminación de archivos), pero ninguno de ellos tuvo éxito. En este momento, no sé si esto es posible de hacer en absoluto.

Sin embargo, logré resolver el problema con una solución alternativa. Aquí está en caso de que alguien más lo encuentre útil.

En lugar de usar input[type="hidden"] Usé una matriz global donde almacené los archivos al recibirlos. Luego elimino elementos de esa matriz de la forma estándar en que eliminaría objetos de una matriz. Al final agrego cada elemento a la formData objeto y enviarlo al servidor.

Creo y lleno la matriz global de esta manera:

globals.files =[].slice.call( this.files ); 

lo elimino así:

$.each( files, function( index, val ) {
            if ( this.name === fileText ) {
                globals.files.splice( index, 1 );
            }
        });

Nota: fileText es donde almaceno el nombre del elemento que se eliminará.

Y al final lo agrego a formData :

var formData = new FormData();

$.each( files, function( ind, val ) {
            formData.append( 'files[]', this );
       });

Y envía esto como el data propiedad de una llamada jQuery ajax estándar.

contestado el 23 de mayo de 12 a las 10:05

si no me equivoco solo archivo con comillas " sale mal, si no escapas, value se cortará a la primera ocurrencia de " y la parte restante se mostrará como html, por lo que lo que necesita es

read.result.replace(/"/g, '&quot;');

contestado el 22 de mayo de 12 a las 11:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.