Subir archivos con arrastrar y soltar con vista previa

El día de hoy vamos a ver como implementar la funcionalidad de subir archivos con arrastrar y soltar o drag and drop a un servidor y que ademas se obtenga una vista previa de la imagen o del tipo de archivo subido, todo esto mediante la librería DropZone.js. Ademas de todo esto, que ya es bastante :P, tendremos la funcionalidad de eliminar fácilmente los archivos subidos (ya que se listaran todos los archivos en el servidor) y modificaremos un poco el codigo de dropzone.js para tener también la opción de descargar dichos archivos, vamos pues que ya! 8)

Para comenzar vamos a ir a la web de dropzone.js para conocer mas en detalle la librería.

Los archivos necesarios serán el javascript de dropzone, el css de dropzone y para algunas funcionalidades jquery.

Vamos a necesitar primero crear la interfaz donde los usuarios podran arrastrar y soltar sus archivos para subir a una carpeta del servidor.

Este archivo contendrá lo siguiente,

<html>
<head>
<style>
body{
font-weight: normal;
font-family: 'Source Sans Pro',sans-serif;
}
</style>
<link rel="stylesheet" href="dist/css/dropzone.css">
</head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="dist/js/dropzone.js"></script>
<script>
$(document).ready(function (){

/* INICIA CONFIGURACIÓN DE DROPZONE */
Dropzone.options.myDropzone = {
dictDefaultMessage: "Arrastre aqui archivos para subir.",
addRemoveLinks: true,
init: function() {
thisDropzone = this;
/* ESTE CODIGO SIRVE PARA MOSTRAR LOS ARCHIVOS ACTUALES EN EL SERVIDOR*/
$.get('file_upload/index.php', function(data) {

$.each(data, function(key,value){
var mockFile = { name: value.name, size: value.size};
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "file_upload/docs/"+value.name);
thisDropzone.emit("complete", mockFile);
var ext = mockFile.name.split(".")[1];
switch(ext){
case "xls":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/excel.png');
break;
case "xlsx":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/excel.png');
break;
case "pdf":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/pdf.png');
break;
case "doc":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/doc.png');
case "docx":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/doc.png');
break;
case "zip":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/zip.png');
break;
case "rar":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/rar.png');
break;
case "ppt":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/ppt.png');
break;
case "pptx":
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/ppt.png');
break;
case "png":
break;
case "jpg":
break;
case "jpeg":
break;
default:
thisDropzone.createThumbnailFromUrl(mockFile, 'dist/img/nose.png');
break;
}
});
});
},
/* EL EVENTO ACCEPT NOS PERMITE CAMBIAR LA IMAGEN DE VISTA PREVIA QUE SE MUESTRA */
accept: function(file, done) {
var thumbnail = $('.dropzone .dz-preview.dz-file-preview .dz-image:last');

switch (file.type) {
case 'application/pdf':
thumbnail.css('background', 'url(dist/img/pdf.png');
break;
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
thumbnail.css('background', 'url(dist/img/doc.png');
break;
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
thumbnail.css('background', 'url(dist/img/excel.png');
break;
case 'application/vnd.ms-excel':
thumbnail.css('background', 'url(dist/img/excel.png');
break;
case 'application/zip, application/x-compressed-zip':
thumbnail.css('background', 'url(dist/img/zip.png');
break;
case 'application/vnd.ms-powerpointtd>':
thumbnail.css('background', 'url(dist/img/ppt.png');
break;
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
thumbnail.css('background', 'url(dist/img/ppt.png');
break;
case 'image/jpeg':
break;
case 'image/png':
break;
default:
thumbnail.css('background', 'url(dist/img/nose.png');
}

done();
},
/* ESTE EVENTO NOS PERMITE ELIMINAR REALMENTE EL ARCHIVO DEL SERVIDOR */
removedfile: function(file) {
$.get( "eliminarArchivo.php", {
nombre: file.name
}).done(function( data ) {
var _ref;
return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
});
}
};

});
</script>
<form action="file_upload/" class="dropzone" id="my-dropzone" method="post">
</form>
</body>
</html>

El código viene bastante entendible, los puntos donde hay dudas o archivos pendientes es explican a continuación.

Omitiendo por ahora todo el código javascript que contiene lo anterior podemos ver que hay un formulario con un action que lleva a una pagina index.php en una carpeta file_upload, el archivo lo puedes descargar de aqui.

En el codigo principal también vemos que para eliminar un archivo del servidor se manda llamar a un archivo llamado eliminarArchivo.txt el cual es bastante simple y puedes descargar aqui.

Las modificaciones en el dropzone.js para agregar el botón de descargar son las siguientes,

busca la siguiente linea en tu archivo dropzone.js

if (this.options.addRemoveLinks) {

el contenido de ese if{} debera ser el siguiente

var elementoContenedor = document.createElement('div');
elementoContenedor.id = "botonesAgrupados";
elementoContenedor.style = "display:inline-block;text-align:center;";
file._openLink = Dropzone.createElement("<a href=\"file_upload/docs/" + file.name + "\" style=\"float:left;color:#000;cursor:pointer;margin-right:15px;\" class=\"dz-open\" download>Descargar</a>");

file._removeLink = Dropzone.createElement("<a style=\"float:left;text-decoration:underline;\" class=\"dz-remove\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
elementoContenedor.appendChild(file._openLink);
elementoContenedor.appendChild(file._removeLink);
file.previewElement.appendChild(elementoContenedor);

Cualquier duda o comentario con gusto lo responderé en los comentarios.

Hasta luego!


Originally published at Blog de Programacion.