DEV Community

Gabriel Gomes de Oliveira
Gabriel Gomes de Oliveira

Posted on

1 1 1 1 1

Usando Stimulus para mostrar o nome da imagem no input de arquivo

Oi, mais um post rápido para ensinar o que acabei de aprender: a usar o Stimulus para conseguir mostrar ao usuário o nome do arquivo que ele está fazendo upload no input tipo 'file'.

Input type file

É bem chato não mostrar isso para o usuário e, apesar de ser algo bem simples de ser feito com Javascript puro, eu queria aprender como se faz usando o Stimulus!

Primeiro, adicionamos nosso data-controller na tag que engloba o nosso input. No caso, estou modificando um formulário de criação de livros na minha biblioteca pessoal

app/views/books/new.html.erb

  <div data-controller="file-input">
    <label for="file">Escolha uma imagem para capa do livro</label>
    <input type="file" id="file" name="file" />
    <p>Nenhum arquivo selecionado...</p>
  </div>

Depois, criamos o file_input_controller para manipular essa estrutura.

app/javascript/controllers/file_input_controller

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
}

Precisamos então pensar quais são nossos "alvos", targets, para nossas ações. Queremos que nosso usuário veja o nome do arquivo selecionado após o input, então precisamos verificar o momento que ele faz essa seleção e também precisamos do local onde colocaremos a informação. Então, nossos targets são o input em si e o parágrafo logo em seguida, que mostra ou não se um arquivo foi escolhido.

app/views/books/new.html.erb

  <div data-controller="file-input">
    <label for="file">Escolha uma imagem para capa do livro</label>
    <input type="file" id="file" name="file" data-file-input-target="input" />
    <p data-file-input-target="fileName">Nenhum arquivo selecionado...</p>
  </div>

Criamos também as variáveis dos targets em nosso controller:

app/javascript/controllers/file_input_controller

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["input", "fileName"];
}

Precisamos pensar agora em que momento queremos averiguar essa informação. Ou seja, quando o usuário vai querer ter essa interação com o formulário ou quando ela tem que estar disponível para ele?

Oras, imediatamente, assim que a página é carregada, isso já precisa estar disponível funcionalmente.

Dessa forma, vamos chamar o método connect(), que é um lifecycle callback do Stimulus, uma função nativa que vai ser chamada assim que o nosso controller for conectado com alguma parte da DOM.

Como nós queremos verificar se o usuário adicionou um arquivo pelo input, precisamos adicionar algo que observe qualquer mudança nesse elemento e modifique o texto com o nome do arquivo.

Assim, temos o seguinte:

app/javascript/controllers/file_input_controller

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
    static targets = ["input", "fileName"];

    connect() {
      this.inputTarget.addEventListener("change", this.updateFileName.bind(this));
    }

    updateFileName() {      
      if (this.inputTarget.files.length > 0) {
        this.fileNameTarget.textContent = this.inputTarget.files[0].name;
      }
    }
}

Explicando tudo, assim que o controller se conectar com o elemento DOM com o atributo data-controller="file-input", ele vai buscar o target input (marcado com o atributo data-file-input-target="input") e vai adicionar o "observador de eventos" de change, conectando o contexto do controller para a função updateFileName.

A função updateFileName vai ser ativada quando o valor do input for alterado, verificando se há algum arquivo e, se houver, irá alterar o conteúdo do elemento marcado com o fileNameTarget para o nome do arquivo. E voilà, é isso, acabou.

Parando pra pensar agora, acho que eu quero mostrar a imagem para o usuário também, mas isso eu faço outro dia! Abraço

Image of Docusign

Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs