我有一个表单,如果复选框为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;
}
};
答案 0 :(得分:174)
这是一个有趣的问题,复杂的角度验证。以下小提琴实现了您想要的:
我创建了一个新指令rpattern
,它是Angular的ng-required
和来自ng-pattern
的{{1}}代码的混合。它的作用是观察字段的input[type=text]
属性,并在使用正则表达式进行验证时将其考虑在内,即如果不需要,则将字段标记为required
。
一个脏(但更小)的解决方案,如果你不想要一个新的指令,将是这样的:
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)
<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;
答案 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);
};
}
}
};
});
答案 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}"