Você está na página 1de 12

07/06/2023, 14:47 Class Let's Code

#854 Top Coders | Web Full Stack Seg • Qua • Sex


arrow_back Framework Front-End I | Angular

Conteúdo
Conteúdo

9 Formulários

Formulários
Na grande maioria dos casos em que temos uma aplicação Angular, precisaremos da ajuda de
formulários. O Angular pode nos ajudar a lidar com os formulários HTML a fim de obter os
dados informados pelos usuários, adicionar validação, erros etc. Nesta seção, vamos entender
como as ferramentas do framework podem nos ajudar com essas tarefas.

Antes de começar a mostrar códigos, é importante saber que o Angular possui duas
abordagens para lidar com formulários: Template-Driven e Reactive Forms.

Template-Driven

Template-Driven ou Formulários Orientados por Modelo é uma das formas de utilizarmos os


formulários no Angular. Nessa abordagem, os elementos de controle no formulários estão
vinculados a propriedades de dados que possuem validação na entrada. Ou seja, podemos
vincular de forma direta o formulário a um modelo de dados do componente. Veremos como
implementamos na prática.

Antes de mais nada, é preciso adicionar o FormsModule ao módulo principal da nossa


aplicação, o AppModule . Tendo feito isso, criamos uma pasta models , dentro da pasta app da
nossa aplicação. Nela, adicionaremos os modelos que utilizaremos na aplicação. Vamos criar
um novo arquivo, dentro da pasta models , que receberá o nome de user.ts , onde definiremos
uma classe User , desta forma:

export class User {


constructor(
public username: string,
public email: string,
public gender: string
) {}
}

Esta classe será o nosso modelo de dados, que utilizaremos para o nosso formulário. No
AppComponent , vamos definir um array com os gêneros que aparecerão como opções

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 1/12
07/06/2023, 14:47 Class Let's Code

selecionáveis do form e, em seguida, um objeto da classe User , que será o usuário que vai
aparecer pré-carregado no formulário.

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
genders = ['Masculino', 'Feminino'];

user = new User('Fulano', 'fulano@email.com', this.genders[0]);

ngOnInit() {
console.log(this.user);
}

onSubmit() {
console.log(this.user);
}
}

No template, construiremos o formulário, utilizando a diretiva ngModel para associar o campo


do formulário à propriedade de user :

<form (ngSubmit)="onSubmit()" #heroForm="ngForm">


<div class="form-group">
<label for="username">Username</label>
<input
class="form-control"
id="username"
name="username"
[(ngModel)]="user.username"
required
/>
</div>
<div class="form-group">
<label for="email">Email</label>
<input
class="form-control"
id="email"
name="email"
[(ngModel)]="user.email"
required
/>
</div>
https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 2/12
07/06/2023, 14:47 Class Let's Code

<div class="form-group">
<label for="gender">Gênero</label>
<select
class="form-control"
id="gender"
name="gender"
required
[(ngModel)]="user.gender"
>
<option *ngFor="let gender of genders" [value]="gender">
{{ gender }}
</option>
</select>
</div>
<button type="submit">Atualizar</button>
</form>

Com isso, temos o seguinte resultado:

Imagem 1 - Formulário utilizando Template-Driven (Fonte da imagem: do autor)

Reactive Forms

Na abordagem reativa, o formulário é criado programaticamente no código Typescript. Nós


podemos criar o formulário através de uma propriedade do tipo FormGroup no código
TypeScript. O FormGroup é simplesmente um grupo de controles que representam cada campo
do nosso formulário.

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 3/12
07/06/2023, 14:47 Class Let's Code

Obs: Para que essa abordagem reativa funcione e possamos conectar nosso formulário criado
no código TypeScript com o nosso código HTML, precisamos importar o ReactiveFormsModule
no AppModule .

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;
}

Criando um formulário no código TypeScript

Criaremos nosso formulário no ngOnInit() , onde passaremos para ele os controles. Os


controles são pares de chave-valor que representam os campos do nosso formulário e que
receberão um valor inicial ao serem criados.

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;

ngOnInit() {
this.signupForm = new FormGroup({
username: new FormControl(null),
email: new FormControl(null),
gender: new FormControl('feminino'),
});
}
}

Sincroninzando o HTML com o formulário

Na seção anterior, criamos um formulário no código TypeScript. Agora, precisamos sincronizá-lo


