Turbine a sua aplicação WEB com um calendário profissional

por Gabriel Pitágoras Silva e Brenner *

Para ler todas as matérias da FórumAccess, assine a revista no endereço http://www.forumaccess.com.br/novo/

Pré Requisitos

Este artigo usa as seguintes tecnologias:

  • Conhecimentos básicos de programação WEB, ASP.NET e Java Script

Visual Studio .NET 2002

 

 

Os melhores sites para reserva de passagens aéreas utilizam um calendário acoplado aos campos do tipo data, agilizando a entrada de dados do usuário. Neste artigo você aprenderá como equipar a sua aplicação WEB com este poderoso e útil recurso, parecido com o DateTimePicker do VB .NET. Este artigo utiliza JavaScript para as rotinas executadas diretamente no navegador e demonstra a criação de um CustomWebControl, tornando transparente a utilização do calendário para o desenvolvedor. Após ler o artigo, o leitor poderá utilizar o WebControlcriado em todas as aplicações que precisarem desse recurso e terá um conhecimento maior sobre as rotinas de Script necessárias para a criação do calendário e sobre a criação e utilização de CustomWebControls.

ESTRUTURANDO A APLICAÇÃO

O programa é separado em duas partes diferentes, porque parte dele será executado pelo navegador (código escrito em JavaScript) e a outra parte, que será executado no servidor, será escrita em VB.NET. As funções JavaScript estão separadas em dois arquivos:

JSCalendario.txt: Contém as funções JavaScript utilizadas para exibição e interação com o calendário e o código HTML de geração do mesmo. Através das funções escritas nesse arquivo é possível montar e navegar pelo calendário, assim como colocar a data selecionada de volta no controle desejado.

JSValidaDatas.txt: Contém as funções JavaScript para validação e digitação de datas diretamente no TextBox. Essas funções são utilizadas para evitar a digitação de valores indevidos, fazer uma prévalidação dos dados digitados diretamente no navegador e incluir as barras das datas automaticamente durante a digitação. O projeto possui outros dois arquivos, sendo que um contém o código da aplicação que rodará no servidor (TextBoxCalendar.vb) e o outro o ícone de exibição do controle criado (Icone.ico) quando o mesmo for adicionado na caixa de ferramentas de um outro projeto ASP.NET.

JSCALENDARIO

As funções presentes no arquivo JsCalendario.txt estão descritas na Tabela 1 e o código completo pode ser conferido no arquivo de exemplo disponível para download. A Lista 1 contém o código HTML que dá origem ao calendário e que será manipulado pelas rotinas JavaScript.

Tabela 1 – Funções JavaScript para manipulação do calendário
Cc580649.R63_CalendarioASPNET_img_1(pt-br,MSDN.10).jpg

Outros elementos importantes são os elementos HTML chamados calendario, month, year, days e dayList, que são manipulados pelo código JavaScript para que todas as operações de montagem do calendário sejam feitas no cliente, não havendo necessidade de consultar o servidor.

Lista 1–HTML da tabela do calendário presente no arquivo JsCalendario.txt

<TABLE bgColor=#ffffff border=1 cellPadding=0 cellSpacing=3 id=calendario style="DISPLAY:none;
POSITION:absolute;Z-INDEX:100">

<TBODY>

<TR>

<TD colSpan=7 vAlign=center>

<SELECT id=month onchange=MontaCalendario()>

<SCRIPT language=JavaScript>

for (var intLoop = 0; intLoop < meses.length; intLoop++)

document.write("<OPTION " + (today.month == intLoop ? "Selected" : "") + ">" + meses[intLoop]);

</SCRIPT>

</SELECT>

<!-- Year combo box -->

<SELECT id=year onchange=MontaCalendario()>

<SCRIPT language=JavaScript>

for (var intLoop = 1900; intLoop < 2028; intLoop++)

document.write("<OPTION " + (today.year == intLoop ? "Selected": "") + ">" + intLoop);

</SCRIPT>

</SELECT>

</TD>

</TR>

<TR class=days>

<SCRIPT language=JavaScript>

for (var intLoop = 0; intLoop < Dias.length; intLoop++)

document.write("<TD>" + Dias[intLoop] + "</TD>");

</SCRIPT>

</TR>

<TBODY class=dates id=dayList onclick="getDate(‘’)" vAlign=center>

