Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable angulars type=email validation?

Tags:

angularjs

How would you go about disabling, or at the very least changing, how Angular validates type=email inputs?

Currently, if you use type=email, Angular essentially double validates.. as the Browser (Chrome in this case) validates the email, and then angular does too. Not only that, but what is valid in Chrome foo@bar is not valid in Angularjs.

The best i could find, is ng-pattern, but ng-pattern simply adds a 3rd pattern validation for the input type.. instead of replacing Angular's email validation. heh

Any ideas?

like image 349
Lee Olayvar Avatar asked Jan 18 '13 21:01

Lee Olayvar


People also ask

How do I validate an email address with regex?

With that in mind, to generally validate an email address in JavaScript via Regular Expressions, we translate the rough sketch into a RegExp : let regex = new RegExp('[a-z0-9]+@[a-z]+\.

What is used for validating AngularJS forms?

Form Validation AngularJS also holds information about whether they have been touched, or modified, or not. You can use standard HTML5 attributes to validate input, or you can make your own validation functions. Client-side validation cannot alone secure user input. Server side validation is also necessary.

How do I validate an email address without regex?

It's a lot harder to validate it without using regex that it is with them. 1) Count the number of '@' characters - it should be one. 2) Check the Domain and Local address lengths - the local is limited to 64 characters, and the total length of the pair is 255 characters. 3) Check that the address ends with a non '.


1 Answers

Note: This is example is for angular 1.2.0-rc.3. Things might behave differently on other versions

Like others have stated it is a bit complex to turn off angulars default input validation. You need to add your own directive to the input element and handle things in there. Sergey's answer is correct, however it presents some problems if you need several validators on the element and don't want the built in validator to fire.

Here is an example validating an email field with a required validator added. I have added comments to the code to explain what is going on.

Input element

<input type="email" required>

Directive

angular.module('myValidations', [])

.directive('input', function () {
  var self = {
      // we use ?ngModel since not all input elements 
      // specify a model, e.g. type="submit" 
      require: '?ngModel'
      // we need to set the priority higher than the base 0, otherwise the
      // built in directive will still be applied
    , priority: 1
      // restrict this directive to elements
    , restrict: 'E'
    , link: function (scope, element, attrs, controller) {
        // as stated above, a controller may not be present
        if (controller) {

          // in this case we only want to override the email validation
          if (attrs.type === 'email') {
            // clear this elements $parsers and $formatters
            // NOTE: this will disable *ALL* previously set parsers
            //       and validators for this element. Beware!
            controller.$parsers = [];
            controller.$formatters = [];

            // this function handles the actual validation
            // see angular docs on how to write custom validators
            // http://docs.angularjs.org/guide/forms
            //
            // in this example we are not going to actually validate an email
            // properly since the regex can be damn long, so apply your own rules
            var validateEmail = function (value) {
              console.log("Validating as email", value);
              if (controller.$isEmpty(value) || /@/.test(value)) {
                controller.$setValidity('email', true);
                return value;
              } else {
                controller.$setValidity('email', false);
                return undefined;
              }
            };

            // add the validator to the $parsers and $formatters
            controller.$parsers.push(validateEmail);
            controller.$formatters.push(validateEmail);
          }
        }
      }
  };
  return self;
})

// define our required directive. It is a pretty standard
// validation directive with the exception of it's priority.
// a similar approach must be take with all validation directives
// you would want to use alongside our `input` directive
.directive('required', function () {
  var self = {
      // required should always be applied to a model element
      require: 'ngModel'
    , restrict: 'A'
      // The priority needs to be higher than the `input` directive
      // above, or it will be removed when that directive is run
    , priority: 2
    , link: function (scope, element, attrs, controller) {
        var validateRequired = function (value) {
          if (value) {
            // it is valid
            controller.$setValidity('required', true);
            return value;
          } else {
            // it is invalid, return undefined (no model update)
            controller.$setValidity('required', false);
            return undefined;
          }

        };
        controller.$parsers.push(validateRequired);
      }
  };
  return self;
})
;

There you have it. You now have control over type="email" input validations. Please use a proper regex to test the email though.

One thing to note is that in this example validateEmail is run before validateRequired. If you need validateRequired to run before any other validations, then just prepend it to the $parsers array (using unshift instead of push).

like image 189
alterecco Avatar answered Oct 13 '22 14:10

alterecco