在单个字段中验证多个电子邮件地址

时间:2014-12-01 17:17:54

标签: angularjs validation

有没有办法在单个输入字段中验证一个或多个电子邮件地址?

我目前正在探索的方法是创建一个自定义指令,如果检测到逗号,它会将输入拆分为不同的电子邮件。这就是我到目前为止所做的:

angular.module('myApp')
  .directive('multipleEmails', function () {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ctrl) {
        ctrl.$parsers.unshift(function(viewValue) {

          var emails = viewValue.split(',');
          // loop that checks every email, returns undefined if one of them fails.
        });
      }
    };
  });

我遇到的问题是我无法手动调用角度电子邮件验证程序。

修改:plunkr

编辑2:原来我可以使用angular 1.3

6 个答案:

答案 0 :(得分:14)

http://plnkr.co/edit/YrtXOphxkczi6cwFjvUp?p=preview

.directive('multipleEmails', function () {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {

        var emails = viewValue.split(',');
        // loop that checks every email, returns undefined if one of them fails.
        var re = /\S+@\S+\.\S+/;

        // angular.foreach(emails, function() {
          var validityArr = emails.map(function(str){
              return re.test(str.trim());
          }); // sample return is [true, true, true, false, false, false]
          console.log(emails, validityArr); 
          var atLeastOneInvalid = false;
          angular.forEach(validityArr, function(value) {
            if(value === false)
              atLeastOneInvalid = true; 
          }); 
          if(!atLeastOneInvalid) { 
            // ^ all I need is to call the angular email checker here, I think.
            ctrl.$setValidity('multipleEmails', true);
            return viewValue;
          } else {
            ctrl.$setValidity('multipleEmails', false);
            return undefined;
          }
        // })
      });
    }
  };
});

答案 1 :(得分:3)

我没有依赖角度验证器,而是最终使用了不同的正则表达式。这就是我最终得到的结果,这与此处显示的内容非常相似:

angular.module('myApp')
  .directive('multipleEmails', function () {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ctrl ) {
        var emailsRegex = /^[\W]*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{2,4}[\W]*,{1}[\W]*)*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{2,4})[\W]*$/;
        ctrl.$parsers.unshift(function(viewValue) {
          if (emailsRegex.test(viewValue)) {
            ctrl.$setValidity('multipleEmails', true);
            return viewValue;
          } else {
            ctrl.$setValidity('multipleEmails', false);
            return undefined;
          }
        });
      }
    };
  });

答案 2 :(得分:2)

您可以使用ngPattern

<input ng-model="mymodel.attribute" required ng-pattern="someRegex">

其中someRegex设置为以逗号分隔的电子邮件地址模式。

AngularJS input.js 有EMAIL_REGEXP,您可以重复使用它来重建模式。这与input[email]验证相同。

或沿着这些方向的东西

Angularjs dynamic ng-pattern validation

答案 3 :(得分:2)

这很简单..请注意,在使用此指令时,您的输入类型应为电子邮件。

// Html

 <input name="emailTextbox" type="email" email-validator 
 ng-model="vm.emailAdd"/>   

//指令

  (function() {
      'use strict';

      angular
      .module('myApp')
      .directive('emailValidator', emailValidator);

      emailValidator.$inject = ['_'];
      /* @ngInject */
      function emailValidator(_) {
        var EMAIL_REGEXP = /^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;

        var directive = {
          require: 'ngModel',
          restrict: 'A',
          link: linkFunc
        };

        return directive;

        function linkFunc(scope, elm, attrs, ctrl) {

          if (ctrl && ctrl.$validators.email) {
            ctrl.$validators.email = function(modelValue) {
              if (angular.isDefined(modelValue)) {
                var isValidEmails = ctrl.$isEmpty(modelValue) || modelValue.split(',').every(
                  function (email) {
                    return EMAIL_REGEXP.test(email.trim());
                  }
                );
              }             
              return isValidEmails;
            };
          }
        }
      }

    })();

答案 4 :(得分:1)

&#13;
&#13;
angular.module('app1', [])
    .controller('appCont', formData)
    .directive('emailValidator', emailValidator);

    function formData($scope) { $scope.emails = 'hcl@hcl.com, mail@rrk.com';} 
    
    function emailValidator() {
        var EMAIL_REGEXP = /^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;

        function multiEmailValidationInTextBox(scope, elm, attrs, ctrl) {
            ctrl.$parsers.unshift(function(modelValue) {
                var isEmailsValid = true
                ,   isLastEmailValid = false;;
                
                if (angular.isDefined(modelValue)) {
                    if (!ctrl.$isEmpty(modelValue)) {
                        var splitEmails = modelValue.split(',')
                        ,   emailLength = splitEmails.length;

                        if (emailLength < 1) {
                            isValidEmails = EMAIL_REGEXP.test(splitEmails[0].trim()); 
                        } else {
                            angular.forEach(splitEmails, function(item, index) {
                                if (!EMAIL_REGEXP.test(splitEmails[index].trim()) && index != emailLength-1) {
                                    isValidEmails = false;                    
                                }
                            });

                            var lastEmail = splitEmails[emailLength-1].trim();
                            if (ctrl.$isEmpty(lastEmail) || 
                                (!ctrl.$isEmpty(lastEmail) && EMAIL_REGEXP.test(lastEmail)) ) {
                                isLastEmailValid = true;
                            }

                        }
                    }
                }        

                if (isEmailsValid && isLastEmailValid) {
                    elm.removeClass('has-error');
                    elm.addClass('has-success');
                } else {
                    elm.addClass('has-error');
                    elm.removeClass('has-success');
                }

                return isEmailsValid;
            });
        }

        return {
            require: 'ngModel',
            restrict: 'A',
            link: multiEmailValidationInTextBox
        };
    }
&#13;
.has-error { background-color: red; }
        .has-success { background-color: #afdcaf; }

        input[type="text"] {
            width: 500px;
            font-family: sans-serif, monospace;
            font-size: 25px;
            border: 1px solid grey;
            border-radius: 4px;
            height: 30px;
            padding: 3px;
        }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app1" ng-controller="appCont"> <div>

    <input name="emailTextbox" type="text" email-validator ng-model="emails"/></div>

</body>
&#13;
&#13;
&#13;

答案 5 :(得分:0)

我知道这是一个迟到的答案,但尽可能使用Angular 1.x逻辑,只添加了多个支持。其他答案都使用自己的验证正则表达式。

<input type="email" data-ng-multiple-email data-ng-model="$ctrl.x">

angular.module("myApp")
    .directive("ngMultipleEmail", function () {
        return {
            restrict: "A",
            require: "?ngModel",
            link: function (scope, elm, attrs, ctrl) {
                if (ctrl && ctrl.$validators.email) {
                    let originalValidator = ctrl.$validators.email;
                    ctrl.$validators.email = function (modelValue,   viewValue) {
                        var value = modelValue || viewValue || "",
                            valueSplit = value.split(/[,;]+/);
                        valueSplit.forEach(function (email) {
                            var valid = originalValidator(email.trim());
                            if (!valid) {
                                return false;
                            }
                        });
                        return true;
                    };
                }
            }
        };
    });