<SCRIPT language=JavaScript>

for (var intWeeks = 0; intWeeks < 6; intWeeks++){

document.write("<TR>");

for (var intDays = 0; intDays < Dias.length; intDays++)

document.write("<TD></TD>");

document.write("</TR>");

}

</SCRIPT>

<TBODY>

<TR>

<TD class=today colSpan=5 id=todayday onclick=getTodayDay()></TD>

<TD align=right colSpan=2><A href="javascript:OcultaCalendario();">

<SPAN style="COLOR: black; FONT-SIZE: 10px"><B>Ocultar</B>

</SPAN></A></TD>

</TR>

</TBODY>

</TABLE>

O código HTML do calendário está no mesmo arquivo do script que o manipula e, como o script, é registrado uma única vez na página. Caso o leitor queira modificar o layout do calendário, basta mudar o HTML, tomando cuidado para não mudar a estrutura da Tabela nem os nomes de seus elementos, porque as rotinas manipulam diretamente tais elementos.

JSVALIDADATAS

As funções presentes no arquivo JsValidaDatas.txt estão descritas na Tabela 2 e o código completo delas está presente na Lista 2.

Tabela 2 – Funções de validação de datas presentes no arquivo JSValidaDatas.txt
Cc580649.R63_CalendarioASPNET_img_2(pt-br,MSDN.10).jpg

<Script language="JavaScript">

function digitaData(objeto){

if (objeto.value.length == 2 || objeto.value.length == 5)

objeto.value += "/";

if(isNaN(String.fromCharCode(window.event.keyCode)))

return false;

}

function isDate(strData){

var dia, mes, ano;

//critica valor de um campo de data

if(strData.length < 10) return false;

mes = strData.substr(3,2);

if(mes > "12" || mes == "00")

return false;

dia = strData.substr(0,2);

if(dia=="00") return false;

ano = strData.substr(6,4);

if (ano < "0200") return false;

if (mes=="01"||mes=="03"||mes=="05"||mes=="07"||mes=="08"||mes=="10"||mes=="12"){

if (dia > "31")

return false;

}

if(mes=="04"||mes=="06"||mes=="09"||mes=="11"){

if (dia > "30")

return false;

}

if(mes=="02"){

if((parseInt(ano) % 4) ==0){

if (dia > "29")

return false;

}

else

if (dia > "28") return false;

}

return true;

}

function CriticaData(objeto){

if (objeto.value=="") return true;

var resultado=isDate(objeto.value);

if (resultado==false) {

alert("A data digitada não é válida, por favor con.ra a digitação !!!");

objeto.focus();

return false;

}

return true;

}

</script>

CRIANDO O CUSTOMWEBCONTROL

Em posse das funções de validação das datas e de montagem e utilização do calendário, torna-se simples a tarefa de criação do CustomWebControl que fará uso das mesmas. Para criar o CustomWebControl, siga os passos a seguir:

  1. Abra o Visual Studio .Net;

  2. Crie um novo projeto WebControlLibrary chamado TextBoxCalendar;

  3. Renomeie a classe WebCustomControl1.vb para TextBoxCalendar.vb;

  4. Ao abrir o código da classe, renomeie em todos os locais o texto WebCustomControl1 por TextBoxCalendar;

  5. Modifique a herança de System.Web.Ui.WebControls.WebControl para System.Web.UI.WebControls.TextBox;

  6. Apague todo o código criado por default no controle para não haver conflito com o código interno da classe TextBox;

  7. Crie os arquivos JSCalendario.txt e JSValidaDatas.txt e coloque o código já apresentado no artigo dentro deles;

  8. Para que esses arquivos passem a ser parte integrante do componente quando compilados, não havendo assim a necessidade de transportá-los, modifique a propriedade Build Action para Embedded Resource.

Após esses passos, falta codificar o arquivo TextBoxCalendar.vb para que as funções contidas nos arquivos JSCalendario.txt e JSValidaDa-tas.txt sejam retornadas junto com o HTML da página e suas funções associadas ao controle que será instanciado (TextBox). O Código da classe TextBoxCalendar.vb está ilustrado na Lista 3.

Public Enum Posicao

Abaixo = 0

ADireita = 1

Acima = 2

End Enum

Private lPosicao As Posicao = Posicao.Abaixo

Public Property PosicaoCalendario() As Posicao

Get

