AJAX com ASP.Net - Criando uma aplicação em poucos minutos

Walter Amorim (e-mail) é programador em ASP.net e VB.net desde 2003. Atualmente trabalha como Programador Web na agência AM4, em Barra Mansa/RJ. É cursando de Engenharia da Computação do Centro Universitário de Barra Mansa, unidade Cicuta (UBM-Cicuta).

Olá pessoal! Neste artigo iremos abordar de forma prática um assunto muito na moda. Trata-se do AJAX. O AJAX (Asynchronous Javascript and XML) é uma metodologia antiga para acesso assíncrono a páginas Web. Ele já vem sendo utilizado arduamente há anos por programadores ASP, PHP e etc, utilizando uma mistura de JavaScript e XML.

Tentarei mostrar como ASP.Net simplifica (e muito) a implementação de AJAX em suas páginas.

Simplificando, as linguagens de programação Web (como ASP, PHP e até mesmo ASP.net) são processadas no servidor. Isso significa que cada vez que o usuário clica em um botão, a página é enviada de volta ao servidor, e recarregada. A utilização do AJAX permite que esse processamento seja assíncrono, evitando que a página seja recarregada, dando ao usuário uma sensação muito mais confortável. É uma ferramenta maravilhosa, quando bem utilizada.

O exemplo mais bem sucedido que conheço da utilização de AJAX é o Gmail. Quando você navega pelo Gmail, as páginas não são diretamente carregadas. Ao invés disso, é mostrada uma mensagem na lateral superior direita, informando que a página está sendo carregada e enquanto isso podemos continuar a usá-la.

image001.jpg

Vamos criar uma aplicação bem simples, para inclusão, exclusão e acesso à dados de uma Lista Telefônica, com nome, cidade, e-mail e telefone. Um exemplo simples, pra que você entenda o funcionamento do Ajax.

Antes de começar, veja aqui o exemplo rodando e baixe aqui o código completo.

Irei utilizar a biblioteca MagicAjax, que, na minha opinião, é a mais fácil de usar, e é OpenSource. Você pode baixá-la em http://www.magicajax.net. Usarei o Visual Web Developer 2005 (.Net 2.0), mas nada impede que você codifique manualmente.

1 – Configurando o MagicAjax em nossa aplicação

Pois bem. Baixe o MagicAjax e copie para a pasta de sua aplicação as pastas “bin” e “core”. Na pasta bin está o arquivo MagicAjax.dll, a biblioteca que usaremos para construir nossa aplicação, e na pasta core estão os scripts usados pelo MagicAjax.

Primeiramente, temos que definir em nossa aplicação que iremos utilizar a biblioteca do MagicAjax. Isso é feito através de algumas linhas de código no Web.config.

Então, crie um arquivo chamado Web.config e neste arquivo, digite o código abaixo:

<?xml version="1.0"?>
<configuration>
       <configSections>
             <section name="magicAjax" type="MagicAjax.Configuration.MagicAjaxSectionHandler, MagicAjax"/>
       </configSections>
       <magicAjax scriptPath="~/Core/Script" outputCompareMode="HashCode" tracing="false">
             <pageStore mode="NoStore" unloadStoredPage="false" cacheTimeout="5" maxConcurrentPages="5" maxPagesLimitAlert="false"/>
       </magicAjax>
       <system.web>
             <httpModules><add name="MagicAjax" type="MagicAjax.MagicAjaxModule, MagicAjax"/>
             </httpModules>
             <customErrors mode="Off"></customErrors></system.web></configuration>

2 – Criando o arquivo de dados

Agora, crie o arquivo XML/XSD que irá conter nossos dados, chamado “dados.xml”. Iremos usar os dados provenientes desse arquivo. Nada impede que você use um banco de dados. No arquivo dados.xml, copie o texto abaixo:

<?xml version="1.0" standalone="yes"?>
<Content xmlns="http://tempuri.org/Content.xsd">
  <xs:schema id="Content" targetNamespace="http://tempuri.org/Content.xsd" xmlns:mstns="http://tempuri.org/Content.xsd" xmlns="http://tempuri.org/Content.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
    <xs:element name="Content" msdata:IsDataSet="true" msdata:Locale="en-US">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Lista">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="ID" msdata:ReadOnly="true" msdata:AutoIncrement="true" type="xs:short" />
                <xs:element name="nome" type="xs:string" minOccurs="0" default=""/>
                <xs:element name="cidade" type="xs:string" minOccurs="0" default=""/>
                <xs:element name="email" type="xs:string" minOccurs="0" default=""/>
                <xs:element name="telefone" type="xs:string" minOccurs="0" default=""/>               
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <Lista>
    <ID>1</ID>
    <nome>Walter V. S. de Amorim</nome>
    <cidade>Barra Mansa/RJ</cidade>
    <email>nao.faca.spam@walteram.com.br</email>
    <telefone>(24)9999-0000</telefone>
  </Lista>
  <Lista>
    <ID>2</ID>
    <nome>Fulano</nome>
    <cidade>Volta Redonda/RJ</cidade>
    <email>teste@teste.com</email>
    <telefone>(21)9990-0123</telefone>
  </Lista>  
</Content>

Os detalhes do arquivo XML não são importantes. São apenas os dados usados por nossa aplicação.

3 – Exibindo os dados

Agora crie um arquivo chamado “default.aspx”. Essa página irá exibir os dados provenientes do arquivo XML criado, através de um DataGrid, e nos permitirá filtrar os itens.

No arquivo, copie o código abaixo:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="MagicAjax" Namespace="MagicAjax.UI.Controls" TagPrefix="ajax" %>
<script runat="server">
    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not Page.IsPostBack Then CarregarDados()
    End Sub
   
    Private Sub CarregarDados()
        'Cria um dataset, e lê os dados do arquivo dados.xml.
        'Você poderia também carregar de um banco de dados, da
        'mesma forma como está acostumado.
        Dim ds As New DataSet
        ds.ReadXml(Server.MapPath("dados.xml"), XmlReadMode.ReadSchema)        
        'Filtra os dados, se houver algum texto no campo de filtro.

        ds.Tables(0).DefaultView.Ro                        

