Проверка нескольких адресов электронной почты в одном поле

Есть ли способ проверить один или несколько адресов электронной почты в одном поле ввода?

Способ, которым я сейчас занимаюсь, заключается в создании настраиваемой директивы, которая будет разделять входные данные на разные электронные письма, если будет обнаружена запятая. Это то, что у меня есть до сих пор:

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

Проблема, связанная с этим, заключается в том, что я не смог вручную вызвать проверку подлинности angular.

Изменить: plunkr

Редактировать 2: Оказывается, что я могу использовать angular 1.3

Ответ 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 = /\[email protected]\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;
          }
        // })
      });
    }
  };
});

Ответ 2

Вы можете использовать ngPattern

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

где someRegex задается шаблон адреса электронной почты, разделенный запятой.

У AngularJS input.js есть EMAIL_REGEXP, который можно повторно использовать для восстановления шаблона. Это то же самое, что и проверка input[email].

или что-то в этом роде

Проверка динамического ng-шаблона Angularjs

Ответ 3

Вместо того, чтобы полагаться на валидатор angular, я просто использовал другое регулярное выражение. Это то, с чем я столкнулся, что очень похоже на то, что показано здесь:

angular.module('myApp')
  .directive('multipleEmails', function () {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ctrl ) {
        var emailsRegex = /^[\W]*([\w+\-.%][email protected][\w\-.]+\.[A-Za-z]{2,4}[\W]*,{1}[\W]*)*([\w+\-.%][email protected][\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;
          }
        });
      }
    };
  });

Ответ 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;
            };
          }
        }
      }

    })();

Ответ 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;
                    };
                }
            }
        };
    });

Ответ 6

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

    function formData($scope) { $scope.emails = '[email protected], [email protected]';} 
    
    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>