aos nossos inputs que estão no template HTML. Fazemos isso utilizando as diretivas
https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 4/12
07/06/2023, 14:47 Class Let's Code

formGroup (localizada na tag form ), que irá receber o nome do formulário criado no código
TypeScript, e formControlName (localizada na tag input ), que irá receber o nome do controle
criado no código TypeScript.

<form [formGroup]="signupForm">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username" />
</div>
<div class="form-group">
<label for="email">E-mail</label>
<input type="text" id="email" formControlName="email" />
</div>
<div class="form-group">
<label for="gender">Sexo</label>
<input type="text" id="gender" formControlName="gender" />
</div>
</form>

Aninhando FormGroups

Por vezes, precisamos lidar com objetos e dados mais complexos, o que nos traz a necessidade
de implementar o aninhamento de grupos de formulário (FormGroup). Pensando no exemplo
anterior, suponhamos que o objeto criado possua, além do username, do e-mail e do sexo, um
endereço e este, por sua vez, possua rua, número, cidade, estado e CEP. Para adicionar esses
campos, podemos fazer o seguinte:

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;

ngOnInit() {
this.signupForm = new FormGroup({
username: new FormControl(null),
email: new FormControl(null),
gender: new FormControl('feminino'),
address: new FormGroup({
street: new FormControl(null),
number: new FormControl(null),

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 5/12
07/06/2023, 14:47 Class Let's Code

city: new FormControl(null),


state: new FormControl(null),
zipCode: new FormControl(null),
}),
});
}
}

E no template:

<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">


<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username" />
</div>
<div class="form-group">
<label for="email">E-mail</label>
<input type="text" id="email" formControlName="email" />
</div>
<div class="form-group">
<label for="gender">Sexo</label>
<input type="text" id="gender" formControlName="gender" />
</div>
<div formGroupName="address">
<h3>Endereço</h3>
<div class="form-group">
<label for="street">Rua</label>
<input type="text" id="street" formControlName="street" />
</div>
<div class="form-group">
<label for="number">Número</label>
<input type="text" id="number" formControlName="number" />
</div>
<div class="form-group">
<label for="city">Cidade</label>
<input type="text" id="city" formControlName="city" />
</div>
<div class="form-group">
<label for="state">Estado</label>
<input type="text" id="state" formControlName="state" />
</div>
<div class="form-group">
<label for="zipCode">CEP</label>
<input type="text" id="zipCode" formControlName="zipCode" />
</div>

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 6/12
07/06/2023, 14:47 Class Let's Code

</div>
</form>

Atualizando o formulário

Uma outra forma de preencher o formulário com dados é fazer isto a partir do TypeScript. Para
isso, podemos utilizar os métodos setValue() e patchValue() .

setValue() : Substitui todo o valor do formulário pelo valor passado no método.

patchValue() : Substitui apenas as propriedades do formulário que forem passadas no


parâmetro.

<form [formGroup]="signupForm">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" formControlName="username" />
</div>
<div class="form-group">
<label for="email">E-mail</label>
<input type="text" id="email" formControlName="email" />
</div>
<div class="form-group">
<label for="gender">Sexo</label>
<input type="text" id="gender" formControlName="gender" />
</div>
<div formGroupName="address">
<h3>Endereço</h3>
<div class="form-group">
<label for="street">Rua</label>
<input type="text" id="street" formControlName="street" />
</div>
<div class="form-group">
<label for="number">Número</label>
<input type="text" id="number" formControlName="number" />
</div>
<div class="form-group">
<label for="city">Cidade</label>
<input type="text" id="city" formControlName="city" />
</div>
<div class="form-group">
<label for="state">Estado</label>
<input type="text" id="state" formControlName="state" />
</div>
https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 7/12
07/06/2023, 14:47 Class Let's Code

<div class="form-group">
<label for="zipCode">CEP</label>
<input type="text" id="zipCode" formControlName="zipCode" />
</div>
</div>
<button type="button" (click)="updateUser()">Atualizar</button>
</form>

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;

ngOnInit() {
this.signupForm = new FormGroup({
username: new FormControl(null),
email: new FormControl(null),
gender: new FormControl('feminino'),
address: new FormGroup({
street: new FormControl(null),
number: new FormControl(null),
city: new FormControl(null),
state: new FormControl(null),
zipCode: new FormControl(null),
}),
});
}

