Série AngularJS: Validando Formulário

angularjslogoA

Olá Pessoal,

Hoje vamos ver como customizar mensagens de validação em um formulário com AngularJS. Será uma simples validação. Para algo mais específico precisamos criar diretivas. Por exemplo, validar se o username é unico. Tem que criar uma diretiva que faça essa validação para poder exibir uma mensagem no formulário. Não vamos entrar nesse cenário aqui, pois já seria um novo post.

Lets go…

Github

O exemplo vai estar no projeto receipeangularexample no meu github

https://github.com/camilolopes/workspaceAngularJs
Development

Vou assumir que você já tem a configuração básica do AngularJS. Para o exemplo usarei rotas/deep linking para acessar o conteúdo.

Step 1 – Configurando a rota

when("/validationform", {
templateUrl : "formvalidation.html",
controller : recipeController}).

//restante do code omitido

 

Step 2 – Criando uma função no Controller

Vamos criar uma função bem simples no controller

var recipeController = function($scope, UserService) {
//codo omitted

$scope.send = function($scope){
alert("send");

}

};

 

Step 3 – Criando o formulário

Agora vem o nosso formulário. Veja:

<form name="mainForm" ng-submit="send()">
<div>
<label>Nome</label>
<input type="text" ng-model="user.name" name="username" required/>
<span ng-class="error" ng-show="mainForm.username.$error.required">Nome é obrigatório</span>
</div>
<div>
<label>email</label>
<input type="email" ng-model="user.email" name="useremail" required/>
<span ng-class="error" ng-show="mainForm.useremail.$error.required">Email é obrigatório</span>
<span ng-class="error" ng-show="mainForm.useremail.$error.email"> Formato do e-mail é inválido</span>
</div>
<div>
<label>Idade</label>
<input type="number" ng-model="user.age" name="userage" required ng-maxlength=2 ng-minlength=1>
<span ng-class="error" ng-show="mainForm.userage.$error.maxlength">Não é permitido mais que 2 digitos</span>
</div>
<div>
<label>Blog/Site</label>
<input type="url" ng-model="user.site" name="usersite" ng-maxlength=30>
<!-- the message only show when the form is validated-->
<div ng-show="mainForm.usersite.$dirty && mainForm.usersite.$invalid">
<span ng-class="error" ng-show="mainForm.usersite.$error.url">Url inválida</span>
</div>
</div>
<div>
<input type="submit" ng-disabled="mainForm.$invalid">
</div>
</form>

Entendendo o Código

Claro que precisamos entender o que o código faz. Focarei apenas no que é importante, ou seja, não preciso explicar o que um atributo required no campo input faz.

Primeiro ponto

Ter um nome para o formulário, sem um nome nada adianta entender o restante do código. É através dele que vamos acessar os campos.

<form name="mainForm" ng-submit="send()">

bloco nome

<div>
<label>Nome</label>
<input type="text" ng-model="user.name" name="username" required/>
<span ng-class="error" ng-show="mainForm.username.$error.required">Nome é obrigatório</span>
</div>

No campo input temos que dar um name para o nosso campo e estamos dizendo que ele é required e qual mensagem deve ser exiba. Se não fizermos isso será a mensagem default HTML 5. Na linha span estamos dizendo: “exiba esta mensagem se o campo username for inválido”, ou seja, se não tiver nada digitado vai exibir essa mensagem por padrão, como vimos na imagem anterior.
bloco email

<div>
<label>email</label>
<input type="email" ng-model="user.email" name="useremail" required/>
<span ng-class="error" ng-show="mainForm.useremail.$error.required">Email é obrigatório</span>
<span ng-class="error" ng-show="mainForm.useremail.$error.email"> Formato do e-mail é inválido</span>
</div>

 

Fizemos a mesma coisa do campo nome, a diferença é que aqui temos um campo do tipo email que valida o formato do e-mail, se este for inválido exibe a mensagem que colocamos na validação

<span ng-class="error" ng-show="mainForm.useremail.$error.email"> Formato do e-mail é inválido</span>

 

O objeto $error que estamos usando contém todas as validações para um específico formulário, que no nosso caso chama-se mainForm.

Lembrando que a estrutura é nomeDoForm.nomePropriedade.$error.attributo ou nomeDoForm.expression.

Para o bloco idade nada de diferente, então nem preciso explicar.

Bloco Site

Aqui estamos validando a url e para isso temos o type url ja no HTML 5.Mas, observe a diferença que a mensagem somente é exiba quando o campo é modificado, ela não aparece quando a página é carregada, como fizemos nos outros campos, isso devido a essa linha aqui:

<div ng-show="mainForm.usersite.$dirty && mainForm.usersite.$invalid">

 

Ela está dizendo: “se o campo usersite for modificado e inválido, exiba o conteudo desse bloco” que no nosso caso temos a mensagem “Url inválida.

$dirty retorna true se o campo foi modificado

Bloco botão submit

<div>
<input type="submit" ng-disabled="mainForm.$invalid">
</div>

 

E para garantir que o usuario nao vai submeter o form, vamos desabilitar o botão submit se o formulário é invalido, ou seja, se todos os requisitos não são atendidos esse botão fica disabled

Testando

angularformvalidationempty

 
angularformvalidationinvalid
Por hoje é isso, vou ficando por aqui e espero que tenham gostado do post.

abracos, see ya!!

Série AngularJS: Advanced Form

olá Pessoal,

No post de hoje vamos ver como brincar um pouco mais com AngularJS e formulário. Com AngularJS tudo é mais simples e tudo que já faziamos pré mundo AngularJS funciona com muita naturalidade. Os exemplos mostrados aqui estão no meu Github no repositório do workspaceAngularJS o arquivo com o exemplo é o advancedform.html

lets go…

Usando checkbox

Está precisando um checkbox para o seu formulário? É bem simples. Veja o código a seguir:

Opção 1

<div>
<label>Role</label>
<!-- the value for user.admin is set to true if checkbox is checked -->
<input type="checkbox" ng-model="user.admin">
{{user.admin}}
</div>

 

Opção 2

<div>
<label>User Role</label>
<!-- the value is admin for object user.role when the checkbox is checked"-->
<input type="checkbox" ng-model="user.role" ng-true-value="admin" ng-false-value="user">
{{user.role}}
</div>

 

Na opção 1 quando checked o valor do bind para o nosso objeto será um boolean. Já na opção dois queremos gravar uma string.

advancedformcheckbox
Criando um radio input

Para criar um radio, é bem simples também, nada de especial o próprio explica tudo:

<label>
<input type="radio" ng-model="user.sex" value="M"> Masculino
</label>
<label>
<input type="radio" ng-model="user.sex" value="F">Feminino
</label>

 

advancedformradio

Quando clicado o valor que passamos para o objeto é M ou F.

Criando um Simples SelectOne

Vamos ver como fazer um selectone com String:

<!-- Select input with String -->
<label>Sexo:
<select ng-model="sex">
<option value="M" ng-selected="sex=='M'">Masculino</option>
<option value="F" ng-selected="sex=='F'">Feminino</option>
</select>
Escolhida foi:{{sex}}
</label>

 

Observe que estamos passando string para o value o ng-selected sendo tratado como String. O resultado é conforme a seguir :

advancedformselect
Agora se queremos que não seja uma string e objetos ou melhor uma lista ? Dai temos que usar o ng-options ao invés do ng-selected, vamos ver:

<!-- select input with object -->
<label>Country
<select ng-model="countrySelected" ng-options="country.name for country in countries">
</select>
{{countrySelected}}
</label>

 

O ng-options é bem simples, informamos qual atributo queremos exibir de cada item do array. No controller criei um array assim:

$scope.countries = [
{name:'Brazil'},
{name:'Australia'},
{name:'Canadá'}
]

 

advancedformngoptions

 

advancedformngoptionselected

Observe que o select fica vazio quando carregado, vamos colocar uma mensagem, então dentro de <select /> coloque:

<option value="">--No Selection--</option>

 

advancedformnoselect

Mostrando validações de erros no form

Vamos dizer que queremos validar um campo, quando o usuário digitar. Podemos fazer isso facilmente. Antes disso é preciso entender apenas um conceito importante que temos no Angular que é o ngModelController.

