sistema de “drag and drop” para upload de arquivos no Laravel

Para implementar um sistema de “drag and drop” (arrastar e soltar) para upload de arquivos no Laravel, você precisa adicionar um pouco de JavaScript no lado do frontend para permitir que os usuários arrastem e soltem arquivos, além de ajustar o formulário para suportar o envio desses arquivos de maneira adequada.

Vou mostrar como você pode fazer isso utilizando o HTML5 e JavaScript no frontend e Laravel no backend.

1. Estrutura do Backend (Laravel)

A estrutura do backend no Laravel será praticamente a mesma que no exemplo anterior. No Laravel, você vai continuar utilizando um método no controlador para processar o upload de arquivos, mas vamos ajustar o código para permitir que o upload seja feito por meio de um formulário multipart/form-data que irá lidar com arquivos enviados via drag-and-drop.

Atualização do Controlador FileUploadController

Certifique-se de que o controlador que recebe o upload de arquivos ainda tenha a mesma funcionalidade, conforme o exemplo anterior:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileUploadController extends Controller
{
    public function showForm()
    {
        return view('upload.form');
    }

    public function upload(Request $request)
    {
        // Validação do arquivo
        $request->validate([
            'file' => 'required|file|mimes:jpg,png,pdf,docx|max:2048',
        ]);

        // Verificar se o arquivo foi carregado com sucesso
        if ($request->hasFile('file') && $request->file('file')->isValid()) {
            // Pegar o arquivo
            $file = $request->file('file');

            // Definir o nome do arquivo
            $fileName = time() . '_' . $file->getClientOriginalName();

            // Salvar o arquivo no disco 'local'
            $path = $file->storeAs('uploads', $fileName, 'local');

            // Retornar o caminho do arquivo ou qualquer outra informação
            return back()->with('success', 'Arquivo enviado com sucesso!')->with('path', $path);
        }

        return back()->withErrors('Erro ao enviar arquivo.');
    }
}

As rotas em routes/web.php também continuam as mesmas:

use App\Http\Controllers\FileUploadController;

Route::get('/upload', [FileUploadController::class, 'showForm']);
Route::post('/upload', [FileUploadController::class, 'upload']);

2. Estrutura do Frontend (Drag and Drop)

Agora, vamos criar a interface do usuário com um formulário de drag-and-drop utilizando HTML5, CSS e JavaScript. Em resources/views/upload/form.blade.php, vamos criar um formulário mais interativo com a funcionalidade de arrastar e soltar arquivos.

Código do Formulário de Upload com Drag and Drop

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload de Arquivo</title>
    <style>
        /* Estilos básicos para o drag-and-drop */
        #drop-zone {
            width: 100%;
            height: 200px;
            border: 2px dashed #007bff;
            border-radius: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 18px;
            color: #007bff;
            cursor: pointer;
            margin: 20px 0;
        }

        #drop-zone.drag-over {
            background-color: rgba(0, 123, 255, 0.1);
        }

        #drop-zone p {
            margin: 0;
        }

        #file-input {
            display: none;
        }

        /* Estilos de erro */
        .error {
            color: red;
        }

        /* Estilos para exibir o sucesso */
        .success {
            color: green;
        }
    </style>
</head>
<body>
    <h1>Upload de Arquivo com Drag and Drop</h1>

    @if(session('success'))
        <p class="success">{{ session('success') }}</p>
        <p>Arquivo salvo em: {{ session('path') }}</p>
    @endif

    @if($errors->any())
        <ul>
            @foreach($errors->all() as $error)
                <li class="error">{{ $error }}</li>
            @endforeach
        </ul>
    @endif

    <form id="upload-form" action="/upload" method="POST" enctype="multipart/form-data">
        @csrf
        <!-- Zone de arrastar e soltar -->
        <div id="drop-zone" ondrop="handleDrop(event)" ondragover="handleDragOver(event)">
            <p>Arraste e solte o arquivo aqui ou clique para selecionar</p>
            <input type="file" name="file" id="file-input" accept="image/*, .pdf, .docx" onchange="handleFileSelect(event)">
        </div>
        <button type="submit">Enviar Arquivo</button>
    </form>

    <script>
        // Função para permitir o arrastar e soltar
        function handleDragOver(event) {
            event.preventDefault();
            document.getElementById('drop-zone').classList.add('drag-over');
        }

        // Função quando o arquivo é solto
        function handleDrop(event) {
            event.preventDefault();
            document.getElementById('drop-zone').classList.remove('drag-over');
            const files = event.dataTransfer.files;
            if (files.length > 0) {
                document.getElementById('file-input').files = files;
            }
        }

        // Função para capturar a seleção de arquivo
        function handleFileSelect(event) {
            const files = event.target.files;
            if (files.length > 0) {
                document.getElementById('drop-zone').innerHTML = `<p>Arquivo selecionado: ${files[0].name}</p>`;
            }
        }

        // Função para abrir o seletor de arquivos ao clicar na zona de arrasto
        document.getElementById('drop-zone').onclick = function() {
            document.getElementById('file-input').click();
        }
    </script>
</body>
</html>

Explicação do Código

  • Estilos: Definimos uma área de drag-and-drop (#drop-zone) com borda tracejada, e a classe drag-over é adicionada quando o arquivo está sendo arrastado sobre a área para indicar visualmente que a área é válida para o upload.
  • JavaScript:
    • A função handleDragOver evita o comportamento padrão do navegador e adiciona a classe drag-over para alterar a aparência da área de arraste.
    • A função handleDrop trata o evento de soltura, impedindo o comportamento padrão e atribuindo os arquivos à entrada de arquivo (#file-input).
    • A função handleFileSelect atualiza a área de arraste com o nome do arquivo quando o usuário seleciona um arquivo diretamente do navegador.
    • O evento onclick na zona de arraste permite abrir o seletor de arquivos quando o usuário clica na área de drag-and-drop.

3. Testar o Sistema de Upload com Drag and Drop

  • Frontend: Ao acessar a página de upload (http://localhost:8000/upload), o usuário poderá arrastar um arquivo para a área designada ou clicar na área para selecionar um arquivo manualmente.
  • Backend: O Laravel receberá o arquivo e o processará da mesma forma que no exemplo anterior, incluindo a validação e o armazenamento do arquivo.

4. Considerações Finais

  • Validação de Arquivo: A validação no backend ainda se aplica, portanto, se o arquivo não atender aos requisitos (tipo de arquivo, tamanho, etc.), o Laravel retornará um erro.
  • Suporte a Vários Arquivos: Para permitir o envio de vários arquivos, você pode modificar a entrada de arquivos no frontend para aceitar múltiplos arquivos (<input type="file" name="file[]" multiple>), e ajustar o controlador para processar uma lista de arquivos.

Esse exemplo oferece uma solução simples de drag-and-drop para upload de arquivos em Laravel!

Posts Similares