ExtJS 3.0 – Formulário com ComboBox e mensagens de validação

Este artigo tem a intenção de mostrar um formulário feito com ExtJS com as seguintes características:

  • Possui um ComboBox que busca seus valores em uma página PHP e possui autocomplete dos valores possíveis.
  • Envia os dados por AJAX.
  • Apresenta para cada campo, mensagens sobre a validação server-side dos dados enviados.

A motivação em escrever este pequeno artigo está no fato de que eu enfrentei dificuldades para conseguir compor um formulário com essas características, embora seja algo simples. Por isso, quero compartilhar esse conhecimento adquirido com muitas horas de estudo e pesquisa, para que outros programadores não sofram tanto quanto eu.

A didática deste artigo será a seguinte:

Vou apresentar o código de cada arquivo com comentários sobre cada parte relevante.

Quero também ressaltar que os arquivos PHP contém código apenas para fornecer os dados necessários para este artigo, portanto, tem validade didática também.

O primeiro arquivo é dados_login.php, que nada mais faz do que fornecer uma saída JSON com os valores que irão aparecer no ComboBox.

<?php
//Este é um array que contém uma string JSON com os valores dos campos id e sistema. No caso são 3 valores.
$json = '{
	rows: [[
		{id: "1", sistema: "Contabilidade"}
		,{id: "2", sistema: "Tesouraria"}
		,{id: "3", sistema: "Compras"}
	]]
}';
echo $json; //Aqui imprimimos a string JSON para o retorno ao Ext.
?>

Em seguida, temos o arquivo do formulário propriamente dito: login.php. Este arquivo contém as inclusões das bibliotecas e CSS do Ext, bem como o código do formulário (preferi colocá-lo dentro do arquivo principal, ao invés de fazer um arquivo separado).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Formulário de login</title>
	<link rel="stylesheet" href="ext-3.0.0/resources/css/ext-all.css"/>
	<!-- GC -->
	<!-- LIBS -->
	<script type="text/javascript" src="ext-3.0.0/adapter/ext/ext-base.js"></script>
	<!-- ENDLIBS -->
	<script type="text/javascript" src="ext-3.0.0/ext-all.js"></script>
	<script type="text/javascript" src="crb-config.js"></script>
	//Início do nosso script
	<script type="text/javascript">
	Ext.onReady(function(){ //Inicia o script assim que todo o documento estiver carregado

		//Inicia a exibição de mensagens
		Ext.QuickTips.init();

		//Configura o local onde as mesnagens serão exibidas
		Ext.form.Field.prototype.msgTarget = "under";

		//Inicia a recuperação dos dados sobre os sistemas
		var store = new Ext.data.JsonStore({
			url: 'dados_login.php', //caminho da página que fornecerá os dados para o ComboBox
			root: 'rows', //Indica qual a "raiz" que contém os dados
			fields: [['id', 'sistema']] //Indica os campos dos dados
		});
		store.load();//Carrega os dados

		//Formulário de login
		var formLogin = new Ext.FormPanel({
			renderTo: 'container1' //Indica onde o formulário será renderizado
			,frame: true//Bordas arredondadas
			,title: 'Entrar no sistema'
			,bodyStyle: 'padding: 20px 20px 20px 20px'
			,buttonAlign: 'right'
			,width: 400
			,height: 250
			,waitMsgTarget: true //Exibe mensagem ao submeter o formulário
			,buttons: [[ //Configuração dos botões do formulário
				new Ext.Button({	//Botão de limpar o formulário
					icon: 'ext-3.0.0/resources/images/default/menu/unchecked.gif'
					,iconAlign: 'left'
					,text: 'Limpar'
					,tooltip: 'Limpar dados digitados'
					,type: 'reset'
					,handler: function(){
						formLogin.getForm().reset();
					}
				})
				,new Ext.Button({ //Botão de enviar o formulário
					icon: 'ext-3.0.0/resources/images/default/menu/checked.gif'
					,iconAlign: 'left'
					,text: 'Entrar'
					,tooltip: 'Entrar no sistema selecionado'
					,type: 'submit'
					//Função para envio dos dados
					,handler: function(){
						formLogin.getForm().submit({
							url:'logar.php' //Endereço do arquivo que receberá os dados
							,method: 'POST'
							,waitMsg:'Por favor, aguarde...'
							,success: function(){
								Ext.Msg.alert('Status','Login com sucesso');
							}
						});
					}
				})
			]]
			,items: [[
				new Ext.form.ComboBox({ //Nosso ComboBox
					name: 'sistema' //Nome do campo
					,fieldLabel: 'Sistemas'
					,mode: 'local' //Indica que o campo será preenchido com os dados ao carregar o formulário.
					,displayField: 'sistema' //Indica qual campo será mostrado no ComboBox
					,valueField: 'id' //especifica qual o campo que terá seu valor submetido
					,hiddenName: 'id' //especifica um nome de campo que será enviado com o valor em valueField
					,store: store//Os dados para preencher o ComboBox
					,labelSeparator: ':'
					,width: 200
					,emptyText: 'Selecione ou digite o sistema'
					,forceSelection: true //Permite que somente os dados existentes no campo seja utilizados
					,typeAhead: true //Preenche o campo com sugestões ao digitar
				})
				,new Ext.form.TextField({ //Campo de texto para usuário
					name: 'usuario'
					,fieldLabel: 'Usuário'
					,width: 200
					,emptyText: 'Informe seu nome de usuário'
				})
				,new Ext.form.TextField({ //Campo de texto para senha
					name: 'senha'
					,fieldLabel: 'Senha'
					,width: 200
					,inputType: 'password'
				})
			]]
		});

		//Posiciona o formulário no centro da tela
		var container1  = document.getElementById('container1');
		container1.style.height = formLogin.height + 'px';
		container1.style.width = formLogin.width + 'px';
		var spaceup = (screen.height - container1.style.height.replace('px',''))/4;
		var spaceleft = (screen.width - container1.style.width.replace('px',''))/2;
		container1.style.marginTop = spaceup + 'px';
		container1.style.marginLeft = spaceleft + 'px';
	});
