Seções iMasters
.NET + Ajax + C# + JavaScript + Visual Studio

Contagem regressiva com C# e JavaScript

Olá, pessoal, gostaria de mostrar hoje como desenvolver de forma dinâmica 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 a cada 30 segundos atualizasse automaticamente depois de clicar no botão para gerar. Até aí é tranqüilo, pois é necessário usar o Timer e o GridView.

Só que era necessário mostrar os segundos na tela ao usuário. Isto é, os segundos decrescentes (30, 29, 28, 27) devem ser mostrados na tela acima de todos os objetos. 

Para facilitar o artigo, vou mostrar algumas telas com o resultado do que foi desenvolvido. Veja a tela 01:

Na figura acima, uma tela de gráfico é mostrada, com os segundos no canto direito sendo diminuído. A contagem de segundos começou em 30.

Esses segundos devem ficar em cima e toda a tela, nunca atrás de algum componente de tela. Na próxima imagem, a tela subiu e os segundos continuam regredindo e acima do gráfico:

A partir de agora, 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 resposta é fácil e tranqüila: 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 de 30 em 30 segundos usando o Timer.

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

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, coloquei desabilitado e no intervalo de 30.000 milisegundos, que equivale 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 usar o UPDATEPANEL (não citado anterioremente).

Sempre visível

Para manter o tempo rodando sempre visível, precisei 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 mantém sempre visível na tela, não importando o objeto que esteja nela. e não importe o objeto que seja nela.

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 o contador JavaScript na tela . 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, preciso que seja atualizado o tempo que está rodando via JavaScript, dessa forma fiz um método 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);
}

Estes 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 um 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. 

Se você quiser 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);
}

Neste 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.

Comente também

8 Comentários

Que tal colocar link para uma página de exemplo ? O artigo está bem explicado mas sem um link de exemplo obriga o desenvolvedor a construir uma página só pra ver o resultado final. Não, os prints iniciais não ajudam muito.

Anyway, parabéns por mais um artigo…

Mauricio Junior

Olá Michel, pode deixar que vou postar aqui uma página de exemplo.

Realmente muito bom esse artigo. Eu estava a algum tempo procurando algo do tipo e isso vai me ajudar e muito. Parabéns! Agora é esperar pela página com o exemplo rodando. Abs!

E a página de exemplo virou lenda !!!

Kleber

Uai, o artigo sumiu?

    Rina Noronha

    Olá, já entramos em contato com o autor para corrigir o problema. Em breve o artigo estará aqui novamente, na íntegra.

Alex Tzimisce

IH! Cadê o artigo?

    Rina Noronha

    Olá, já entramos em contato com o autor para corrigir o problema. Em breve o artigo estará aqui novamente, na íntegra.

Qual a sua opinião?