O ngModelControler é responsável por gerenciar o data binding entre o valor passado com o model (ng-model). E assim ele faz o track com a view se é valido ou não, e se o input tem sido modificado. No exemplo a seguir vamos validar um campo e-mail, veja o código:

<form name="userInfoForm">
<!-- call my function and field will be validated-->
<div class="control-group" ng-class="getCssClasses(userInfoForm.email)">
<label>E-mail</label>
<!-- we must inform name for field -->
<input type="email" ng-model="user.email" name="email" required>
<!-- will be show only if the format is invalid-->
<span ng-show="showError(userInfoForm.email, 'email')">
E-mail format is inválid. 
</span>
<span ng-show="showError(userInfoForm.email,'required')">
E-mail is required
</span>
</div>
</form>

 

Observe que no ng-show passamos o campo e o tipo de validação. Agora no controller vamos criar a função que faz o tratamento :

//check if field passed is valid or invalid 
$scope.getCssClasses = function(ngModelController){
return{
error:ngModelController.$invalid && ngModelController.$dirty,
success:ngModelController.$valid && ngModelController.$dirty
};
};
$scope.showError = function(ngModelController,error){
return ngModelController.$error[error];
};

O resultado será conforme a seguir:

advancedformshowvalidationemail

Informando que o campo é requerido. Agora vamos ver quando o formato do e-mail for inválido:

 

advancedformshowvalidationformat

E quando for válido:

advancedformshowvalidationvalid

E para finalizar vamos aprender a reusuar componentes de formulário em outro, ou seja, composite. É bem simples.

Primeiro Passo é criar o formulario que será reutilizado usando ng-template assim:

 

<!--creating composite reusable components-->
<script type="text/ng-template" id="password-form">
<label>Password</label>
<input ng-model="user.password" type="password" required>
</script>

 

Passo 2

É criar o formulario normal e adicionar o composite:

<!--using composite -->
<form name="form1" novalidate>
<legend>User</legend>
<label>username</label>
<input ng-model="user.username" required>
<ng-include src="'password-form'"></ng-include>
</form>

 

Observe que apenas damos um nome para o nosso composite e no ng-include, chamamos ele.
O resultado:

advancedformnginclude

Exemplo Live

http://plnkr.co/edit/fW44yi
E por hoje é isso, eu espero que tenham gostado das dicas do post.
Vou ficando por aqui.

See ya!!

Usando Yoeman com AngularJS

yeoman

Olá Pessoal,

No post de hoje vamos ver como usar o Yeoman com AngularJS.  Eu falei sobre o Yeoman rapidamente nesse post.

Lets go…

Step 1

Para o ambiente Windows, você pode ter o Gitbash instalado com suporte a execução de comando linux/unix. Instale também o NodeJS.

 Step 2

Agora abra o Gitbash e digite o comando

npm install -g yo

 

yoemaninstall

Ao terminar

 yoemanfinishedinstall

Step 3

Para ter suporte à criação de projetos com o angular, precisamos instalar o generator para o framework.

npm install -g generator-angular

yoemaninstallangular

Crie uma pasta algo como yeomandemo. Entre nela e digite

 yo

 

Responda Y

E escolha a opção:

yo angular

 

E vá respondendo às perguntas.

 yoemanangularsetup

Pronto, seu projeto foi criado. Para entender a estrutura há um post completo: http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/

 No meu github coloquei um exemplo do projeto demo que fiz com yoeman gerando o projeto com angular https://github.com/camilolopes/workspaceAngularJs

 Abraços. See ya!!!

Série AngularJS: Criando blackList com angular-ui validate

Olá Pessoal,

O objetivo do post de hoje é mostrar um pouquinho do que temos no angular-ui.  E para isso vou mostrar um recurso de ui-validate que permite validar se o valor recebido está em um Blacklist ou não.

Lets go…

Starting…

O angular-ui é uma suíte baseado no angularJS com vários componentes UI implementados. Tem coisas bem bacanas e é um projeto que é tão novo quanto o angularJS. Ainda acho o angular-ui um pouco bagunçado e tem poucas informações de como getstarted por exemplo para pegar o .js, não está em um local simples, tem bastante coisa separado. O ideal era oferecerem .js de maneira mais simples e fácil de achar no site.