PosicaoCalendario = lPosicao

End Get

Set(ByVal Value As Posicao)

lPosicao = Value

End Set

End Property

Private Sub TextBoxCalendar_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles 
MyBase.PreRender

Dim s As System.IO.Stream = System.Re.ection.Assembly.GetExecutingAssembly().GetManifestResourceStream
("TextBoxCalendar.JSCalendario.txt")

Dim sr As New System.IO.StreamReader(s)

Dim str As String = sr.ReadToEnd()

s = System.Re.ection.Assembly.GetExecutingAssembly().GetManifestResourceStream
("TextBoxCalendar.JSValidaDatas.txt")

sr = New System.IO.StreamReader(s)

Dim str1 As String = sr.ReadToEnd

If Not Me.Page.IsClientScriptBlockRegistered("scrCalendar") Then

Me.Page.RegisterClientScriptBlock("scrCalendar", str)

Me.Page.RegisterClientScriptBlock("scrValidaDatas", str1)

End If

sender.attributes.add("onclick", "Calendario(this.name," & lPosicao & ","& 
sender.Width.ToString.Replace("px", "") & "," & sender.height.ToString.Replace("px", "") & ")")

sender.attributes.add("onkeypress", "return digitaData(this)")

sender.attributes.add("onblur", "CriticaData(this)")

End Sub 

O Enumerador Posicao foicriado para dar ao usuário a possibilidade de posicionar o calendário acima, a direita ou abaixo do controle, possibilitando formatar melhor sua página e posicionar o calendário da maneira mais agradável em relação ao layout. A propriedade PosicaoControle será exibida na Properties Window quando uma aplicação web estiver utilizando esse componente, permitindo para o desenvolvedor alterar a posição do controle de forma muito simples. O método Pre_Render é utilizado, porque ele é executado antes da TextBox ser “desenhada” no navegador, possibilitando que se inclua propriedades na tag HTML que será gerada na execução da página aspx. Quando mudamos a propriedade Build Action e determinamos que os arquivos farão parte da dll, é necessário buscar esse recurso dentro do projeto e, para ler seu conteúdo, a rotina faz uso do código ...

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream (“TextBoxCalendar.JSCalendario.txt”) 

... que retorna o conteúdo do arquivo JSCalendario.txt (agora contido dentro do projeto) em forma de um Stream. Para utilizar as funções de leitura dos arquivos de recurso, é necessário fazer referência com o Imports às bibliotecas System.Resources e System.Reflection. Após ter o conteúdo do arquivo em uma Stream, basta colocá-lo dentro de uma variáveldo tipo String e escrevê-lo na página. Antes de escrevêlo, é necessário ter a preocupação de não colocar código JavaScript repetido na página, e para que isso não aconteça, a rotina faz uso da função IsClientScriptBlockRegistered que retorna True caso já tenha sido registrado aquele bloco de script, não permitindo com isso um registro duplicado, possibilitando haver vários controles que utilizem as mesmas funções JavaScript que estarão presentes uma única vez na página. Após essa verificação, os dois blocos de script são registrados na página com o método RegisterClientScriptBlock. Apesar das funções estarem registradas na página, ainda não há a associação das mesmas com o controle que será renderizado, então é necessário atribuir a cada função os respectivos eventos de script do controle. Paraisso, são adicionados à coleção de atributos do controle os eventos click, onkeypress e onblur, contendo respectivamente o código de abertura ou fechamento do calendário, digitação de datas e validação da data ao sair do controle.

ADICIONANDO UM ÍCONE AO CUSTOMWEBCONTROL

Após criar o CustomWebControl, pode-se associar ele a umícone para melhor identificá-lo na caixa de ferramentas do desenvolvedor. Para isso, adicione um ícone ao projeto, mude a propriedade Build Action para Embedded Resource e seu nome para Icone.ico. A propriedade Build Action é modificada para que o ícone passe a fazer parte integrante da dll, assim como foi feito com os outros dois arquivos. Faça referência com o Imports, dentro do arquivo TextBoxCalendar.vb a biblioteca System.Drawing. Depois disto, basta adicionar à tag, antes da declaração da classe, a função ToolBoxBitmap carregando o ícone.

