Sencha Touch 2: Exemplo Página de Login
Oi Pessoal,
Recebi alguns pedidos e sugestões de post para o blog que é fazer uma página de Login com Sencha Touch 2. E aqui estou escrevendo um post sobre isso! :)
Hoje então vou mostrar passo a passo como fazer uma página bem simples de login com Sencha Touch - para caso alguém queira usar de base. Não vou falar sobre autenticação, pois senão já entra em um assunto muito amplo e que vai depender da tecnologia usada no server side. Também não vou explicar muito a fundo, pois todos os conceitos abordei nos cursos de Ext JS 4 e Sencha Touch 2, então espero que tenha um conhecimento básico de certas coisas! :)
PS.: para quem já usa o Sencha Architect 3, deixo a dica que o SA3 já vem com um template para Login. O que vou mostrar hoje é um pouco diferente! :)
Views
O projeto consiste em 3 views: a página de login, uma página principal que está vazia (e é onde seria colocado o conteúdo da app) com um botão de logout, e um Viewport que vai ter a página de login e a página principal fazendo o wrapper da app.
Página de Login
A página de Login é apenas um Form Panel com os campos de usuário e senha, conforme screenshot abaixo:
Note que nas linhas 15 - 21 também temos uma Label hidden que é para mostrar alguma mensagem de erro como usuário e senha inválidos ou algo parecido.
E nas linhas 51 - 55 temos uma função que é para setar a mensagem de erro na Label que descrevemos acima.
Ext.define('MyApp.view.Login', {
extend: 'Ext.form.Panel',
alias: 'widget.loginform',
config: {
padding: '10px',
styleHtmlContent: true,
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'Login'
},
{
xtype: 'label',
hidden: true,
hideAnimation: 'fadeOut',
html: 'Por favor, entre com as credenciais corretas',
itemId: 'failmsg',
showAnimation: 'fadeIn',
style: 'color: #990000; margin:5px 0px;'
},
{
xtype: 'fieldset',
title: 'Login',
items: [
{
xtype: 'textfield',
itemId: 'user',
required: true,
placeHolder: 'usuário'
},
{
xtype: 'passwordfield',
itemId: 'pass',
required: true,
placeHolder: 'senha'
}
]
},
{
xtype: 'button',
itemId: 'loginbtn',
padding: '10px',
ui: 'action-round',
text: 'Entrar'
}
]
},
showSignInFailedMessage: function(message) {
var label = this.down('#failmsg');
label.setHtml(message);
label.show();
}
});Página Principal
A página Principal está vazia, mas seria aqui que colocaríamos o conteúdo da app. A página consiste de um Panel com uma Toolbar que contém um botão de Logout.
E apenas para não fica vazia, deixei um HTML bem basicão só para dizer que o usuário está logado! :)
A Página Principal fica assim:
E o código:
Ext.define('MyApp.view.Main', {
extend: 'Ext.Panel',
alias: 'widget.mainpanel',
config: {
html: 'Você está logado!',
styleHtmlContent: true,
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'Minha App',
layout: {
pack: 'end',
type: 'hbox'
},
items: [
{
xtype: 'button',
itemId: 'logoutbtn',
text: 'Logout'
}
]
}
]
}
});Viewport
O Viewport é apenas um container que irá juntar as duas views que já criamos e será o reponsável pela navegação da app. Para isso, vou usar o Card Layout, assim apenas uma view fica visível por vez.
No Card Layout, a primeira view é a view ativa por padrão, então quando o usuário carregar a app, a página de login será a view exibida e a view Main ficará escondida (só para o exemplo viu, isso não é coisa que se deva fazer em app que vai para produção :) ).
Ext.define('MyApp.view.MyViewport', {
extend: 'Ext.Container',
alias: 'widget.myviewport',
requires: [
'MyApp.view.Login',
'MyApp.view.Main'
],
config: {
layout: {
type: 'card'
},
items: [
{
xtype: 'loginform'
},
{
xtype: 'mainpanel'
}
]
}
});Controller
Ah, o Controller é aquele cara que vai ficar escutando os eventos disparados pelos componentes (views). Para esse exemplo estamos interessados em escutar dois eventos: quando o usuário fazer um tap no botão de Login ou quando fazer um tap no botão de logout (lembrando que o tap seria o click de apps desktop).
Código:
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginForm: {
selector: 'loginform',
xtype: 'Ext.form.Panel'
},
myViewport: {
selector: 'myviewport',
xtype: 'Ext.Container'
},
mainPanel: {
selector: 'mainpanel',
xtype: 'Ext.Panel'
}
},
control: {
"loginform #loginbtn": {
tap: 'onLogInButtonTap'
},
"mainpanel #logoutbtn": {
tap: 'onLogOutButtonTap'
}
}
},
onLogInButtonTap: function(button, e, eOpts) {
var form = button.up('loginform'),
user = form.down('#user'),
pass = form.down('#pass'),
label = form.down('#failmsg'),
me = this;
label.hide();
var userName = user.getValue(),
password = pass.getValue();
var task = Ext.create('Ext.util.DelayedTask', function () {
label.setHtml('');
me.onSignInCommand(form, userName, password);
user.setValue('');
pass.setValue('');
});
task.delay(500);
},
onLogOutButtonTap: function(button, e, eOpts) {
var me = this,
login = me.getLoginForm(),
myViewport = me.getMyViewport();
myViewport.animateActiveItem(login, {type: 'slide', direction: 'right'});
},
onSignInCommand: function(login, username, password) {
var me = this;
if (username.length === 0 || password.length === 0) {
login.showSignInFailedMessage('Por favor, informe seu usuário e senha.');
return;
}
login.setMasked({
xtype: 'loadmask',
message: 'Signing In...'
});
if (username.length > 0 || password.length > 0) {
me.signInSuccess();
}
},
signInSuccess: function() {
var me = this,
login = me.getLoginForm(),
mainPanel = me.getMainPanel(),
myViewport = me.getMyViewport();
login.setMasked(false);
myViewport.animateActiveItem(mainPanel, {type: 'slide', direction: 'left'});
}
});Vamos lá!
Linhas 5 - 17 : temos as refs, que são apelidos criados para nos ajudar a referenciar esses componentes no nosso código. Essas refs são similar a usar Ext.ComponentQuery.query('selector')[0]. Por isso precisamos ter certeza de ter apenas 1 instância desses componentes no nosso código. Como selector usei o próprio alias de cada view.
Linhas 21 - 27 : aqui estamos escutando os eventos tap dos botões login e logout. Usei o itemId dos botões e para diminuir o escopo de busca do Sencha Touch, declarei também o componente (xtype/alias) que contém esses botões.
Linhas 30 - 50 : essa é a função que é executada quando o usuário faz um tap no botão Login. A idéia geral é verificar se o usuário e senha foram digitados pelo usuário (não estão vazios - pelo menos 1 char).
- Linha 31 - obter a referência do Form
- Linha 32 - com a referência do Form, pegamos a referência do campo Usuário
- Linha 33 - com a referência do Form, pegamos a referência do campo Senha
- Linha 34 - com a referência do Form, pegamos a referência da label para caso exista necessidade de exibir uma mensagem de erro
- Linha 37 - escondemos da Label de erro - caso já tenha acontecido um erro em outra ocasião
- Linhas 39 e 40 - obtemos o valor inputado de usuário e senha
- Linhas 42 - apenas para fazer um charme, na hora de fazer o login temos um pequeno delay
- Linha 49 - instanciamos o delay
- Linhas 43, 45 e 46 - limpamos os campos de usuário e senha, e a label de erro
- Linha 44 - chamada da função onSignInCommand passando o Form, e campos de usuário e senha como parâmetros
Linhas 60 - 76 : função que apenas valida se usuário e senha são válidos. Não estou fazendo nenhum verificação com o server, mas seria aqui que enviaria para o server para verificar as credenciais.
- Linha 63 a 66: se usuário e senha estão em branco, atualizados a mensagem de erro e mostramos na tela e também saímos da função terminando a execução.
- Linhas 68 a 71 - apenas uma graça mascarando a tela de login
- Linhas 73 a 75 - Se usuário e senha não estão vazios, faz o login chamando a função signInSuccess
Linhas 78 - 86 : apenas troca a view ativa do Viewport pela View Main.
- Linha 80 - obtém a referência do Form (poderíamos ter passado como parâmetro através da função anterior também)
- Linha 81 - obtém a referência da View da página principal
- Linha 82 - obtém a referência do Viewport
- Linha 84 - remove a máscara que adicionamos nas linhas 68 a 71
- Linha 85 - apenas troca a view ativa do ViewPort para a view principal fazendo uma animação para ficar bonitinho! :)
Linhas 52 - 58 : função que faz logout. Apenas coloca a view Login como view ativa do Viewport.
Download Código
O código está disponível no github: https://github.com/loiane/sencha-touch2-examples-architect/tree/master/SenchaTouchLogin
Até a próxima! :)



