【问题标题】:Validate multiple email addresses in single field在单个字段中验证多个电子邮件地址
【发布时间】:2014-12-01 17:17:54
【问题描述】:

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

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

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

【问题讨论】:

  • ctrl.$parsers 是一个数组,自己动手吧!但这听起来绝对像是一个糟糕的用户界面。
  • @Blackhole 你能给我一个例子来说明它是如何工作的吗?我希望用户界面可以改变,但我认为这是不可能的:(
  • 你可以用空格而不是逗号分割,删除逗号,然后检查有效性并设置有效性
  • @Blackhole - 根据我的经验,带有分隔电子邮件地址的输入字段在 UI(即 Outlook)和服务器端代码中很常见。地址由逗号或分号分隔。
  • @SoluableNonagon 不确定这如何测试电子邮件的有效性

标签: angularjs validation


【解决方案1】:

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;
          }
        // })
      });
    }
  };
});

【讨论】:

  • 谢谢,太好了。如果您还想允许空输入,请执行以下操作:var validityArr = emails.map(function (str) { if (viewValue) { return regexPattern.test(str.trim()); } else if (!viewValue) { return true; } }); // sample return is [true, true, true, false, false, false]
  • 为了支持“显示名称 ”,我改用这个正则表达式测试:var re = /^(?:([\w\s]+)\s*<(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}>|(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6})$/;
【解决方案2】:

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

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;
          }
        });
      }
    };
  });

【讨论】:

    【解决方案3】:

    你可以使用ngPattern

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

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

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

    或类似的东西

    Angularjs dynamic ng-pattern validation

    【讨论】:

      【解决方案4】:

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

      //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;
                  };
                }
              }
            }
      
          })();
      

      【讨论】:

      • 这不会验证 .travel、.museum 等更长的 TLD。
      • 好的@Episodex...试试这个正则表达式而不是以前的... var EMAIL_REGEXP = /^[_a-z0-9]+(\.[_a-z0-9]+)* @[a-z0-9-]+(\.[a-z0-9-]+)*(\.[az]{2,20})$/;
      • 如何访问父控制器中的结果?
      【解决方案5】:

      我知道这是一个迟到的答案,但尽可能使用 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;
                          };
                      }
                  }
              };
          });
      

      【讨论】:

      • ctrl.$validators.email 函数总是返回true。考虑every() 而不是forEach()
      【解决方案6】:

      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
              };
          }
      .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;
              }
      <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>

      【讨论】:

        猜你喜欢
        • 2017-01-31
        • 2013-10-14
        • 1970-01-01
        • 2018-08-21
        • 2019-09-28
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 2011-11-07
        相关资源
        最近更新 更多