Angularjs动态ng模式验证

时间:2013-09-19 16:33:37

标签: angularjs angularjs-directive angularjs-ng-change

我有一个表单,如果复选框为false,则使用ng-required指令对文本输入强制执行验证。如果复选框为true,则隐藏该字段,并将ng-required设置为false。

问题是我还在输入上指定了验证的正则表达式,并使用了ng-pattern angular指令。我遇到的问题是,如果用户填写了无效的电话号码,请选中该框以停用该输入(因此无需进一步验证),表单将不允许提交,因为它基于ng-pattern无效。

我尝试通过添加ng-change函数来设置输入模型为null来解决此问题,但是ng-pattern和字段仍然在复选框的初始设置为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;
        }
    };

7 个答案:

答案 0 :(得分:174)

这是一个有趣的问题,复杂的角度验证。以下小提琴实现了您想要的:

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

详细

我创建了一个新指令rpattern,它是Angular的ng-required和来自ng-pattern的{​​{1}}代码的混合。它的作用是观察字段的input[type=text]属性,并在使用正则表达式进行验证时将其考虑在内,即如果不需要,则将字段标记为required

备注

  • 大部分代码来自Angular,根据需要量身定制。
  • 选中该复选框后,该字段为必填字段。
  • 当必填复选框为false时,不会隐藏该字段。
  • 演示文稿简化了正则表达式(有效数字为3位)。

一个(但更小)的解决方案,如果你不想要一个新的指令,将是这样的:

valid-pattern

在HTML中,不需要进行任何更改:

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

这实际上是通过调用我们的 <input type="text" ng-model="..." ng-required="requireTel" ng-pattern="phoneNumberPattern" /> 方法,而不是test()来考虑RegExp.test()

答案 1 :(得分:25)

没有采取任何措施远离Nikos的精彩回答,也许你可以更简单地做到这一点:

<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变量,则第二个输入不仅会被隐藏,而且根本不会被渲染,因此表单将通过验证并且按钮将变为启用状态,您将获得所需的内容。

答案 2 :(得分:5)

使用过的模式:

 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">

答案 3 :(得分:2)

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

答案 4 :(得分:2)

我前几天碰到了这个。

我所做的,比上面更容易,是在范围上的变量上设置模式,并在视图中以ng-pattern引用它。

当&#34;取消选中复选框&#34;我只是在onChanged回调上将正则表达式值设置为/.*/(如果要取消选中)。更改的ng-pattern选择并说'#34;好的,你的价值很好&#34;。表格现在有效。我也会从现场删除不良数据,这样你就不会有一个明显不好的电话#坐在那里。

我有关于ng-required的其他问题,并做了同样的事情。工作就像一个魅力。

答案 5 :(得分:0)

  

如果ngModel $ viewValue与通过评估属性值中给出的Angular表达式找到的RegExp不匹配,则设置模式验证错误键。如果表达式求值为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!#$%&'*+/=?^_`{|}~.-]+@example\.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

答案 6 :(得分:-1)

您可以使用网站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}"