Forms and form validation
HTML CODE
1. using local template reference variable
<form class="contact-form needs-validation" novalidate #myForm="ngForm" (ngSubmit)="handleForm(myForm)">
<input required email minlength="4" type="email" #email='ngModel' name="email" ngModel>
<div *ngIf="email.invalid && (email.dirty || email.touched)" class="alert alert-danger">
<div *ngIf="email.errors?.['required']">
Email is required.
</div>
<div *ngIf="email.errors?.['minlength']">
Email must be at least 6 characters long.
</div>
<div *ngIf="email.errors?.['email']">
Its not correct Email
</div>
</div>
<input type="submit" class="btn btn-outline-primary rounded-pill btn-send mb-3" value="Subscribe" (click)="myForm.form.markAllAsTouched()">
</form>
COMPONENT
export class EmailSubscriptionComponent {
handleForm(data:any){
if (data.valid) {
// Form is valid, perform submission logic here
} else {
// Form is invalid, handle the validation errors or display an error message
}
console.log(data.value);
}
}
FOR Select dropdown
component.ts
subsForm_frequency:string ='0';
html
<div class="col-4">
<div class="form-select-wrapper mb-4">
<select class="form-select" aria-label="Default select example" name="frequency" [(ngModel)]="subsForm_frequency">
<option value="0">Alert Frequency</option>
<option value="1">Daily</option>
<option value="2">Weekly</option>
</select>
</div>
</div>
Lets break down the code:
<input> element representing the email input field. It has the following attributes and directives:
- required: Specifies that the field must be filled in before submitting the form.
- email: Indicates that the input value should be a valid email address format.
- minlength="4": Specifies the minimum length of the input value to be 4 characters.
- type="email": Indicates that the input type is "email" to enable email-specific browser validation.
- #email='ngModel': Declares a local template reference variable "email" and assigns it to the NgModel directive for the input field.
To display the validation errors when the submit button is clicked, we use
(click)="myForm.form.markAllAsTouched()"
SAME PASSWORD VALIDATION
<input type="password" name="new_pass" #new_pass='ngModel' ngModel required="required">
<input type="password" name="new_pass_cnf" #new_pass_cnf='ngModel' ngModel required="required">
<div *ngIf="new_pass.value != new_pass_cnf.value" class="alert alert-danger mt-2">
Passwords don't match.
</div>
2. using Reactive form
>>simple form
component.ts
/*
Reactive forms provide a model-driven approach to handling form inputs whose values change over time.
1. app.module.ts
> import { ReactiveFormsModule } from '@angular/forms';
> imports: [
ReactiveFormsModule
],
2. inside component
import { FormControl } from '@angular/forms';
3. use inside template
<label for="name">Name: </label>
<input id="name" type="text" [formControl]="name">
*/
name = new FormControl('inital value');
updateName() {
this.name.setValue('Nancy');
}
.html
<label for="name">Name: {{name.value}}</label><br/>
<input id="name" type="text" [formControl]="name">
<button type="button" (click)="updateName()">Update Name</button>
<hr>
>> FORM GROUP
component.ts
/* form group: a form group instance tracks the form state of a group of form control instances (for example, a form).
1. import { FormGroup } from '@angular/forms';
2. USE FormGroup
3. to save data (ngSubmit)="onSubmit()" its captures the current value of profileForm. Use EventEmitter to keep the form encapsulated and to provide the form value outside the component.
*/
profileForm = new FormGroup({
firstName: new FormControl(),
address: new FormGroup({
street: new FormControl('bhera'),
city: new FormControl(''),
})
});
updateProfile() {
this.profileForm.patchValue({
firstName: 'Nancy',
address: {
street: '123 Drew Street'
}
});
}
onSubmit() {
console.warn(this.profileForm.value);
}
html
<h2>FORM GROUP</h2>
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<label for="first-name">First Name: </label>
<input id="first-name" type="text" formControlName="firstName">
<div formGroupName="address">
<h6>Address</h6>
<label for="street">Street: </label>
<input id="street" type="text" formControlName="street">
<label for="city">City: </label>
<input id="city" type="text" formControlName="city">
</div>
<button type="button" (click)="updateProfile()">Update Profile</button>
<button type="submit" [disabled]="!profileForm.valid">Submit</button>
</form>
<hr>
>> create form using service
component.ts
/**
* Creating form control instances manually can become repetitive when dealing with multiple forms. The FormBuilder service provides convenient methods for generating controls.
* 1. import { FormBuilder } from '@angular/forms';
* 2. constructor(private fb: FormBuilder) { }
* 3.
*/
constructor(private fb: FormBuilder) { }
serviceForm = this.fb.group({
username: [''],
services: this.fb.group({
misaj: [''],
polish: [''],
}),
});
html
<h2>SERVICE TO CREATE FORM</h2>
<form [formGroup]="serviceForm">
<label>username: </label>
<input type="text" formControlName="username">
<div formGroupName="services">
<h6>services</h6>
<input placeholder="misaj" type="text" formControlName="misaj">
<input placeholder="polish" type="text" formControlName="polish">
</div>
<button type="submit" [disabled]="!serviceForm.valid">Submit</button>
</form>
>> FORM VALIDATION
component.ts
/*
form validation:
1.import { Validators } from '@angular/forms';
2. firstName: ['', Validators.required], //make field required
3. <p>Form Status: {{ profileForm.status }}</p>
*/
export class FormsComponent{
formValid = new FormGroup({
nameis: new FormControl('', [Validators.required, Validators.minLength(4),forbiddenNameValidator(/bob/i)]),
});
}
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? {forbiddenName: {value: control.value}} : null;
};
}
html
<h2>Form validation</h2>
<form [formGroup]="formValid">
<label>Name: </label>
<input type="text" formControlName="nameis" >
<div *ngIf="formValid.controls.nameis.invalid && (formValid.controls.nameis.dirty || formValid.controls.nameis.touched)" class="alert alert-danger">
<div *ngIf="formValid.controls.nameis.errors?.['required']">
Name is required.
</div>
<div *ngIf="formValid.controls.nameis.errors?.['minlength']">
Name must be at least 4 characters long.
</div>
<div *ngIf="formValid.controls.nameis.errors?.['forbiddenName']">
Name cannot be Bob.
</div>
</div>
<p>Form Status: {{ formValid.status }}</p>
</form>