Contagem regressiva com C# e JavaScript

Olá, pessoal! Hoje veremos uma forma dinâmica de desenvolver um contador regressivo, feito em javascript comunicando com o C#, mais especificamente com o Control Toolkit.
Requisitos:
  • Visual Studio .NET 2008
  • Linguagem C#.NET
  • Ajax ControlToolkit
Foi me dada a missão de gerar um relatório que fosse atualizado a cada 30 segundos, automaticamente, depois de clicar no botão para gerar. Até aí é tranquilo, pois é necessário usar o Timer e o GridView.
Só que era necessário mostrar os segundos para o usuário, na tela. Isto é, os segundos decrescentes - 30, 29, 28, 27...e assim por diante. O contador deve ser mostrado na tela, acima de todos os objetos. 
Para facilitar o artigo, vou mostrar algumas telas com o resultado do que foi desenvolvido. Para ficar mais fácil de entender, segue a tela 1:
imagem
Na figura acima, uma tela de gráfico é mostrada com os segundos no canto direito, de forma decrescente, começando em 30. 
Esses segundos devem ficar em cima de toda as telas, nunca podendo ficar atrás de algum componente de tela. Na próxima imagem, a tela subiu e os segundos continuam regredindo e acima do gráfico:
imagem
De agora em diante, vou mostrar como fazer para que os segundos fiquem acima da imagem e tenham sincronismo para atualizar a página pelo C# depois de acabar a contagem.
O primeiro passo é criar o contador regressivo em JavaScript:
<script language="javascript">

        var parselimit;
        function inicio() {
            clock1.innerHTML = "";
            var limit = "0:31"

            if (document.images) {
                parselimit = limit.split(":")
                parselimit = parselimit[0] * 60 + parselimit[1] * 1
            }

            begintimer();
        }

        function finalizar() {
            parselimit = 1;
        }

        function begintimer() {

            if (!document.images)
                return

            if (parselimit == 1) {
                //document.forms[0].submit();
                //window.location = "site de destino apos o tempo"
            } else {
                parselimit -= 1
                curmin = Math.floor(parselimit / 60)
                cursec = parselimit % 60
                if (curmin != 0) {
                    curtime = curmin + " minutos e " + cursec + " segundos para você sair dessa página"
                }
                else {
                    curtime = cursec + " Segundos regredindo....."
                    //window.status = curtime
                    clock1.innerHTML = cursec
                    setTimeout("begintimer()", 1000)
                }
            }
        }
</script>
<html>
<span id="clock1"></span>
</html>
Como é feito no código em javascript para escrever na tela? A pergunta é fácil e tranquila: na função inicio(), o objeto de tela chamado clock1 é zerado com o innerHTML. No código beginTimer(), esse mesmo objeto é escrito na tela de tempos em tempos. Nas últimas linhas você pode ver o código, antes do setTimeout(...).
O segundo passo é colocar a tela para atualizar a cada 30 segundos usando o Timer.
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
Não preciso explicar muito como usar o Timer, só vou dar os passos para usar.
Primeiro coloquei o registro na página do AjaxControlToolkit. Você pode pegar a DLL no site www.asp.net.
<asp:Timer ID="Timer1" runat="server" Enabled="false" Interval="30000"
ontick="Timer1_Tick">
</asp:Timer>
Depois de colocar o registro, carreguei o componente chamado Timer, que coloquei desabilitado e no intervalo de 30.000 milisegundos, que equivale a 30 segundos. Cliquei duas vezes no componente e gerou o onclick:
        protected void Timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                GerarRelatorio();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Depois disso, o timer está funcionando perfeitamente, e de 30 em 30 segundos o sistema gera o relatório passando pelo método Timer1_Tick. É lógico que precisa usar o UPDATEPANEL (não citado anterioremente).

Sempre visível

Para que o tempo rodando esteja sempre visível, é preciso usar o componente do Control Toolkit chamado AlwaysVisibleControlExtender.
 <cc1:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender1"
                runat="server" TargetControlID="pnlClock"
                VerticalOffset="1"
                VerticalSide="Bottom"
                HorizontalSide="Right"
                HorizontalOffset="70"
                ScrollEffectDuration=".1">
            </cc1:AlwaysVisibleControlExtender>

            <asp:Panel ID="pnlClock" runat="server" Visible="false">
                <table width="100px" border="1" cellpadding="0" cellspacing="0" style="background-color:White; border-color:Black;">
                    <tr>
                        <td>
                            <br />
                            <span id="clock1"></span>
                            <br /><br />
                        </td>
                    </tr>
                </table>
            </asp:Panel> 
Existem duas coisas importantes para se destacar no código acima.
A primeira é o uso e a configuração do componente AlwaysVisible... A segunda é a colocação de um Panel contendo o <span id="clock1"></span>. Ou seja, não é toda hora que ele vai ser visualizado de acordo com a regra de negócio.
O Panel é para ser usado no componente AlwaysVisibleControlExtender e, assim, manterá a contagem de tempo sempre visível na tela, não importando o objeto que esteja sendo visualizado no momento. 

O que falta?

Para terminar o que foi feito, falta sincronizar o JavaScript com o C#.NET, pois até agora o tempo está rodando na tela e o timer está rodando e contando no C#. Quando termina o tempo do Timer, é necessário atualizar na tela o contador JavaScript. Para isso, no início do artigo, coloquei os códigos inicio() e finalizar() timer.
Quando o contador terminar a contagem e for atualizar o relatório, o tempo que está rodando via JavaScript precisa ser atualizado. Dessa forma, fiz um método em que o C#.NET chama o código JavaScript:
 protected void finalizaTimerJavaScript(Page sender)
{

   string scriptjs = "finalizar();";

   ScriptManager.RegisterClientScriptBlock(sender, sender.GetType(), Guid.NewGuid().ToString(), scriptjs, true);
}




protected void inicioTimerJavaScript(Page sender)
{

    string scriptjs = "inicio();";

    ScriptManager.RegisterClientScriptBlock(sender, sender.GetType(), Guid.NewGuid().ToString(), scriptjs, true);
}
Esses dois métodos são específicos para chamar funções escritas em JavaScript pelo C#.NET.
Na hora de gerar o relatório, eu chamo o método inicioTimerJavaScript passando o parâmetro correto, que é a página. Veja o exemplo:
protected void cmdGerarRelatorio_Click(object sender, EventArgs e)

        {

            if (Page.IsValid)

            {

                try

                {

                    GerarRelatorio();

                    Timer1.Enabled = true;



                    pnlClock.Visible = true;

                    inicioTimerJavaScript(this.Page);

                }

                catch (Exception ex)

                {

                    throw ex;

                }

            }

        } 
Note que habilito o Timer1, mostro o painel Clock e inicio a contagem chamando o método inicioTimerJavaScript(this.Page). Automaticamente a página inicia o contador.
No caso de querer atualizar a página clicando em algum outro botão, ou recarregando a página, basta finalizar o tempo no javascript:
protected void cmbAgencia_SelectedIndexChanged(object sender, EventArgs e)

        {



            pnlClock.Visible = false;

            finalizaTimerJavaScript(this.Page);

        } 
Nesse caso, ao selecionar uma combo, automaticamente o clock sumirá e será finalizado o tempo javascript na tela.
Espero ter ajudado e qualquer dúvida pode entrar em contato.
Obrigado pelo seu comentário

Postagens Relacionadas

Related Posts Plugin for WordPress, Blogger...

Programador GB