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

  • aaa@aaa
  • aaa---aaa@gmail.com
  • aaa`aaa@aaa

Expected Valid Emails

  • aabc@ddd.com
  • aaa.aaa@fddd.co.in
  • aaa@ddd.co.uk
Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
  • 4
    abc@abc is as far as I know a valid local domain email address. - and ` are also valid characters in an email address – ivarni May 15 '14 at 07:41
  • 2
    Here is the regexp angular is using btw: https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L12 – ivarni May 15 '14 at 07:48
  • check this you can use ng-messages http://stackoverflow.com/questions/24490668/how-to-validate-email-id-in-angularjs-using-ng-pattern/38463063#38463063 – arun-r Jul 19 '16 at 15:43

6 Answers6

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

Community
  • 1
  • 1
jackypan1989
  • 2,786
  • 1
  • 13
  • 11
  • 11
    This fails if the first letter of the email is capitalized. I.e. Bob@company.com fails, but bob@company.com does not. I used this regex instead - `ng-pattern=".{1,}@[_a-z0-9A-Z]+(\.[a-z0-9A-Z]+)+"` – Jon Mattingly Feb 28 '15 at 22:36
  • 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 – Pakk May 26 '15 at 20:52
  • 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... – Don Simon Sep 24 '15 at 11:48
  • 1
    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. – Don Simon Sep 24 '15 at 11:54
  • 6
    Only worked for me when I used `pattern` instead of `ng-pattern` – Spadar Shut Jan 21 '16 at 09:15
  • building on JonMattingly 's and Spaldar 's answers, here's what works for me: `ng-pattern="/^.{1,}@[_a-z0-9A-Z]+(\.[a-z0-9A-Z]+)+$/"` – Miguel Hughes Nov 14 '16 at 18:09
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.

Re Captcha
  • 3,125
  • 2
  • 22
  • 34
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>
so-random-dude
  • 15,277
  • 10
  • 68
  • 113
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>
Community
  • 1
  • 1
Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
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/>
dball
  • 374
  • 2
  • 10
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.

deepakssn
  • 5,195
  • 2
  • 24
  • 19