83

我有一个表单,如果复选框为 false,则使用 ng-required 指令对文本输入进行验证。如果复选框为真,则该字段被隐藏并且 ng-required 设置为假。

问题是我还使用了 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;
        }
    };
4

7 回答 7

176

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

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

细节

我创建了一个新指令,rpattern它是 Angularng-requiredng-pattern来自input[type=text]. 它的作用是观察required字段的属性,并在使用正则表达式进行验证时将其考虑在内,即如果不需要,则将字段标记为valid-pattern.

笔记

  • 大部分代码都来自 Angular,专门针对这个需求。
  • 选中复选框时,该字段为必填项。
  • 当必填复选框为 false 时,该字段不会隐藏。
  • 正则表达式为演示简化(有效为 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到 。

于 2013-09-24T14:48:21.853 回答
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>

注意第二个输入:我们可以使用 anng-if来控制表单中的渲染和验证。如果requireTel变量未设置,第二个输入不仅会被隐藏,而且根本不会呈现,因此表单将通过验证并且按钮将变为启用状态,您将获得所需的内容。

于 2014-07-23T08:30:33.883 回答
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">
于 2014-10-29T17:37:35.510 回答
2

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

于 2015-05-08T06:07:42.513 回答
2

我前几天刚碰到这个。

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

当“未选中复选框”时,我只需在 onChanged 回调(如果未选中)上将正则表达式值设置为 /.*/。ng-pattern 选择改变并说“好的,你的价值很好”。表格现在有效。我还会从该字段中删除不良数据,这样您就没有明显的不良电话#坐在那里。

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

于 2017-02-03T18:29:00.803 回答
0

如果 ngModel $viewValue 与通过评估属性值中给出的 Angular 表达式找到的 RegExp 不匹配,则设置模式验证错误键。如果表达式的计算结果为 RegExp 对象,则直接使用 this。如果表达式的计算结果为字符串,则在将其包装为 ^ 和 $ 字符后,它将被转换为正则表达式。

似乎应该更新这个问题中投票最多的答案,因为当我尝试它时,它不应用test功能并且验证不起作用。

Angular 文档中的示例对我很有用:

修改内置验证器

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

普朗克

于 2015-12-26T19:20:58.337 回答
-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}"
于 2015-09-30T08:38:49.187 回答