wFilter = "nome like '%" & txtFiltrar.Text & "%' or cidade like '%" & txtFiltrar.Text & "%'"
        dg.DataSource = ds.Tables(0)
        dg.DataBind()       
    End Sub
   
    Private Sub dg_Command(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
        If e.CommandName.ToLower = "excluir" Then

            'Rotina responsável por excluir um ítem       
            'Pega o código do ítem

            Dim IDItem As Long = e.Item.Cells(0).Text.ToString
            'Cria um dataset, lê os dados e acha o ítem a apagar
            Dim ds As New DataSet
            ds.ReadXml(Server.MapPath("dados.xml"), XmlReadMode.ReadSchema)
            ds.Tables(0).DefaultView.RowFilter = "ID=" & IDItem
            'Se achar o ítem, apaga
            If ds.Tables(0).DefaultView.Count > 0 Then ds.Tables(0).DefaultView.Delete(0)
            'Salva o dataset no arquivo
            ds.WriteXml(Server.MapPath("dados.xml"), XmlWriteMode.WriteSchema)
            'Carrega os dados
            CarregarDados()
        ElseIf e.CommandName.ToLower = "detalhes" Then
            'Abre os detalhes do ítem escolhido
            Dim IDItem As Long = e.Item.Cells(0).Text.ToString
            MagicAjax.AjaxCallHelper.Redirect("editar.aspx?id=" & IDItem)
        End If
    End Sub

 

    Protected Sub CapturarTecla_KeyUp(ByVal sender As Object, ByVal e As MagicAjax.UI.Controls.KeyEventArgs)
        'Toda vez que uma tecla for pressionada, em qualquer controle
        'dentro deste container, este evento será carregado.
        CarregarDados()
    End Sub
</script>

 

<html>
<head runat="server"><title>Mostrando os Dados</title>
</head>
<body>
    <form id="form1" runat="server">
        <ajax:AjaxPanel ID="AjaxPanel1" runat="server">
            <!--Tudo que estiver dentro do controle AjaxPanel
                irá funcionar com os recursos do MagicAjax.-->

            <ajax:KeyClientEventWrapper ID="CapturarTecla" runat="server" OnKeyUp="CapturarTecla_KeyUp">
                <!--Dentro do AjaxPanel temos um KeyClientEventWrapper
                    que irá capturar todas as teclas digitadas.-->

                Filtrar:
                <asp:TextBox ID="txtFiltrar" runat="server"></asp:TextBox>
            </ajax:KeyClientEventWrapper>
            <!--Dentro do AjaxPanel temos também um DataGrid, que irá exibir os dados -->
            <asp:DataGrid ID="dg" runat="server" Width="520px" AutoGenerateColumns="False" OnItemCommand="dg_Command">
                <Columns>
                    <asp:BoundColumn DataField="Id" HeaderText="Cód." />
                    <asp:BoundColumn DataField="nome" HeaderText="Nome" />
                    <asp:BoundColumn DataField="cidade" HeaderText="Cidade" />                   
                    <asp:ButtonColumn ButtonType="LinkButton" Text="Ver + " CommandName="Detalhes" />
                    <asp:ButtonColumn ButtonType="LinkButton" Text="Excluir" CommandName="Excluir" />
                </Columns>
            </asp:DataGrid>
            <br />
     <a href="adicionar.aspx">
         Para Adicionar um ítem, clique aqui.
     </a>
        </ajax:AjaxPanel>       
    </form></body></html>

Salve a página e execute-a. Você verá o seguinte:

image002.gif

Tente digitar algum texto no campo “Filtrar”. Você verá que os dados serão filtrados sem recarregar a página.

Observe também que quando você faz o filtro, ou exclui um item, aparece um pequeno quadro com o texto “Loading”, no canto superior direito, bem parecido com o que acontece com o Gmail:

image003.gif

Mais à frente, você verá como alterar o texto “Loading”.

O código da página, como você pode ver, não tem nada de incrível, à não ser por dois pequenos trechos. O primeiro, no início da página, é:

<%@ Register Assembly="MagicAjax" Namespace="MagicAjax.UI.Controls" TagPrefix="AJAX" %>

Nesta linha registramos os controles do MagicAjax. Assim podemos usar todos os recursos dessa biblioteca.

Um outro trecho importante:

<AJAX:AjaxPanel ID="AjaxPanel1" runat="server">
  <AJAX:KeyClientEventWrapper ID="CapturarTecla" runat="server" OnKeyUp="CapturarTecla_KeyUp">
Filtrar: <asp:TextBox ID="txtFiltrar" runat="server"></asp:TextBox>
  </AJAX:KeyClientEventWrapper>
  <asp:DataGrid ID="dg" runat="server" Width="520px" AutoGenerateColumns="False" OnItemCommand= "dg_Command">
       ...
  </asp:DataGrid>
</AJAX:AjaxPanel>

Neste trecho, utilizamos o AjaxPanel para controlar os eventos de nossa aplicação. Tudo que estiver dentro desse controle irá atuar sobre as regras do MagicAjax. E tudo que estiver fora do AjaxPanel, irá atuar da forma normal.

Dentro desse controle está o KeyClientEventWrapper. Este outro controle, que também vêm com a biblioteca MagicAjax, é responsável por capturar as teclas digitadas. Dentro dele temos um TextBox comum. Quando uma tecla é digitada neste TextBox, o KeyClientEventWrapper chama a função CapturarTecla_KeyUp, que carrega os dados novamente.

Dentro do AjaxPanel está também o DataGrid, que exibe os dados e permite-nos excluir um item. O DataGrid tem ainda um link para editar os dados. Essa será a próxima etapa.

Em nosso caso, usamos os controles AjaxPanel e KeyClientEventWrapper. Sugiro que você consulte a documentação do MagicAjax (disponível no download) que contém uma explicação geral de cada controle disponível na biblioteca.

Você pode ver que é bem simples implementar o AJAX em suas páginas. Tudo que tem que fazer é colocar seus controles dentro da tag AjaxPanel.

4 – Alterando os Dados da Lista Telefônica

A próxima etapa em nosso exemplo é criar a página que irá nos possibilitar a edição dos dados. Nesta, como você verá, não há nada de extraordinário.

Crie uma página chamada “editar.aspx”, e nela cole o código abaixo.

<%@ Page Language="VB" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="MagicAjax" Namespace="MagicAjax.UI.Controls" TagPrefix="ajax" %>

<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        'Carrega os dados do arquivo
        If Not Page.IsPostBack Then
            'Cria um dataset, e lê os dados do arquivo dados.xml.
            Dim Codigo As Long = Request.QueryString("id")
            Dim ds As New DataSet, dr As DataRow
            ds.ReadXml(Server.MapPath("dados.xml"), XmlReadMode.ReadSchema)
            'Filtra os dados
            ds.Tables(0).DefaultView.RowFilter = "id =" & Codigo.ToString
            'Se achar o item, coloca nos textboxes
            If ds.Tables(0).DefaultView.Count > 0 Then
                dr = ds.Tables(0).DefaultView.ToTable.Rows(0)
                lblCodigo.Text = dr.Item("id")
                txtNome.Text = dr.Item("nome")
                txtCidade.Text = dr.Item("cidade")
                txtEmail.Text = dr.Item("email")
                txtTelefone.Text = dr.Item("telefone")
            End If
        End If
    End Sub
   
    Protected Sub cmdSalvar_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        'Salva os dados no arquivo
        Dim Codigo As Long = Request.QueryString("id")
        Dim ds As New DataSet
        ds.ReadXml(Server.MapPath("dados.xml"), XmlReadMode.ReadSchema)
        For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
            If ds.Tables(0).Rows(i).Item("id") = Codigo Then
                ds.Tables(0).Rows(i).Item("nome") = txtNome.Text.ToString
                ds.Tables(0).Rows(i).Item("cidade") = txtCidade.Text.ToString
                ds.Tables(0).Rows(i).Item("email") = txtEmail.Text.ToString
                ds.Tables(0).Rows(i).Item("telefone") = txtTelefone.Text.ToString
                ds.WriteXml(Server.MapPath("dados.xml"), XmlWriteMode.WriteSchema)
                Exit For
            End If
        Next
        'Redireciona para a página de exibição.
        'Note que usamos a função redirect própria do MagicAjax.
        'Você pode usar o habitual Response.Redirect
        MagicAjax.AjaxCallHelper.Redirect("default.aspx")
    End Sub

    Protected Sub cmdCancelar_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        'Ao cancelar, simplesmente redireciona para a página de exibição.
        MagicAjax.AjaxCallHelper.Redirect("default.aspx")
    End Sub
</script>

<html>
<head runat="server"><title>Editando os Dados</title></head>
<body>
    <form id="form1" runat="server">
        <table>
            <tr>
                <td>Código:</td>
                <td><asp:Label ID="lblCodigo" runat="server"></asp:Label></td>
            </tr>
            <tr><td>Nome:</td>
                <td><asp:TextBox ID="txtNome" runat="server" Width="245px" /></td>
            </tr>
            <tr><td>Cidade:</td>
                <td><asp:TextBox ID="txtCidade" runat="server" /></td>
            </tr>
            <tr><td>E-mail:</td>
                <td><asp:TextBox ID="txtEmail" runat="server" /></td>
            </tr>
            <tr><td>Telefone:</td>
                <td><asp:TextBox ID="txtTelefone" runat="server" Width="80px" /></td>
            </tr>
            <tr><td></td>
                <td>
                    <ajax:AjaxPanel ID="AjaxPanel1" runat="server">
                        <asp:Button ID="cmdSalvar" runat="server" OnClick="cmdSalvar_Click" Text="Salvar" />
                        <asp:Button ID="cmdCancelar" runat="server" Text="Cancelar" OnClick="cmdCancelar_Click" />
                    </ajax:AjaxPanel>                                           
                </td>                   
            </tr>
        </table>
    </form></body></html>

Novamente, utilizamos o AjaxPanel. Mas, desta vez, apenas nos botões Salvar e Cancelar.

Você deve ter notado que utilizamos a função MagicAjax.AjaxCallHelper.Redirect. Esta função atua de forma quase que idêntica ao Response.Redirect, mas utiliza Ajax. A biblioteca MagicAjax possui diversas funções interessantes, como essa.

5 – Adicionando Dados à Lista

A última etapa em nossa pequena aplicação é criar a página onde poderemos adicionar dados.
Então, crie uma página chamada “adicionar.aspx” e cole o código abaixo:

<%@ Page Language="VB" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="MagicAjax" Namespace="MagicAjax.UI.Controls" TagPrefix="ajax" %>

<script runat="server">
    Protected Sub cmdSalvar_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        'Salva os dados no arquivo
        Dim ds As New DataSet, dr As DataRow
        ds.ReadXml(Server.MapPath("dados.xml"), XmlReadMode.ReadSchema)
        dr = ds.Tables(0).NewRow
        dr.Item("nome") = txtNome.Text.ToString
        dr.Item("cidade") = txtCidade.Text.ToString
        dr.Item("email") = txtEmail.Text.ToString
        dr.Item("telefone") = txtTelefone.Text.ToString
        ds.Tables(0).Rows.Add(dr)
        ds.WriteXml(Server.MapPath("dados.xml"), XmlWriteMode.WriteSchema)
        'Redireciona para a página de exibição.
        'Note que usamos a função redirect própria do MagicAjax.
        'Você pode usar o habitual Response.Redirect
        MagicAjax.AjaxCallHelper.Redirect("default.aspx")
    End Sub

    Protected Sub cmdCancelar_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        'Ao cancelar, simplesmente redireciona para a página de exibição.
        MagicAjax.AjaxCallHelper.Redirect("default.aspx")
    End Sub
</script>

<html>
<head runat="server">
    <title>Adicionando Dados</title>
</head>
<body>
    <form id="form1" runat="server">
        <table>
            <tr><td>Nome:</td>
                <td><asp:TextBox ID="txtNome" runat="server" Width="245px" /></td>
            </tr>
            <tr><td>Cidade:</td>
                <td><asp:TextBox ID="txtCidade" runat="server" /></td>
            </tr>
            <tr><td>E-mail:</td>
                <td><asp:TextBox ID="txtEmail" runat="server" /></td>
            </tr>
            <tr><td>Telefone:</td>
                <td><asp:TextBox ID="txtTelefone" runat="server" Width="80px" /></td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <ajax:AjaxPanel ID="AjaxPanel1" runat="server">
                        <asp:Button ID="cmdSalvar" runat="server" OnClick="cmdSalvar_Click" Text="Salvar" />
                        <asp:Button ID="cmdCancelar" runat="server" Text="Cancelar" OnClick="cmdCancelar_Click" />
                    </ajax:AjaxPanel>                                           
                </td>                   
            </tr>
        </table>
    </form>
</body>
</html>

6 – Alterando o texto “Loading”

Conforme prometi, irei mostrar como alterar o texto “Loading”. Pois bem. Abra o arquivo “AjaxCallObject.js” (dentro da pasta core/script). Lá no final do arquivo (+- linha 1051), você verá o código:

function CreateWaitElement() {
    var elem = document.getElementById('__AjaxCall_Wait');
    if (!elem) {
        elem = document.createElement("div");
        elem.id = '__AjaxCall_Wait';
        elem.style.position = 'absolute';
        elem.style.height = 17;
        elem.style.paddingLeft = "3px";
        elem.style.paddingRight = "3px";
        elem.style.fontSize = "11px";
        elem.style.fontFamily = 'Arial, Verdana, Tahoma';
        elem.style.border = "#000000 1px solid";
        elem.style.backgroundColor = "DimGray";
        elem.style.color = "#ffffff";
        elem.innerHTML = 'Loading ...';
        elem.style.visibility = 'hidden';
        document.body.insertBefore(elem, document.body.firstChild);
    }
    waitElement = elem;
}
// end wait element

Altere o texto (por exemplo, para ‘Aguarde...’). Você pode também definir a cor de fundo, altura, borda, e etc.
Quando terminar, salve o arquivo e execute novamente.  Pronto:

image004.jpg

7 - Concluindo

É isso aí. Agora você está pronto pra começar a desenvolver suas próprias aplicações em Ajax.
Como você viu, tudo que tem de fazer é definir o Web.Config, registrar o MagicAjax no topo das páginas que for usar, e colocar os seus controles dentro do AjaxPanel. Simples, não?!

Nos próximos artigos irei me aprofundar mais nesse assunto tão importante. E por hoje é só. Não deixe de baixar o exemplo e brincar um pouco. E em caso de dúvidas, mande um e-mail.

Um Abraço!