</script>
</head>
<body>
	<div></div>
</body>
</html>

Por fim, o arquivo logar.php é que faz a validação dos dados e informa se houve sucesso ou falha, neste caso informando os campos e os erros.

<?php
   //Uma pequena configuração dos dados válidos
   $u = 'root';
   $s = '123';
   $sis = '1';
   $sistema = $_POST[['id']];
   $usuario = $_POST[['usuario']];
   $senha = $_POST[['senha']];
   
   //Verifica se os dados enviados correspondem aos dados válidos, senão, indica o erro
   
   if($usuario != $u){
   	$errors[['usuario']] = 'usuário não confere';
	   $result = false;
   }
   if($senha != $s){
   	$errors[['senha']] = 'senha não confere';
	   $result = false;
   }
   
   //Observe que na validação a seguir, o erro deve ser informado<br />com o campo id, o mesmo informado no valor hiddenName, ou <br />não será exibida a mensagem de erro para o ComboBox
   if($sistema != $sis){
   	$errors[['id']] = 'sistema não confere';
	   $result = false;
   }else{
	   $result = true;
   }
   if($result){
	   $o = array("success"=>true);
   }else{
	   $o = array('success'=>false,'errors'=>$errors);
   }
   
   //Retorno dos dados à página principal
   header("Content-Type: application/json");
   echo json_encode($o);
?>

O funcionamento deste código é o seguinte:

O usuário pode digitar o nome do sistema desejado (verifique o autocomplete do ComboBox) ou selecioná-lo na lista apresentada, informar um nome de usuário e uma senha. Se os dados conferem com os dados válidos, é exibida uma mensagem de sucesso, senão, são exibidas mensagens de erro abaixo dos campos com problemas.

Espero que este pequeno artigo ajude àqueles que desejam trabalhar com ExtJS.

Um especial agradecimento à comunidade brasileira dos utilizadores do ExtJS e ao siteSaki’s Ext Examples.

Nós queremos saber sua opinião aqui