Desenvolvimento de Aplicações Web Ricas (RIA) com Ext JS 4 e Rails 3

O Ext JS é um framework escrito com a linguagem de scripts JavaScript focada para o desenvolvimento de RIA (Rich Internet Application) ou Aplicações de Internet com interfaces Ricas.

Originalmente foi criado por Jack Slocum e começou como uma extensão do Yahoo! User Interface. Teve o apoio da comunidade no desenvolvimento e na versão 2.0 começou a ter duas licenças: a paga e a open source.

A versão open source é distribuída através da licença GPLv3 (General Public Licence) ou também conhecida como licença GNU, ou seja, a licença open source é válida apenas se a sua aplicação também for licenciada sobre os termos da GNU.

Atualmente o framework está na versão 4.1 e é distribuído pela Sencha Inc, uma companhia localizada na Califórnia, Estados Unidos. Segundo dados da própria Sencha, a comunidade de desenvolvedores ao redor do mundo do Ext JS é superior a um milhão de pessoas!

O Ext JS é um framework cross-browser (roda até no Internet Explorer 6!) exclusivo para o desenvolvimento do client-side (lado cliente), ou seja, o lado servidor (server-side) pode ser desenvolvido em qualquer linguagem de programação para a internet. Isso inclui por exemplo, PHP, Python, Java, ASP.Net, etc. Para o desenvolvimento neste artigo, irei optar pelo framework de desenvolvimento web Ruby on Rails 3. No entanto, se desejar, você pode portar o código do lado do servidor que utilizaremos para a sua linguagem preferida livremente, já que o foco é introduzirmos ao Ext JS 4.

Instalação do Ruby e do Rails

Na plataforma Windows, a forma mais simples de instalar o Ruby, é baixar o pacote one-click installer, disponível no link: http://rubyforge.org/frs/download.php/72075/rubyinstaller-1.9.1-p430.exe. A instalação é simplesmente o “famoso” Next, Next, Finish.

Se você estiver utilizando o Linux, nas distribuições Debian ou Ubuntu, basta utilizar o gerenciador de pacotes:

sudo apt-get install ruby irb rdoc

Para instalar o framework Rails no Windows, abra o prompt de comando e digite:

gem install rails

No Linux, abra o terminal e informe:

sudo gem install rails

Para certificar-se que tudo está rodando corretamente, ainda no prompt de comando ou no terminal, digite:

rails –v

Será exibida a versão instalada do Rails. Dessa forma, seja bem vindo ao Rails!

Download do Ext JS

O download do Ext JS 4 deve ser efetuado a partir do endereço http://cdn.sencha.io/ext-4.1.0-gpl.zip.

Observe que será salvo um arquivo compactado chamado ext-4.1.0-gpl.zip, que é a versão que utilizaremos para a confecção do nosso exemplo.

Interface de Login

A aplicação que será desenvolvida neste artigo, será uma interface de login, conforme imagem a seguir:

RIA: ecrã de login

Nela, entre as diversas configurações, iremos definir por exemplo, a obrigatoriedade dos atributos, o tamanho mínimo de cada e habilitaremos o botão login somente quando os dois campos forem corretamente informados.

Abra o seu terminal ou prompt de comando, crie uma pasta para armazenar o nosso projeto, (eu sugiro projetos) e digite:

rails new portugal-a-programar
cd portugal-a-programar
rails g scaffold user login:string
                   password:string
rake db:migrate
rails s

Abra o seu navegador preferido e aponte para: http://localhost:3000/users. Observe que em apenas cinco linhas, já criamos um pequeno registo de utilizadores com o CRUD (Create, Read, Update e Delete) completo!

RIA: página com lista de utilizadores

Agora que o nosso registo de utilizadores já está correndo, vamos criar a interface de login no Ext JS. Para isso, descompacte o arquivo ext-4.1.0-gpl.zip no diretório portugal-a-programar\public\ext-4.

Aponte o navegador para http://localhost:3000/ext-4/index.html e terá acesso à tela inicial do Ext JS, com acesso a ótima documentação e exemplos.

RIA: página inicial do Ext JS

O primeiro passo será substituir todo o código da página index.html do nosso projeto dentro do diretório portugal-a-programar\public, pelo código a seguir:

<html>
  <head>
    <meta http-equiv="Content-Type"
          content="text/html; charset=utf-8" />
    <title>Projeto Exemplo Ext JS - P@P </title>
    <link rel="stylesheet" type="text/css"
          href="ext-4/resources/css/ext-all.css">
    <style type="text/css">
      body {background-color: #DFE8F6;}
    </style>
    <script type="text/javascript"
            src="ext-4/bootstrap.js"></script>
    <script type="text/javascript"
            src="login.js"></script>
  </head>
  <body>
  </body>
</html>

Na criação dessa página HTML, observe que estamos a efetuar uma chamada à folha de estilos CSS padrão do framework chamada ext-all.css, estamos também a chamar o framework através do arquivo bootstrap.js e na linha relativa ao login.js iremos chamar o arquivo JavaScript que será criado por nós.

O código do arquivo login.js que deverá ser salvo em portugal-a-programar\public está reproduzido a seguir:

ExtJS.onReady(function () {
  Ext.QuickTips.init();
  function doLogin() {
    if (camposlogin.getForm().isValid()) {    
      camposlogin.getForm().submit( {
        method: 'POST',
        waitTitle: 'Aguarde enquanto o login é efetuado...',
        waitMsg: 'Verificando informações...',
        success: function () {
          camposlogin.getForm().reset();
          var redirect = "principal.html";
          window.location = redirect;
        },
        failure: function (form, action) {
          if (action.failureType == 'server') {
            obj = Ext.decode(action.response.responseText);
            Ext.Msg.show( {
              title: 'Falha no login!',
              msg: obj.errors.reason,
              buttons: Ext.Msg.OK,
              icon: Ext.MessageBox.ERROR,
              scope: this,
              width: 150
            });
          } else {
            Ext.Msg.alert('Atenção', 'Não foi possível validar o login: '
                + action.response.responseText);
          }
          camposlogin.getForm().reset();
        }
      });
    }
  };
  var camposlogin = Ext.create('Ext.form.Panel', {
    labelWidth: 50,
    url: '/login',
    frame: true,
    defaultType: 'textfield',
    monitorValid: true,
    items: [ {
      fieldLabel: 'Login',
      name: 'login',
      emptyText: 'Informe o seu login',
      blankText: 'Informe o seu login',
      minLength: 3,
      minLengthText: 'O campo login deve ter no mínimo 3 caracteres',
      inputType: 'textfield',
      allowBlank: false,
      anchor: '90%'
    }, {
      fieldLabel: 'Palavra-Passe',
      name: 'password',
      blankText: 'Informe a sua palavra-passe',
      inputType: 'password',
      allowBlank: false,
      anchor: '90%'
    } ], 
    buttons: [ { 
      text: '<b>Login</b>',
      formBind: true,
      handler: doLogin
    }, {
      text: 'Limpar',
      scope: this,
      handler: function () { camposlogin.getForm().reset(); }
    }] 
  }); 
  var win = Ext.create('Ext.window.Window', {
    layout: 'fit',
    title: 'Login no Sistema',
    width: 300,
    height: 150,
    closable: false,
    resizable: false,
    draggable: false,
    plain: true,
    border: false,
    items: [camposlogin]
  }); 
  win.show();
});

Na criação da janela de login, possuímos algumas opções de como se ela pode ser fechada (closable: false), se pode ser redimensionada (resizable: false), ou ainda se pode ser arrastada (draggable: false).

Observe também que estamos verificando se o formulário foi validado, ou seja, se os campos login e palavra-passe foram informados. No campo login iremos obrigar também o tamanho mínimo de 3 caracteres através da propriedade minLength. Caso o formulário esteja validado, (isValid()) encaminharemos ao servidor a requisição via o método POST do protocolo HTTP para uma URL chamada /login. O servidor web retornará um arquivo no formato JSON (JavaScript Object Notation) com a propriedade :success como true ou false.

Caso o utilizador informado seja válido ("success":true), a aplicação tentará carregar uma página chamada principal.html, onde poderia estar, por exemplo, o menu principal da nossa aplicação. Caso o utilizador não exista na base de dados ("success":false), será exibida uma mensagem de erro, conforme imagem a seguir:

RIA: mensagem erro

Para que o Rails reconheça a rota /login, necessitaremos editar o arquivo portugal-a-programar\config\routes.rb, inserindo a linha a seguir, logo após a linha PortugalAProgramar::Application.routes.draw do match 'login' => "users#login".

Nessa linha, estamos a redirecionar a aplicação para o método login do controller Users. (O Rails utiliza o padrão de desenvolvimento MVCModel View Controller.)

Para implementar o método login no controller User, edite o arquivo portugal-a-programar\app\controllers\users_controller.rb, adicionando o método login, logo após a definição da classe, conforme o código a seguir:

class UsersController < ApplicationController
def login
  if params[:login].nil? || params [:password].nil? 
    render :json => {
      :success => false,
      :errors => {:reason => "Informe o login e a palavra-passe do utilizador!" }
    }
  else 
    dados = User.find(
      :first,
      :conditions => [" login = ? and password = ?", params[:login],params[:password]]
    )
    if dados
      #definimos um cookie
      cookies[:utilizador_id] = dados.id
      render :json => { :success => true }
    else
      render :json => {
        :success => false,
        :errors => { :reason => "Erro ao validar o login e palavra-passe informados!" }}
    end
  end
end 
#mantenha o código já existente...

O método login basicamente irá receber dois parâmetros chamados login e password que foram definidos através do name no arquivo login.js. Caso um dos parâmetros esteja vazio (nil), será retornado um JSON com success:false e a respectiva mensagem de erro.

Se os dois parâmetros forem passados, iremos verificar se o utilizador existe no banco de dados através do método find na classe User e armazenaremos em um array chamado dados, armazenando também um cookie com o ID do utilizador logado, retornando logo em seguida a propriedade true para a chave success.

Para realizar os testes, aponte o seu navegador para http://localhost:3000/users, cadastre um ou mais utilizadores e em seguida aponte o navegador para http://localhost:3000 e informe um login e palavra-chave válidos e um login e palavra-chave inválidos.

Caso o utilizador exista na base de dados, a aplicação emitirá um erro, informando que não foi possível localizar o arquivo principal.html, no qual poderemos abordar a criação de um menu num próximo artigo.

Note que por questões didáticas não foi implementado o método de criptografia da palavra-chave.

Conclusão

O framework client-side Ext JS 4 integrado ao framework server-side Ruby on Rails mostram uma alternativa bastante produtiva para o desenvolvimento de aplicações ricas. Validações como campos obrigatórios, tamanho mínimo do campo ou se a janela pode ser fechada ou arrastada são facilmente configuradas através de propriedades no código JavaScript.

Para saber o que cada propriedade faz, sugiro consultar a ótima documentação disponível em http://docs.sencha.com/ext-js/4-1/.

Bibliografia

  1. GRONER, Loiane. Ext JS 4 First Look. Birmingham, Uk: Packt Publishing, 2012. p. 340.
  2. LEME, Ricardo. Desenvolvendo aplicações web com Ruby on Rails 2.3 e PostgreSQL. Rio de Janeiro: Brasport, 2009. p. 198.

Publicado na edição 35 (PDF) da Revista PROGRAMAR.