Páginas

terça-feira, 20 de setembro de 2011

Utilizando corretamente o atributo MODAL do Dialog no jQuery UI

Você sabia que o atributo modal do widget "Dialog" do jQuery UI ao ser habilitado, altera não só as características de visualização da tela travando o background mas também desabilita alguns elementos na página, evitando que suas ações sejam realizadas?

Muito bem!
Descobri esta informação hoje ao enfrentar um problema no qual eu não conseguia disparar um click de um botão em um WebForm com o Dialog aberto.
Vamos a um exemplo para ser mais específico!

Digamos que eu tenha uma página contendo o seguinte html:
<html>
<head>
 <title>Teste Dialog</title>
</head>
<body>

<form>

Texto: <input type="text" id="texto">
<input type="submit" id="btnEnviar" value="Enviar">

</form>

</body>
</html>
Com esta tela, o usuário solicita que você inclua uma mensagem de confirmação que é exibida ao clicar no botão Enviar, para que o usuário possa decidir se deseja continuar ou não.
Como você conhece jQuery e quer utilizar os widgets que existem na biblioteca do jQuery UI, você acaba optando pelo "Dialog".
Seu código html ficará da seguinte forma:
<html>
<head>
 <title>Teste Dialog</title>
 <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
 <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>

 <script language="JavaScript">
     var botaoFoiClicado = false;

     $(function () {

         $('#btnEnviar').click(function (event) {
             if (!botaoFoiClicado) {
                 event.preventDefault();
                 $('#DialogConfirmacao').dialog('open');
             }
         });

         $('#DialogConfirmacao').dialog({
             autoOpen: false,
             width: 250,
             height: 300,
             buttons: {
                 "Não": function () { botaoFoiClicado = false; $(this).dialog("close"); },
                 "Sim": function () { botaoFoiClicado = true; $('#btnEnviar').click(); }
             }
         });

     });
 </script>
</head>
<body>

<form>

Texto: <input type="text" id="texto">

<input type="submit" id="btnEnviar" value="Enviar">

</form>

<div id="DialogConfirmacao" title="Confirmação">
 Tem certeza que deseja enviar esta informação?
</div>

</body>
</html>
Com este código, você apresenta a tela para o usuário e ele diz: "Muito bom! Era isso que eu estava pensando!! Mas só uma coisa, deste modo em que está a pessoa poderá alterar o texto que está no campo ainda. Não tem como bloquear o fundo?"

Você mostrando que a solução para isto é simples, rapidamente e adiciona o atributo "modal" na criação do dialog, ficando assim:
         $('#DialogConfirmacao').dialog({
             autoOpen: false,
             width: 250,
             height: 300,
             modal: true,
             buttons: {
                 "Não": function () { botaoFoiClicado = false; $(this).dialog("close"); },
                 "Sim": function () { botaoFoiClicado = true; $('#btnEnviar').click(); }
             }
         });
Você atualiza a página e mostra para o usuário que aquilo era simples!



Ele te elogia e diz que está perfeito e que você é um ótimo desenvolvedor. Você agradece e vai para sua mesa.
Logo que você volta, o usuário liga no seu ramal e diz que o botão "Sim" não está funcionando. Você fica com um ponto de interrogação na cabeça pensando como aquilo seria possível diante de tão simples programação.

Depois de horas pesquisando, você se depara com o texto na documentação do jQuery UI, falando sobre o modal:
If set to true, the dialog will have modal behavior; other items on the page will be disabled (i.e. cannot be interacted with).


Você para por alguns instantes e diz: "Caramba! Que coisa simples! É exatamente o funcionamento correto de uma modal! Porque não pensei nisso antes!?"

Concluindo, para resolver este problema tive que fechar a modal antes de clicar no botão Enviar, conforme exemplo abaixo:
         $('#DialogConfirmacao').dialog({
             autoOpen: false,
             width: 250,
             height: 300,
             modal: true,
             buttons: {
                 "Não": function () { botaoFoiClicado = false; $(this).dialog("close"); },
                 "Sim": function () { botaoFoiClicado = true; $(this).dialog("close"); $('#btnEnviar').click(); }
             }
         });
Referências: http://docs.jquery.com/UI/Dialog#option-modal e http://jqueryui.com/demos/dialog/

7 comentários:

  1. Olá como faria para pegar um valor de um input e enviar para uma janela modal como uma variavel php ?? sei que assim eu passo em forma de texto para o dialog:
    var txt = $("input[type=text][name=teste]").val(); // PEGA VALOR DE INPUT

    $("#dialog-form").text(txt ); // MOSTRA VALOR DE INPUT

    $( "#dialog-form" ).dialog("open" );

    ResponderExcluir
    Respostas
    1. Não entendi muito bem sua pergunta.
      Você entendeu que o Dialog do jQuery não é uma popup, certo?
      O que exatamente você necessita?

      Se é uma variável, você não necessita passar para o Dialog. Do próprio Dialog você consegue resgatar essa variável que já se encontra na mesma página.

      Excluir
    2. Caro José, obrigado por responder minha pergunta, vamos ver se consigo te explicar melhor. Vamos se basear no seu exemplo acima... Minha dúvida é + - assim... como faria para por exemplo mostrar (ou pegar) o valor que foi digitado no seu input "texto" e de alguma forma mostrar este valor digitado na janela modal que se abre de confirmação? Será que consegui ser mais claro agora. Agradeço pela resposta. Abs

      Excluir
    3. Sim. Eu adicionaria algum elemento dentro da div para ficar mais fácil de manipular.

      Exemplo:

      <input type="text" id="txtValor" />
      <input type="button" id="btnExecutar" />

      <div id="DialogConfirmacao" title="Confirmação">
      Tem certeza que deseja enviar a informação <span id="nrInfo" /> ?
      </div>

      No evento click do botão, eu realizo resgato o valor do input e adiciono este valor no elemento que está dentro do div (Dialog).

      $('#btnExecutar').click(function ()
      {
      var nrInfo = $('#txtValor').val();
      $('#nrInfo').html(nrInfo);
      $('#DialogConfirmacao').dialog('open');
      });

      Consegui responder sua pergunta?

      Excluir
    4. Obrigado mais uma vez José, sim conseguiu responder minha pergunta e solucionei o meu problema. Abraços.

      Excluir
    5. Oi galera,

      No dialog dá para ter inicialmente os botões escondidos e após carregar noutro botão, e uma função verificar-se, por exemplo, algum dos outros ficar então visível?

      Excluir