updateUser() {
this.signupForm.patchValue({
username: 'Beltrano',
gender: 'masculino',
address: {
street: 'Rua sem Fim',
number: 854,
},
});
console.log(this.signupForm.value);
}
}

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 8/12
07/06/2023, 14:47 Class Let's Code

Imagem 2 - Atualizando o formulário (Fonte da imagem: do autor)

Validação dos campos do formulário

Muitos erros podem decorrer do preenchimento indevido dos campos de um formulário. Para
lidar com isso, usamos a validação de formulário.

Para adicionar validação a um formulário Angular, precisamos importar uma função validadora.
O Angular nos disponibiliza a Validators , que nos traz uma série de validações úteis para os
campos do formulário. Vamos ver isso na prática:

Usando o exemplo anterior, vamos definir como obrigatórios os campos de username e e-mail
no formulário.

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;

ngOnInit() {
this.signupForm = new FormGroup({
username: new FormControl(null, [Validators.required]),
email: new FormControl(null, [Validators.required]),
gender: new FormControl('feminino'),
address: new FormGroup({
street: new FormControl(null),

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2a… 9/12
07/06/2023, 14:47 Class Let's Code

number: new FormControl(null),


city: new FormControl(null),
state: new FormControl(null),
zipCode: new FormControl(null),
}),
});
}
}

Imagem 3 - Validando os campos do formulário (Fonte da imagem: do autor)

Note que o status do formulário só passa a ser válido após o preenchimento dos campos
obrigatórios.

Existem inúmeras outras possibilidades de validação dos campos de um formulário no Angular,


para saber mais sugiro uma visita à documentação.

Submetendo o formulário

Nas seções anteriores, nós construímos o formulário no nosso código TypeScript e no template,
conectamos ambos, e agora vamos ver como fazemos para submeter esse formulário.

Para fazer isso é simples: iremos reagir ao evento ngSubmit . Quando o evento for acionado,
iremos executar uma função onSubmit . Esse evento será acionado a partir de um botão do tipo
submit .

<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">


<div class="form-group">
https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2… 10/12
07/06/2023, 14:47 Class Let's Code

<label for="username">Username</label>
<input type="text" id="username" formControlName="username" />
</div>
<div class="form-group">
<label for="email">E-mail</label>
<input type="text" id="email" formControlName="email" />
</div>
<div class="form-group">
<label for="gender">Sexo</label>
<input type="text" id="gender" formControlName="gender" />
</div>
<div formGroupName="address">
<h3>Endereço</h3>
<div class="form-group">
<label for="street">Rua</label>
<input type="text" id="street" formControlName="street" />
</div>
<div class="form-group">
<label for="number">Número</label>
<input type="text" id="number" formControlName="number" />
</div>
<div class="form-group">
<label for="city">Cidade</label>
<input type="text" id="city" formControlName="city" />
</div>
<div class="form-group">
<label for="state">Estado</label>
<input type="text" id="state" formControlName="state" />
</div>
<div class="form-group">
<label for="zipCode">CEP</label>
<input type="text" id="zipCode" formControlName="zipCode" />
</div>
</div>
<button type="submit">Submit</button>
</form>

A função onSubmit irá simplesmente mostrar no console o valor do formulário criado.

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
signupForm: FormGroup;

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2… 11/12
07/06/2023, 14:47 Class Let's Code

ngOnInit() {
this.signupForm = new FormGroup({
username: new FormControl(null),
email: new FormControl(null),
gender: new FormControl('feminino'),
address: new FormGroup({
street: new FormControl(null),
number: new FormControl(null),
city: new FormControl(null),
state: new FormControl(null),
zipCode: new FormControl(null),
}),
});
}

onSubmit() {
console.log(this.signupForm.value);
}
}

Resultado no console com os valores obtidos no formulário:

Imagem 4 - Formulário Reativo (Fonte da imagem: do autor)

Referências e Links úteis

chevron_left Tópico anterior Próximo Tópico chevron_right


Criando um formulário orientado por modelo. Acesso em: 12/07/2022.

https://class.letscode.com.br/apps/academy/courses/977326ae-d78b-4f19-a54b-7f268eecf2dd/122fa596-0ed8-4812-aed8-cd6fc870cb7c/c36c2… 12/12

Você também pode gostar