Como criar formulários do tipo Template-driven Forms com Angular

Template-driven forms

Template-driven forms é uma das duas maneiras de criar formulários com o Angular.
Nesse tutorial você vai aprender

  • Criar um formulário com um componente
  • Usar o ngModel para criar o two-way data bindings para ler e escrever nos inputs na tela
  • Como limpar os campos na tela após submeter o formulário

Pré-requisitos

Esse tutorial foi feito utilizando o Bootstrap para criação de uma interface mais amigável. Se você não sabe o que é o Bootstrap, clique aqui para ver o tutorial.

Também foi utilizada a versão 7.0 do Angular.

Passo a passo para a criação do formulário

  1. Instalação do FormsModule
  2. Criar a classe que será o modelo do formulário
  3. Criar o componente com o formulário
  4. Aplicar o ngModel nos inputs
  5. Fazer o formulário submter

1 – Instalação do FormsModule

Antes de começar, você precisa importar o módulo FormsModule no seu projeto.
Esse modulo possui todas as diretivas de criação de formulários do tipo Template-driven Forms. É necessário efetuar o import antes de qualquer componente que use um formulário.
Para importar, é só incluir a linha abaixo no arquivo app.module.ts.

import { FormsModule } from '@angular/forms';

O arquivo app.module.ts deve ficar assim:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule }   from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

2 – Criar a classe que será o modelo do formulário

Para esse exemplo, será criado uma classe de cliente com os campos abaixo.
Para criar uma classe é só rodar o comando abaixo.

ng g class clientes/shared/cliente

O arquivo cliente.ts deve ficar assim:

export class Cliente {
  nome: string = '';
  tipo: number = 1;
  genero: string = "1";
  dataNascimento: Date = null;
  observacao: string = '';
  inativo: boolean = false;
}

3 – Criar o componente com o formulário

O formulário no Angular é um formulário comum com a adição do ngModel para fazer o binding entre o controle na tela e a classe que você está usando.

Criar o componente
Para criar o componente que terá o formulário, é só rodar o comando abaixo

ng g component clientes/formulario

A principio o arquivo formulario.component.html deve ficar assim:

<form>

  <div class="form-group">
    <label for="nome">Nome</label>
    <input type="text" class="form-control" name="nome" id="nome">
  </div>

  <div class="form-group">
    <label for="tipo">Tipo</label>
    <select class="form-control" name="tipo" id="tipo">
      <option value="1">Pessoa física</option>
      <option value="2">Pessoa jurídica</option>
    </select>
  </div>

  <div class="form-group">
    <label>Gênero</label>

    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="masculino" [value]="1">
      <label class="form-check-label" for="masculino">Masculino</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="feminino" [value]="2">
      <label class="form-check-label" for="feminino">Feminino</label>
    </div>
  </div>

  <div class="form-group">
    <label for="dataNascimento">Data de nascimento</label>
    <input type="date" class="form-control" name="dataNascimento" id="dataNascimento">
  </div>

  <div class="form-group">
    <label for="observacao">Observação</label>
    <textarea class="form-control" rows="3" name="observacao" id="observacao"></textarea>
  </div>

  <div class="form-check">
    <input class="form-check-input" type="checkbox" name="inativo" id="inativo">
    <label class="form-check-label" for="inativo">Inativo</label>
  </div>

  <input type="submit" class="btn btn-primary mt-4" value="Salvar">
  <a href="#" class="btn btn-secondary mt-4 ml-2">Cancelar</a>

</form>

Exibir o formulário na tela
Para ver o resultado na tela, é necessário incluir o componente de formulário no componente raiz da aplicação app.component.
O arquivo app.component.html deve ficar assim:

<app-formulario></app-formulario>

4 – Aplicar o ngModel nos inputs

Agora é hora de usar a diretiva ngModel para poder fazer o binding dos controles.

Primeiro é necessário criar uma propriedade que será o model do formulário.
Para isso no arquivo formulario.component.ts será criado a propriedade cliente do tipo Cliente.

cliente: Cliente;

E depois é necessário instanciar esse objeto para que ele não fique nulo e não de erro na tela.

ngOnInit() {
  this.cliente = new Cliente();
}

Agora é hora de fazer o binding do componente na tela para a propriedade cliente.
Para isso em cada input na tela será colocado o ngModel.
O arquivo formulario.component.html deve ficar assim:

<form>

  <div class="form-group">
    <label for="nome">Nome</label>
    <input type="text" class="form-control" name="nome" id="nome" [(ngModel)]="cliente.nome">
  </div>

  <div class="form-group">
    <label for="tipo">Tipo</label>
    <select class="form-control" name="tipo" id="tipo" [(ngModel)]="cliente.tipo">
      <option value="1">Pessoa física</option>
      <option value="2">Pessoa jurídica</option>
    </select>
  </div>

  <div class="form-group">
    <label>Gênero</label>

    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="masculino" [(ngModel)]="cliente.genero" [value]="1">
      <label class="form-check-label" for="masculino">Masculino</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="feminino" [(ngModel)]="cliente.genero" [value]="2">
      <label class="form-check-label" for="feminino">Feminino</label>
    </div>
  </div>

  <div class="form-group">
    <label for="dataNascimento">Data de nascimento</label>
    <input type="date" class="form-control" name="dataNascimento" id="dataNascimento" [(ngModel)]="cliente.dataNascimento">
  </div>

  <div class="form-group">
    <label for="observacao">Observação</label>
    <textarea class="form-control" rows="3" name="observacao" id="observacao" [(ngModel)]="cliente.observacao"></textarea>
  </div>

  <div class="form-check">
    <input class="form-check-input" type="checkbox" name="inativo" id="inativo" [(ngModel)]="cliente.inativo">
    <label class="form-check-label" for="inativo">Inativo</label>
  </div>

  <input type="submit" class="btn btn-primary mt-4" value="Salvar">
  <a href="#" class="btn btn-secondary mt-4 ml-2">Cancelar</a>

</form>

Com isso todo valor que você digitar na tela será salvo na respectiva propriedade da propriedade cliente e todo valor que você colocar em alguma propriedade do cliente será exibido na tela.
Um exemplo disso é mostrado no vídeo acima.

5 – Fazer o formulário submter

Para fazer o formulário submeter é necessário criar um método no arquivo formulario.component.ts e adicionar a chamada desse método no evento (ngSubmit) do formulário.

Método para submeter o formulário

onSubmit() {
  // aqui você pode implementar a logica para fazer seu formulário salvar
  console.log(this.cliente);
}

E na tag form adicionar

(ngSubmit)="onSubmit()"

Limpando os campos do formulário
Para limpar os valores preenchidos na tela de maneira simples basta instanciar um novo objeto do seu model logo após você salvar os dados que foram preenchidos.

onSubmit() {
    // aqui você pode implementar a logica para fazer seu formulário salvar
    console.log(this.cliente);
    // ao instanciar novamente o objeto cliente, você vai limpar os controles na tela
    this.cliente = new Cliente();
  }

O exemplo completo do arquivos formulario.component.ts e formulario.component.html está abaixo:

Arquivo formulario.component.ts

import { Component, OnInit } from '@angular/core';
import { Cliente } from '../shared/cliente';

@Component({
  selector: 'app-formulario',
  templateUrl: './formulario.component.html',
  styleUrls: ['./formulario.component.scss']
})
export class FormularioComponent implements OnInit {
  cliente: Cliente;

  constructor() { }

  ngOnInit() {
    this.cliente = new Cliente();
  }

  onSubmit() {
    // aqui você pode implementar a logica para fazer seu formulário salvar
    console.log(this.cliente);
    // ao instanciar novamente o objeto cliente, você vai limpar os controles na tela
    this.cliente = new Cliente();
  }
}

Arquivo formulario.component.html

<form (ngSubmit)="onSubmit()" >

  <div class="form-group">
    <label for="nome">Nome</label>
    <input type="text" class="form-control" name="name" id="nome" [(ngModel)]="cliente.nome">
  </div>

  <div class="form-group">
    <label for="tipo">Tipo</label>
    <select class="form-control" name="tipo" id="tipo" [(ngModel)]="cliente.tipo">
      <option value="1">Pessoa física</option>
      <option value="2">Pessoa jurídica</option>
    </select>
  </div>

  <div class="form-group">
    <label>Gênero</label>

    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="masculino" [(ngModel)]="cliente.genero" [value]="1">
      <label class="form-check-label" for="masculino">Masculino</label>
    </div>
    <div class="form-check">
      <input class="form-check-input" type="radio" name="genero" id="feminino" [(ngModel)]="cliente.genero" [value]="2">
      <label class="form-check-label" for="feminino">Feminino</label>
    </div>
  </div>

  <div class="form-group">
    <label for="dataNascimento">Data de nascimento</label>
    <input type="date" class="form-control" name="dataNascimento" id="dataNascimento" [(ngModel)]="cliente.dataNascimento">
  </div>

  <div class="form-group">
    <label for="observacao">Observação</label>
    <textarea class="form-control" rows="3" name="observacao" id="observacao" [(ngModel)]="cliente.observacao"></textarea>
  </div>

  <div class="form-check">
    <input class="form-check-input" type="checkbox" name="inativo" id="inativo" [(ngModel)]="cliente.inativo">
    <label class="form-check-label" for="inativo">Inativo</label>
  </div>

  <input type="submit" class="btn btn-primary mt-4" value="Salvar">
  <a href="#" class="btn btn-secondary mt-4 ml-2">Cancelar</a>

</form>

Referências