Skip to main content

Introdução | Formulários | Angular

  • Introdução | Formulários | Angular

info

Sempre precisamos importar o módulo FormModule

FormControl

  • FormGroup é um conjunto de FormControl

  • value, valid, disabled

const fc = new FormControl();

fc.value
fc.valid
fc.disabled

fc.setValue('Another Value');

Html

  • ngNoForm: informa que aquela formulário não será um form
<form ngNoForm></form>

Input

warning

Necessita ter a prop name junto com o [(ngModel)]

<input [(ngModel)]="userInfo.firstName" name="firstName" type="text" id="name"/>
  • [ngModelOptions]: {}
    • name: podemos essa prop ao invés de usar a prop name do input
    • updateOn:
      • change: altera conforme digita no campo
      • blur: altera o valor quando tira o foco do campo
      • submit: o valor altera apenas quando clica no botão de submit
      info

      Para aplicar a todos os campos o updateOn deve secolocar na tag do <form>. Ex. <form [ngModelOptions]={updateOn:}">

    • standlone: especifica se o campo deve ser tratado como independente, sem fazer parte de um formulário Angular. True ou False. Um caso de uso é quando precisamos ter campos helpers que não será enviado para nossa API.
    • debouce: Define um atraso (em milissegundos) antes de atualizar o modelo, útil para evitar atualizações excessivas.
    • allowInvalid: Define se o modelo deve ser atualizado mesmo que o valor do campo seja inválido. True ou False.

NgSubmit

info

#userForm="ngForm"

Explicação

O #userForm="ngForm" é uma referência de template em Angular que permite acessar e interagir com o formulário no template HTML. Aqui está uma explicação detalhada:

  • #userForm: Cria uma referência de template chamada userForm. Você pode usar essa referência para acessar o formulário e suas propriedades no template.
  • "ngForm": Informa ao Angular que a referência userForm deve ser associada à diretiva ngForm, que é responsável por gerenciar o estado do formulário.

Com essa referência, você pode acessar várias propriedades e métodos do formulário, como:

  • userForm.value: Obtém os valores atuais dos controles do formulário.
  • userForm.valid: Verifica se o formulário é válido.
  • userForm.invalid: Verifica se o formulário é inválido.
  • userForm.touched: Verifica se algum controle do formulário foi tocado.
  • userForm.untouched: Verifica se nenhum controle do formulário foi tocado.
  • userForm.dirty: Verifica se algum controle do formulário foi modificado.
  • userForm.pristine: Verifica se nenhum controle do formulário foi modificado.

Exemplo

<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value)">
<div ngModelGroup="userInfo">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" name="firstName" ngModel>

<label for="lastName">Last Name:</label>
<input type="text" id="lastName" name="lastName" ngModel>
</div>

<button type="submit" [disabled]="!userForm.valid">Submit</button>
</form>

<p *ngIf="userForm.invalid">Form is invalid</p>

Neste exemplo, a referência #userForm="ngForm" permite que o botão de envio seja desativado se o formulário for inválido e exibe uma mensagem se o formulário for inválido.

<form #userForm="ngForm" (ngSubmit)="onSubmitForm()"></form>
onSubmitForm(form: NgForm){
}

NgModelGroup

O ngModelGroup é usado para agrupar controles de formulário em um formulário Angular. Aqui está um exemplo de como usá-lo:

<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value)">
<div ngModelGroup="userInfo">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" name="firstName" ngModel>

<label for="lastName">Last Name:</label>
<input type="text" id="lastName" name="lastName" ngModel>
</div>

<div ngModelGroup="address">
<label for="street">Street:</label>
<input type="text" id="street" name="street" ngModel>

<label for="city">City:</label>
<input type="text" id="city" name="city" ngModel>
</div>

<button type="submit">Submit</button>
</form>

TypeScript

import { Component } from '@angular/core';

@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html'
})
export class UserFormComponent {
onSubmit(formValue: any) {
console.log('Form Value:', formValue);
}
}

Neste exemplo, ngModelGroup é usado para agrupar os campos firstName e lastName sob userInfo, e os campos street e city sob address. Quando o formulário é enviado, o valor do formulário é registrado no console, mostrando a estrutura agrupada dos dados.

Validations

  • Os validators são: required, minLength, pattern
<input required minLength="2" pattern="^[azA-Z0-9_.]" />

<!-- form é a referência colocar na tag <form> -> #form-->
<button [disable]="form.invalid"></button>
.ng-invalid.ng-dirty{
border: 2px solid var(--color-error);
}

button[disabled] {
background-color: rgba(0, 0, 0, 0.15);
border-color: rgba(0, 0, 0, 0.1);
pointer-events: none;
}

Mostar mensagens de validação

danger

Colocando o #<nome_do_campo> conseguimos acessar direto o valor sem ter que criar algo no arquivo .ts para acessar o campo.

<div class="form-field">
<label for="name">First Name</label>
<input
[(ngModel)]="userInfo.firstName"
required
minlength="2"
appBanWords="test"
#firstName="ngModel"
name="first-name"
type="text"
id="name"
placeholder="Enter your name">
<div *ngIf="firstName.dirty && firstName.hasError('required')" class="input-error">This field is required</div>
<div *ngIf="firstName.dirty && firstName.hasError('minlength')" class="input-error">
The length should be at least <strong>{{firstName.getError('minlength').requiredLength}}</strong> characters
</div>
<div *ngIf="firstName.dirty && firstName.hasError('appBanWords')" class="input-error">
The value <strong>{{ firstName.getError('appBanWords').bannedWord }}</strong> is not allowed
</div>
</div>

Custom Validator

@Directive({
selector: '[appBanWords]',
standalone: true,
providers: [
{
provide: NG_VALIDATORS,
useExisting: BanWordsDirective,
multi: true
}
]
})
export class BanWordsDirective implements Validator {

@Input()
set appBanWords(value: string | string[]) {
this.bannedWords = Array.isArray(value) ? value : [value];
this.onChange();
}
private bannedWords: string[] = [];

private onChange: () => void = () => {}

constructor() { }

validate(control: AbstractControl<string>): ValidationErrors | null {
const foundBannedWord = this.bannedWords.find(word => word.toLowerCase() === control.value?.toLowerCase());
return !foundBannedWord
? null
: { appBanWords: { bannedWord: foundBannedWord } }
}

registerOnValidatorChange(fn: () => void) {
this.onChange = fn;
}

}

// <input appBanWords="test" #firstName.hasError("appBanWords") />

Resetar form

  • Resetar valores e estados
form.resetForm();
  • Resetar estados
form.resetForm({
'first-name': form.controls['first-name'].value
});
//ou
form.resetForm(form.value);
// ------------------------------------------

<form (onReset)="onReset($event, form)"></form>

onReset(e: Event, form: NgForm){
form.resetForm();
}