Reputation: 780
I want to create a form where the user will enter his email. I'd like to validate email format client-side.
Is there any generic email validator in Angular 2?
NB: Something similar to AngularJS validator.
Upvotes: 46
Views: 84408
Reputation: 69
You can use the built in Angular form validators without a form. I'm not sure if it's good practice, but it works.
const control = new FormControl('', Validators.email);
control.setValue(valueToCheck);
console.log(control.errors);
Other answers have already shown how to use it in a form:
this.contactUsForm = this.formBuilder.group({
firstName: new FormControl('', Validators.required),
lastName: new FormControl('', Validators.required),
emailAddress: new FormControl('', [Validators.required, Validators.email]),
message: new FormControl('', Validators.required)
});
Upvotes: 1
Reputation: 101
Here is another way of validating a field using RegEx. You can bind a method to the keyUp event of the field.
In your component:
import {NgForm} from 'angular2/common';
//...
emailValidator(email:string): boolean {
var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!EMAIL_REGEXP.test(email)) {
return false;
}
return true;
}
In your HTML (view)
<div class="form-group">
<label>Email address</label>
<input type="email" class="form-control" [(ngModel)]="user.email"
placeholder="Email address" required ngControl="email"
#email="ngForm"
(keyup)="emailValidator(email.value) == false ? emailValid = false : emailValid = true">
<div [hidden]="emailValid || email.pristine" class="alert alert-sm alert-danger">Email address is invalid</div>
</div>
Another option (required field + validate when user leaves the field)
<div class="form-group">
<label for="registerEmail">Email address</label>
<input type="email" class="form-control" [(ngModel)]="user.email"
placeholder="Email address" required ngControl="email"
#email="ngForm"
(blur)="emailValidator(email.value) == true ? emailIsInvalid = false : emailIsInvalid = true">
<div [hidden]="email.valid || email.pristine" class="alert alert-sm alert-danger">This field is required</div>
<div [hidden]="!emailIsInvalid" class="alert alert-sm alert-danger">Email address is invalid</div>
</div>
This method will work with any validation, so you could change the RegEx and validate Credit Card, Date, Time etc...
Upvotes: 7
Reputation: 19640
Update For Angular 4
ngOnInit() {
this.user = new FormGroup({
name: new FormGroup({
firstName: new FormControl('',Validators.required),
lastName: new FormControl('')
}),
age: new FormControl('',null,validate),
email: new FormControl('',emailValidator),
// ...
});
}
Validator
export function emailValidator(control: AbstractControl):{[key: string]: boolean} {
var EMAIL_REGEXP = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (control.value != "" && (control.value.length <= 5 || !EMAIL_REGEXP.test(control.value))) {
return {invalid:true};
}
return null;
}
Template
<div class="row">
<div class="col-md-12">
<md-input-container>
<input mdInput type="text" placeholder="Email" formControlName="email">
</md-input-container>
</div>
</div>
<div class="row">
<div class="col-md-12">
<span *ngIf="user.get('email').touched && !user.get('email').valid && !user.get('email').pristine">
<small>Invalid email</small>
</span>
</div>
</div>
Upvotes: 1
Reputation: 9391
You can use Form Directives and Control to do this.
export class TestComponent implements OnInit {
myForm: ControlGroup;
mailAddress: Control;
constructor(private builder: FormBuilder) {
this.mailAddress = new Control(
"",
Validators.compose([Validators.required, GlobalValidator.mailFormat])
);
}
this.addPostForm = builder.group({
mailAddress: this.mailAddress
});
}
Import:
import { FormBuilder, Validators, Control, ControlGroup, FORM_DIRECTIVES } from 'angular2/common';
Then your GlobalValidator
class:
export class GlobalValidator {
static mailFormat(control: Control): ValidationResult {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
if (control.value != "" && (control.value.length <= 5 || !EMAIL_REGEXP.test(control.value))) {
return { "incorrectMailFormat": true };
}
return null;
}
}
interface ValidationResult {
[key: string]: boolean;
}
And then your HTML:
<div class="form-group">
<label for="mailAddress" class="req">Email</label>
<input type="text" ngControl="mailAddress" />
<div *ngIf="mailAddress.dirty && !mailAddress.valid" class="alert alert-danger">
<p *ngIf="mailAddress.errors.required">mailAddressis required.</p>
<p *ngIf="mailAddress.errors.incorrectMailFormat">Email format is invalid.</p>
</div>
</div>
For more information about this, you can read this good article : https://medium.com/@daviddentoom/angular-2-form-validation-9b26f73fcb81#.jrdhqsnpg or see this github project for a working example.
(edit : that reg ex does not seem to check for a dot in the domain
I use this one instead
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
Upvotes: 49
Reputation: 2416
You can do only using html:
<md-input-container class="md-icon-float md-block" flex-gt-sm>
<label>Email</label>
<input md-input
id="contact-email"
type="text"
ngControl="email"
#email="ngForm"
[(ngModel)]="contact.email"
required
pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,6})+$">
<div class="md-errors-spacer" [hidden]="email.valid || email.untouched">
<div class="md-char-counter" *ngIf="email.errors && email.errors.required">
Email is required
</div>
<div class="md-char-counter" *ngIf="email.errors && email.errors.pattern">
Email is invalid
</div>
</div>
</md-input-container>
Upvotes: 77
Reputation: 381
I'm using : https://www.npmjs.com/package/ng2-validation
npm install ng2-validation --save ng2-validation
I'm not responding exaclty your question but for a lot of common scenarios you can find a custom validator already implemented
example in your case : email : ['', [CustomValidators.email]]
Best Reagards,
Upvotes: 0
Reputation: 7302
For angular 4 and above:
According to This you can use "email validator".
Example:
If you use template-driven forms:
<input type="email" name="email" email>
<input type="email" name="email" email="true">
<input type="email" name="email" [email]="true">
If you use model-driven forms(aka ReactiveFormsModule) use Validators.email:
this.myForm = this.fb.group({
firstName: ['', [<any>Validators.required]],
email: ['', [<any>Validators.required, <any>Validators.email]],
});
Old answer: You can use angular 2 FormGroup,
By using validators.pattern and regex like this:
let emailRegex = '^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$';
this.myForm = this.fb.group({
firstName: ['', [<any>Validators.required]],
email: ['', [<any>Validators.required, <any>Validators.pattern(emailRegex) ]],
});
Upvotes: 65
Reputation: 4174
Also you can use ng2-validation-manager for reactive forms which makes validation match easier:
this.form = new ValidationManager({
'email' : 'required|email',
'password' : 'required|rangeLength:8,50'
});
and the view:
<form [formGroup]="form.getForm()" (ngSubmit)="save()">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" formControlName="email">
<div *ngIf="form.hasError('email')" class="alert alert-danger">
{{form.getError('email')}}
</div>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" formControlName="password">
<div *ngIf="form.hasError('password')" class="alert alert-danger">
{{form.getError('password')}}
</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
Upvotes: 1
Reputation: 2141
I think nowadays you can use browser validation here. Email fields has a decent support and you can get validation result from element.validity.valid
. You just need to pass this through the Angular custom validator
See https://developer.mozilla.org/en-US/docs/Web/API/ValidityState and http://caniuse.com/#feat=input-email-tel-url for details
Upvotes: 0
Reputation: 1530
Yet another way to do this is using a custom directive. I like this approach as it's more consistent with the other ng2 validators.
import { Directive, forwardRef } from '@angular/core';
import { NG_VALIDATORS } from '@angular/forms';
import { Validator, AbstractControl } from '@angular/forms';
@Directive({
selector: '[validateEmail][formControlName], [validateEmail][formControl],[validateEmail][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EmailValidator), multi: true }
]
})
export class EmailValidator implements Validator {
constructor() {
}
validate(c: AbstractControl) {
let EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
return EMAIL_REGEXP.test(c.value) ? null : {
validateEmail: {
valid: false
}
};
}}
Then usage in html is
<input class="form-control"
type="email"
[(ngModel)]="user.emailAddress"
name="emailAddress"
placeholder="[email protected]"
validateEmail
Upvotes: 6
Reputation: 940
I guess just now there is no email validator, but it's pretty easy to add a custom one. See this demo I used the same regex as angular1 uses.
function emailValidator(control) {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
if (!EMAIL_REGEXP.test(control.value)) {
return {invalidEmail: true};
}
}
Upvotes: 4