24

I am using Angular for form validation.

Here is what I use - plunker-edit I have taken this code from Angularjs documentation - Binding to form and control state Have used type as email but when I run this and enter abc@abc it says it is valid. How do I fix this ?

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-example100-production</title>


  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.8/angular.min.js"></script>
  <script src="script.js"></script>



</head>
<body ng-app="">
    <div ng-controller="Controller">
    <form name="form" class="css-form" novalidate>
      E-mail:
        <input type="email" ng-model="user.email" name="uEmail" required/><br />
      <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid:
        <span ng-show="form.uEmail.$error.required">Tell us your email.</span>
        <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
      </div>
    </form>
  </div>
</body>
</html>

P.S : I am a beginner in AngularJs

Edit:

Also the following inputs wer also shown valid

Expected Valid Emails

3

6 Answers 6

36

Refer to my another answer: AngularJS v1.3.x Email Validation Issue

Try to use ng-pattern in your email input.

<input type="email" name="input" ng-model="text" ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/" required>

It fits your valid and invalid cases.

See an example: plunk

Sign up to request clarification or add additional context in comments.

6 Comments

This fails if the first letter of the email is capitalized. I.e. [email protected] fails, but [email protected] does not. I used this regex instead - ng-pattern=".{1,}@[_a-z0-9A-Z]+(\.[a-z0-9A-Z]+)+"
when i use the ng-pattern at all it gives me "Failed to load template" - any idea why? - copied the code over, no errors before
Weirdly it works fine for me in terms of angular adding the ng-invalid class based on the pattern while the form.input.$error.email property seems to still be set based on the built in email validation. So my styling of the input box works fine but the error message shows up falsly...
Not so weird after all, the email error is for the built in email validation, to use the pattern check "form.input.$error.pattern". Makes sense.
Only worked for me when I used pattern instead of ng-pattern
|
3

These emails are valid, as they can be local emails or to an intranet email server: Domains.

The TLD is not required for local emails. As shown in the Wikipedia example, the domain may even contain an IP Address in place of the domain.

3 Comments

In my case user would be entering his/her email address with a tld. How do I validate in that case ?
@Yasser You could use custom validation in your case, using a custom regex.
@ReCaptcha, reference link is worth to read.. At least came to know why angularJs has made a@a a valid email
2

Even better, now, Angular has email validator built-in, from Angular 4 onwards https://github.com/angular/angular/blob/master/CHANGELOG.md#features-6 https://github.com/angular/angular/pull/13709

Just add email to the tag. For example

  <form #f="ngForm">
    <input type="email" ngModel name="email" required email>
    <button [disabled]="!f.valid">Submit</button>
    <p>Form State: {{f.valid?'VALID':'INVALID'}}</p>
  </form>

Comments

1

As ReCaptcha suggested I ended up creating a custom validation directive

var app = angular.module('login-form', []);
var INTEGER_REGEXP = new RegExp('^[a-z0-9]+(\.[_a-z0-9]+)*@@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,50})$', 'i');
app.directive('cemail', function () {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue) {
                if (INTEGER_REGEXP.test(viewValue)) {
                    // it is valid
                    ctrl.$setValidity('cemail', true);
                    return viewValue;
                } else {
                    // it is invalid, return undefined (no model update)
                    ctrl.$setValidity('cemail', false);
                    return undefined;
                }
            });
        }
    };
});

and in html

<label>Email</label>
<input id="UserName" name="UserName" type="text" value="" data-ng-model="email" required="" cemail>
<span data-ng-show="form.UserName.$dirty && form.UserName.$invalid">
    <span data-ng-show="form.UserName.$error.required">Required</span>
    <span data-ng-show="form.UserName.$error.cemail">Invalid Email</span>
</span>

Comments

0

I have written a directive that uses the same email validation regular expression that ASP.Net uses. While this may not cover 100% of scenarios, it will cover the vast majority and works perfectly for what we need to cover.

function email() {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, elem, attrs, ctrl) {
        if (!ctrl) {
            return false;
        }

        function isValidEmail(value) {
            if (!value) {
                return false;
            }
            // Email Regex used by ASP.Net MVC
            var regex = /^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$/i;
            return regex.exec(value) != null;
        }

        scope.$watch(ctrl, function () {
            ctrl.$validate();
        });

        ctrl.$validators.email = function (modelValue, viewValue) {
            return isValidEmail(viewValue);
        };
    }
};
}    

Use it like this:

<input type="email" ng-model="$scope.emailAddress" name="newEmailAddress" email/>

Comments

0

Angular 6

I generally don't want to allow $$$@$$$ format and always expect a TLD (like .com, .net, .org, etc).

In addition to angular email validator I add my regex pattern to make it work.

 <input type="email" name="email" pattern="^\S*[@]\S*[.]\S*$" email required />

pattern="^\S*[@]\S*[.]\S*$" will make sure that there is a @ and a . followed by a string. This will be an addition to Angular's email validation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.