<DefaultProperty("Text"), ToolboxBitmap(GetType(TextBoxCalendar), "ICONE.ICO"), ToolboxData("<{0}:TextBoxCalendar 
runat=server></{0}:TextBoxCalendar>")> Public Class TextBoxCalendar

Inherits System.Web.UI.WebControls.TextBox

Ao compilar o projeto será gerada a dll do controle TextBoxCalendar que poderá ser utilizada em qualquer aplicação ASP.NETindependente da linguagem em que esteja sendo construída.

USANDO O CONTROLE CRIADO EM UMA APLICAÇÃO ASP.NET

Para utilizar o componente criado,inicie uma novainstância do VS.NET e crie uma nova aplicação ASP.NET. Para utilizar o controle é necessário fazer referência a ele e colocá-lo na Toolbox. Para isso, clique com o botão direito sobre a pasta References na janela Project Explorer e, no menu que abrir, selecione a opção Add Reference conforme ilustrado na Figura 1.

Cc580649.R63_CalendarioASPNET_img_6(pt-br,MSDN.10).jpg
Figura 1 - Adicionando referência ao Custom Web Control criado

Você verá a janela Add Reference. Clique no botão Browse... da guia .NET e selecione a dllcriada na compilação do CustomWebControl, que normalmente estará na pasta bin, logo abaixo da pasta da aplicação. Após adicionar a referência, clique com o botão direito naToolbox e, no menu que abrir, clique na opção CustomizeToolbox. Na janela que abrir, clique no botão Browse... da guia .NET Framework Components e selecione novamente a dll criada. Aparecerá naToolbox uma nova opção com o ícone escolhido para a aplicação, conforme ilustrado na Figura 2.

Cc580649.R63_CalendarioASPNET_img_8(pt-br,MSDN.10).jpg
Figura 2 – CustomWebControl criado colocado na Toolbox

Após adicionar o controle à Toolbox, basta utilizá-lo normalmente, como se fosse uma TextBox. Inclua-o em uma página ASP.NET e selecione na propriedade PosicaoCalendario em qual posição deseja que o calendário apareça. O resultado será similar ao ilustrado na Figura 3, que ilustra as três possíveis posições do calendário.

Cc580649.R63_CalendarioASPNET_img_7(pt-br,MSDN.10).jpg
Figura 3 – Posições do calendário em relação ao TextBox, definida na propriedade PosicaoCalendario do CustomWebControl

ADICIONANDO A FUNCIONALIDADE DE CALENDÁRIO A PÁGINAS ASP

Para utilizar as funções do calendário e de validação de datas em ASP, basta que os dois arquivos que contêm as funções escritas em JavaScript, sejam transformados em Includes e que nas páginas .asp, queirão gerar o retorno HTML, haja referência a tais arquivos. A tabela que está dentro do arquivo JSCalendario precisa estar dentro das páginas asp e as tags precisam ser removidas do script. Após as referências e as modificações efetivadas, basta incluir os eventos de scripts a um controle do tipo Text, conforme idéia ilustrada na Lista 5 e o controle funcionará de forma idêntica ao TextBoxCalendar apresentado no artigo.

<head>

<title>Utilizando o Calendário em aSP</title>

</head>

<body>

<script language="JavaScript" src="JSCalendario.js">

</script>

<script language="JavaScript" src="JSValidaDatas.js">

</script>

CONCLUSÃO

O artigo apresentou para o leitor um controle que adiciona a funcionalidade de calendário a um TextBox, tornando seu funcionamento mais agradável. Além de utilizar o controle trabalhado no artigo, o leitor pode, através das idéias apresentadas, desenvolver novos componentes que tenham o mesmo objetivo, que é o de facilitar a interação do usuário com as telas de um sistema Web e agilizar o desenvolvimento de sistemas. Espero mais uma vez ter abordado um assunto relevante profissionalmente para o leitor. Um forte abraço e até o próximo artigo.

Matérias Relacionadas

Revista 60 - Criando um Custom Web Control com máscaras
Revista 61 - Utilizando JavaScript no ASP .NET

* Gabriel Pitágoras S. Brenner (gabrielbrenner@inb.gov.br) é Bacharel em Sistemas de Informação, desenvolvedor pelas Indústrias Nucleares do Brasil S/A (http://www.inb.gov.br) e professor titular do curso de graduação em Sistemas de Informação da Faculdade de Ciências Econômicas, Administrativas e da Computação Dom Bosco (http://www.aedb.br).

Mostrar: