Угловая динамическая проверка ng-шаблонов

У меня есть форма, которая, если флажок false, принудительно выполняет проверку на ввод текста с использованием директивы ng-required. Если флажок установлен верно, поле скрыто, а для ng-required установлено значение false.

Проблема в том, что у меня также есть регулярное выражение для проверки, указанное на входе, а также использование директивы ng-pattern angular. Проблема, с которой я сталкиваюсь, заключается в том, что если пользователь заполняет недействительный номер телефона, он проверяет флажок, чтобы деактивировать этот ввод (и, следовательно, не нуждается в дальнейшей проверке), форма не разрешает отправку, поскольку она недействительна на основе ng-шаблона.

Я попытался решить эту проблему, добавив функцию ng-change, чтобы установить модель ввода в значение null, однако ng-шаблон и, следовательно, поле по-прежнему установлено как недопустимое в исходном наборе флажка в значение false. Если я, однако, снимите флажок, установив все обратно на начальную загрузку формы, затем снова установите флажок, форма действительна и может подать. Я не уверен, что мне не хватает. Вот код ng-change, который у меня есть до сих пор:

    var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    $scope.phoneNumberPattern = phoneNumberRegex;
    $scope.removeValidation = function() {
        if ($scope.cell._newUser === false) {
            $scope.request._number = '';
            $scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
        } else {
            $scope.phoneNumberPattern = phoneNumberRegex;
        }
    };

Ответ 1

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

http://jsfiddle.net/2G8gA/1/

Подробнее

Я создал новую директиву rpattern, которая представляет собой сочетание Angular ng-required и кода ng-pattern от input[type=text]. То, что он делает, - это смотреть атрибут required этого поля и учитывать это при проверке с помощью регулярного выражения, т.е. Если не требуется поле метки как valid-pattern.

Примечания

  • Большая часть кода от Angular, с учетом потребностей этого.
  • Когда флажок установлен, поле требуется.
  • Поле не скрывается, когда установленный флажок установлен.
  • Регулярное выражение упрощается для демонстрации (допустимо 3 цифры).

Грязное (но меньшее) решение, если вы не хотите новую директиву, было бы чем-то вроде:

$scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    return {
        test: function(value) {
            if( $scope.requireTel === false ) {
                return true;
            }
            return regexp.test(value);
        }
    };
})();

И в HTML никаких изменений не потребуется:

<input type="text" ng-model="..." ng-required="requireTel"
    ng-pattern="phoneNumberPattern" />

Это фактически трюки Angular для вызова нашего метода test() вместо RegExp.test(), который учитывает required.

Ответ 2

Не снимая ничего из удивительного ответа Никоса, возможно, вы можете сделать это проще:

<form name="telForm">
  <input name="cb" type='checkbox' data-ng-modal='requireTel'>
  <input name="tel" type="text" ng-model="..." ng-if='requireTel' ng-pattern="phoneNumberPattern" required/>
  <button type="submit" ng-disabled="telForm.$invalid || telForm.$pristine">Submit</button>
</form>

Обратите внимание на второй вход: мы можем использовать ng-if для управления рендерингом и валидацией в формах. Если переменная requireTel не установлена, второй вход не будет скрыт, но не будет отображаться вообще, поэтому форма будет проходить проверку, и кнопка станет включенной, и вы получите то, что вам нужно.

Ответ 3

Используемый шаблон:

 ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"

Используемый ссылочный файл:

 '<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>'

Пример ввода:

 <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">

Ответ 4

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">

Ответ 5

Я просто столкнулся с этим на днях.

Что я сделал, что кажется проще, чем выше, это установить шаблон в переменной в области видимости и ссылаться на него в ng-образце в представлении.

Когда "флажок снят", я просто устанавливаю значение регулярного выражения в/.*/на обратном вызове onChanged (если он не установлен). ng-pattern выбирает, что меняется и говорит "ОК, ваше значение в порядке". Теперь форма действительна. Я также удалял бы плохие данные из поля, чтобы у вас не было явно плохого телефона #, сидящего там.

У меня были дополнительные проблемы вокруг ng-required, и я сделал то же самое. Работали как шарм.

Ответ 6

Задает ключ ошибки проверки шаблона, если ngModel $viewValue не совпадает с RegExp, найденным путем вычисления выражения Angular, указанного в значении атрибута. Если выражение оценивает объект RegExp, то это используется напрямую. Если выражение оценивается как строка, то оно будет преобразовано в RegExp после того, как оно будет помещено в символы ^ и $.

Похоже, что самый проголосовавший ответ в этом вопросе должен быть обновлен, потому что, когда я его пробую, он не применяет функцию test, а проверка не работает.

Пример из Angular docs работает хорошо для меня:

Изменение встроенных валидаторов

HTML

<form name="form" class="css-form" novalidate>
  <div>
   Overwritten Email:
   <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
   <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
   Model: {{myEmail}}
  </div>
</form>

JS

var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() {
    var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-][email protected]\.com$/i;

    return {
        require: 'ngModel',
        restrict: '',
        link: function(scope, elm, attrs, ctrl) {
            // only apply the validator if ngModel is present and Angular has added the email validator
            if (ctrl && ctrl.$validators.email) {

                // this will overwrite the default Angular email validator
                ctrl.$validators.email = function(modelValue) {
                    return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
                };
             }
         }
     };
 });

Plunker

Ответ 7

Вы можете использовать сайт https://regex101.com/ для создания своего собственного шаблона для определенной страны:

Например, Польша:

-pattern = xxxxxxxxx OR xxx-xxx-xxx OR xxx xxx xxx 
-regexp ="^\d{9}|^\d{3}-\d{3}-\d{3}|^\d{3}\s\d{3}\s\d{3}"