Question

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
Was it helpful?

Solution

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

OTHER TIPS

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.

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>

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>

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/>

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top