O código é bem simples, apenas um input e o nome do usuário. Se ele digita alguma palavra que esteja no blacklist, o botão de submit não é habilitado.

Metendo a mão na massa

Vou considerar que você já vem acompanhando a série do angularJS e tem as configurações básicas. Não seria legal repetir toda configuração a cada novo post. Vou colocar apenas o código relacionado  ao objetivo do post.

Step 1

Adicione o angular-ui.js  ao projeto

Step 2

Como estou usando rotas e o ng-view tudo fica na index.html, então vou colocar para carregar o novo arquivo angular-ui.js  lá. Veja como fica:

<script src="js/lib/angular-ui.js"></script>

 Step 3

Crie um controller

var blacklistController= function($scope){

       //criando meu black list, um array.

       $scope.blacklist= ['satanas', 'biba'];

       //verifica se a palavra digitada corresponde ao que temos no blacklist

       $scope.notBlackListed = function(value){

             return $scope.blacklist.indexOf(value)===-1;

       }; 

};

 Step 4

Agora vamos criar o arquivo HTML, que não tem nada de especial. Chamei ele de angularui.html

<form name="form">

<label> first name</label>

<input name="firstname" type="text" ng-model="user.firstname" required

ui-validate="{blacklisted:'notBlackListed($value)'}"/>

 <button ng-disabled="form.$invalid" class="btn">Submit</button>

</form>

 

Step 5

Como estou usando o recurso de rotas do angularJS, preciso atualizar para quando eu chamar a url  /angularui ele deve carregar o controller. Basta adicionar a linha abaixo:

when("/angularui",{templateUrl:"angularui.html",controller:blacklistController}).

 

 Testando

Vamos testar agora:

uivalidateinvalid

Observe que o botão de submit não ficou ativo.

uivalidatevalid

Agora sim. Simples, não?

Claro que ao clicar nada acontece. O objetivo aqui não era dar funcionalidade real, mas mostrar como o ui-validate do angular-ui facilita nossa vida. Óbvio que as palavras do nosso blacklist deveriam ser recuperadas de uma base de dados através de um serviço  REST, por exemplo.

Bom, vou ficando por aqui. Espero que tenham curtido um pouco do angular-ui e é claro que há muito mais coisas, basta acessar  http://angular-ui.github.io  e se divertir.

Abraços. See ya!!

Série AngularJS: Atualizando versão do AngularJS via Yeoman

yeoman

Olá Pessoal,

No post de hoje vamos ver como dizer para o Yeoman usar uma versão específica do angularJS.

Lets go…

Atualizando AngularJS via Yeoman

Por default, o Yeoman na versão 1.0 vem com o AngularJS 1.0.7, mas se precisamos usar a versão mais recente ou uma específica, como atualizar? É bem simples.

Note: vou considerar que você criou seu projeto via yeoman.

Step 1

Abra o arquivo bower.json

Step 2

Altere as dependências a seguir para a versão desejada:

"angular": "~1.2.9",
"angular-resource": "~1.2.9",

 "devDependencies":

{

    "angular-mocks": "~1.2.9",

    "angular-scenario": "~1.2.9"

  }

  Step 3

Digite bower update e aguarde atualização

bowerupdateversion

Step 4

Agora execute:

bower install --save angular-route

 Step 5

Precisamos atualizar o arquivo Karma.conf.js  no array files adicione:

'app/bower_components/angular-sanitize/angular-route.js',

 Step 6

Abra o arquivo apps.js  e atualize. Adicione ngRoute ficando assim:

angular.module('webappApp', [

  'ngCookies',

  'ngResource',

  'ngSanitize',

  'ngRoute'

])

Step 7

Abra o arquivo index.html dentro de app/index.html e adicione a linha a seguir no bloco de script/modules.js

<script src="bower_components/angular-route/angular-route.js"></script>

Pronto. Veja que a estrutura do projeto foi alterada de acordo com a versão escolhida do AngularJS. Sabemos que a partir da versão 1.2 tivemos mudanças que são incompatíveis com projetos na versão 1.0.x, como já citei aqui no blog.

Vou ficando aqui e espero que tenham gostado do post.

Abraços, see ya!