Criando uma janela modal com dialog

Um componente amplamente empregado no desenvolvimento web é a janela modal, utilizada para mostrar uma variedade de conteúdos, como imagens, alertas, formulários, entre outros. Durante bastante tempo, recorreu-se a bibliotecas, como Bootstrap e jQuery, para facilitar a implementação desses componentes. Pessoalmente, as utilizei muito. Contudo, com a introdução do elemento HTML dialog, a criação de janelas modais tornou-se consideravelmente mais simples e acessível. O dialog é empregado para criar caixas de diálogo tanto modais quanto não modais.

Inicialmente, vamos criar um elemento dialog e adicionar algum conteúdo a ele.

    <dialog>
        <h1>Olá Mundo Dialog</h1>

        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
    </dialog>

Ao observar este exemplo, podemos notar que nada é exibido inicialmente, uma vez que, por padrão, a janela permanece oculta. Para torná-la visível, podemos adicionar o atributo “open” ao elemento dialog (<dialog open>). No entanto, ao fazer isso, ela não será aberta no modo modal. Para ativar o modo modal e abrir como uma janela modal, recorremos ao uso de JavaScript, que nos permite iteragir com ela utilizando os seguintes métodos:

  • .show(): abre o dialog em modo não modal
  • .showModal() : abre o dialog em modo modal
  • .close() : fecha o dialog

Portanto, para criar uma janela modal simples, o código seria o seguinte:

    <script>
        window.onload = () => {
            const dialog = document.querySelector('dialog');

            const openDialog = document.querySelector('#open-dialog');
            openDialog.addEventListener('click', () => {
                dialog.showModal();
            });

            const closeDialog = document.querySelector('#close-dialog');
            closeDialog.addEventListener('click', () => {
                dialog.close();
            });
        }
    </script>

    <button id="open-dialog">Abrir Dialog</button>
    <dialog>
        <h1>Olá Mundo Dialog</h1>

        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>

        <button id="close-dialog">Fechar</button>
    </dialog>

Conforme mostrado no exemplo, pegamos o elemento dialog utilizando o querySelector na linha 3. Na linha 5, obtemos o botão responsável por abrir o dialog e, em seguida, adicionamos um evento de clique (linha 6) a ele, invocando o método showModal do elemento dialog para exibir a caixa de diálogo. Na linha 10, capturamos o botão de fechamento e associamos um evento de clique (linha 11), chamando o método close para encerrar a caixa de diálogo.

Um aspecto relevante é que, quando a caixa de diálogo está aberta no modo modal, é possível fechá-la pressionando a tecla “Esc”.

Agora podemos estilizar com CSS o elemento dialog.

        dialog::backdrop {
            background: rgb(0, 0, 0, 0.5);
        }

        dialog{
            border:none;
            border-radius: 0.5rem;
            box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.7);
        }

O elemento dialog pode ser estilizado como uma caixa qualquer, com um detalhe: para modificar a cor de fundo da janela onde o dialog é exibido sobreposta, utilizamos a pseudo-classe ::backdrop e aplicamos normalmente uma cor de fundo com alguma transparência.

Veja o resultado da janela modal.

Formulário Modal

Podemos criar um formulário dentro de uma elemento dialog, trocando o method do formulário por “dialog“, isto fará que ao invés de enviar os dados para o endereço do action ele irá apenas fechar o dialog.

É possível criar um formulário dentro de um elemento dialog, alterando o atributo method do formulário para “dialog“. Isso fará com que, em vez de enviar os dados para o endereço especificado em action, o formulário simplesmente feche o dialog.

<script>
        window.onload = () => {
            const dialog = document.querySelector('dialog');

            const openDialog = document.querySelector('#open-dialog');
            openDialog.addEventListener('click', () => {
                dialog.showModal();
            });

            const sendBtn = document.querySelector('#btnSend');
            sendBtn.addEventListener("click", (event) => {
                event.preventDefault(); 
                dialog.close('send'); 
            });

            dialog.addEventListener('close', (event) => {
                const nome = document.querySelector('#nome');
                const sobrenome = document.querySelector('#sobrenome');
                if(dialog.returnValue == 'send'){
                    const output = document.querySelector('#output');
                    output.innerHTML = `<p>Nome: ${nome.value}</p><p>Sobrenome: ${sobrenome.value}</p>`;
                }
                if(dialog.returnValue == 'cancel'){
                    nome.value= '';
                    sobrenome.value = '';
                }
            })
        };
    </script>

    <button id="open-dialog">Abrir Dialog Form</button>

    <dialog>
        <h1>Formulário</h1>

        <form method="dialog">
            <div>
                <input name="nome" id="nome" placeholder="Nome">
            </div>
            <div>
                <input name="sobrenome" id="sobrenome" placeholder="Sobrenome">
            </div>
            
            <button value="send" id="btnSend">Enviar</button>
            <button value="cancel"  id="btnCancel">Cancelar</button>
        </form>
    </dialog>

    <div id="output"></div>

No exemplo apresentado, nas linhas 36 a 46, criamos um formulário simples com dois campos de texto, um para o nome e outro para o sobrenome, além de dois botões, um para enviar e outro para cancelar. Entre as linhas 5 e 8, abrimos a janela modal da mesma forma que no exemplo anterior. Na linha 10, selecionamos o botão responsável por enviar os dados, e na linha 11, adicionamos um evento de clique a ele. Dentro desse evento, utilizamos o preventDefault para impedir o comportamento padrão do formulário, permitindo-nos fechar a janela modal por meio do método close(), passando um parâmetro que ficará disponível no atributo returnValue do elemento dialog.

Na linha 16, implementamos um evento de fechamento para o dialog. Dentro desse evento, recuperamos os dois campos de entrada do formulário. Se o valor do atributo returnValue do dialog for “send” (que fornecemos ao chamar o método close), capturamos os valores dos campos e os exibimos em uma div de saída. Caso o valor seja “cancel” (presente no atributo value do botão “Cancelar” clicado para enviar o formulário), limpamos os valores dos campos e como o formulário possui o atributo method="dialog", o formulário será simplesmente fechado.

Veja o exemplo de janela modal com formulário.

Bom era isso, espero que tenha ajudado um pouc. T++.