Introdução | Formulários | Angular
- Introdução | Formulários | Angular
Sempre precisamos importar o módulo FormModule
FormControl
-
FormGroupé um conjunto deFormControl -
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
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
infoPara aplicar a todos os campos o
updateOndeve 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.
TrueouFalse. 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.
TrueouFalse.
NgSubmit
#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 chamadauserForm. Você pode usar essa referência para acessar o formulário e suas propriedades no template."ngForm": Informa ao Angular que a referênciauserFormdeve ser associada à diretivangForm, 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
validatorssã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
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();
}