Implementar una funcionalidad de drag and drop para subir archivos en Angular de manera nativa puede ser más sencillo de lo que parece. No es necesario recurrir a librerías externas, ya que podemos aprovechar las características nativas de HTML5 y Angular para crear una interfaz intuitiva y funcional para los usuarios.
En este artículo, te mostraré paso a paso cómo construir un área de drag and drop en Angular para subir archivos, además de permitir que los usuarios seleccionen archivos a través de un input tradicional si lo prefieren.
Lo primero que necesitamos es un área donde los usuarios puedan arrastrar y soltar los archivos. Para ello, usaremos un div
que manejará los eventos de arrastre y soltado, y un input
oculto para permitir la selección de archivos de manera convencional.
<div class="drag-drop-container"
(dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)"
(drop)="onDrop($event)">
<p>Arrastra y suelta los archivos aquí</p>
<button mat-button (click)="fileInput.click()">Seleccionar archivos</button>
<input type="file" #fileInput multiple (change)="onFileSelect($event)" style="display:none" />
</div>
<ul *ngIf="files.length > 0">
<li *ngFor="let file of files">
{{ file.name }}
</li>
</ul>
div
): Este contenedor se encargará de recibir los archivos que el usuario arrastre. Se utilizan los eventos dragover
, dragleave
y drop
para manejar la interacción.Añadimos estilos para que el área de arrastre sea más atractiva visualmente y cambie de color cuando se esté arrastrando un archivo sobre ella.
.drag-drop-container {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
margin-top: 20px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.drag-drop-container.dragging {
background-color: #e0f7fa;
}
padding
para que el área sea fácilmente reconocible como una zona de arrastre.Ahora, necesitamos gestionar los eventos de arrastre, soltado y selección de archivos en nuestro componente de Angular. Aquí te muestro cómo hacerlo:
import { Component } from '@angular/core';
@Component({
selector: 'app-reservation-dialog',
templateUrl: './reservation-dialog.component.html',
styleUrls: ['./reservation-dialog.component.scss'],
})
export class ReservationDialogComponent {
public files: File[] = [];
// Evita que el navegador abra el archivo en la ventana
public onDragOver(event: DragEvent) {
event.preventDefault();
event.stopPropagation();
const element = event.target as HTMLElement;
element.classList.add('dragging');
}
public onDragLeave(event: DragEvent) {
const element = event.target as HTMLElement;
element.classList.remove('dragging');
}
public onDrop(event: DragEvent) {
event.preventDefault();
event.stopPropagation();
const element = event.target as HTMLElement;
element.classList.remove('dragging');
if (event.dataTransfer?.files) {
const filesArray = Array.from(event.dataTransfer.files);
this.files.push(...filesArray); // Añade los archivos al array
}
}
// Maneja los archivos seleccionados por el input de exploración
public onFileSelect(event: any) {
const selectedFiles = event.target.files as FileList;
this.files.push(...Array.from(selectedFiles));
}
}
onDragOver(event)
: Este método previene el comportamiento predeterminado del navegador (como abrir archivos en una nueva pestaña) y añade la clase dragging
al contenedor, lo que activa el cambio de color de fondo.onDragLeave(event)
: Cuando el archivo deja el área de arrastre, se elimina la clase dragging
para restaurar el estilo original del contenedor.onDrop(event)
: Al soltar los archivos en el área, este método previene el comportamiento predeterminado y los añade a la lista files
. Aquí es donde se realiza la acción principal de capturar los archivos arrastrados.onFileSelect(event)
: Si el usuario selecciona archivos desde el input oculto, este método los procesa y los añade a la lista files
.Este ejemplo básico se puede mejorar con algunas validaciones o funcionalidades adicionales, como:
file.type
) antes de añadirlo a la lista de archivos permitidos.file.size
.public onDrop(event: DragEvent) {
event.preventDefault();
event.stopPropagation();
const element = event.target as HTMLElement;
element.classList.remove('dragging');
if (event.dataTransfer?.files) {
const validTypes = ['image/png', 'image/jpeg', 'application/pdf'];
const filesArray = Array.from(event.dataTransfer.files).filter(file => validTypes.includes(file.type));
if (filesArray.length !== event.dataTransfer.files.length) {
alert('Algunos archivos tienen un formato no permitido');
}
this.files.push(...filesArray);
}
}
Crear un área de drag and drop para subir archivos en Angular de manera nativa es una tarea sencilla y te da la flexibilidad de personalizar la experiencia del usuario sin depender de librerías externas. Con este enfoque, puedes implementar una funcionalidad clave en tu aplicación y mantener el control total sobre su comportamiento y estilo.
Ahora que ya tienes el conocimiento básico, puedes seguir mejorando la funcionalidad con validaciones de archivos, integración con servicios de backend para subir los archivos o añadir mensajes de error personalizados. ¡La personalización está en tus manos!
I am particularly drawn to developing applications that are not only functional but also visually appealing and easy to use. I accomplish this by implementing SOLID principles and clean architecture, and applying testing to ensure quality.