javascript angularjs 验证输入并在无效时防止更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18241558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
angularjs validate input and prevent change if invalid
提问by kannix
I neeed an input field where I can enter only the values 1,2 or 3 so i'm trying to build a directive which prevents all changes to the model if it doesn't match these values.
eg the value is 1 and I change it to 5 it should be still 1.
我需要一个输入字段,我只能在其中输入值 1,2 或 3,因此我正在尝试构建一个指令,如果模型与这些值不匹配,该指令将阻止对模型的所有更改。
例如,值是 1,我将其更改为 5,它应该仍然是 1。
I've put together a small fiddle http://jsfiddle.net/kannix/Q5YKE/but it's most likely wrong to use the $parsers.
我已经整理了一个小小提琴http://jsfiddle.net/kannix/Q5YKE/但使用 $parsers 很可能是错误的。
app.directive('myvalidator', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
var validValues = [1,2,3];
ctrl.$parsers.push(function (value) {
if (validValues.indexOf(value) === -1){
//what to do here? should refuse wrong value and leave the old one
}
});
}
}
})
采纳答案by Brian Lewis
You could always listen to the keypress
event and prevent the character from making it through. Here is a plunker
您可以随时收听keypress
事件并阻止角色通过。这是一个plunker
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.validValues = ['a','1','2'];
});
app.directive('myValidator', function ($parse) {
return {
scope: {
validValues: '=validValues'
},
link: function (scope, elm, attrs) {
elm.bind('keypress', function(e){
var char = String.fromCharCode(e.which||e.charCode||e.keyCode), matches = [];
angular.forEach(scope.validValues, function(value, key){
if(char === value) matches.push(char);
}, matches);
if(matches.length == 0){
e.preventDefault();
return false;
}
});
}
}
});
回答by Ian Haggerty
I recently wrote a directive just for this. It takes a regExp object that validates the incoming key presses and only permits them if are valid:
我最近为此编写了一个指令。它需要一个 regExp 对象来验证传入的按键,并且仅在有效时才允许它们:
// forces keystrokes that satisfy the regExp passed
app.directive("regExpRequire", function() {
var regexp;
return {
restrict: "A",
link: function(scope, elem, attrs) {
regexp = eval(attrs.regExpRequire);
var char;
elem.on("keypress", function(event) {
char = String.fromCharCode(event.which)
if(!regexp.test(elem.val() + char))
event.preventDefault();
})
}
}
})
Template usage: <input type="text" reg-exp-require="/^[a-zA-Z]$/">
模板用法: <input type="text" reg-exp-require="/^[a-zA-Z]$/">
Or in your case: <input type="text" reg-exp-require="/^[1-3]*$/">
或者在你的情况下: <input type="text" reg-exp-require="/^[1-3]*$/">
回答by Mobiletainment
I'd recommend using the ng-pattern-restrict
directive.
我建议使用该ng-pattern-restrict
指令。
Get the libraryand simply decorate your input like so:
获取库并简单地装饰您的输入,如下所示:
<input type="text" pattern="[0-9]+" ng-pattern-restrict />
GitHub: AlphaGit/ng-pattern-restrict
GitHub: AlphaGit/ng-pattern-restrict
回答by coblr
I've actually had to build onto and modify the answer form Ian Haggerty. His code worked well, until I started to test it in different ways. I was specifically trying to test for values less than 100, but I was getting some strange results.
我实际上不得不建立并修改 Ian Haggerty 的答案表。他的代码运行良好,直到我开始以不同的方式对其进行测试。我专门尝试测试小于 100 的值,但得到了一些奇怪的结果。
If I had 100 in my input, then tried to insert a decimal to make it 10.0, Ian's fix didn't account for this and said it wasn't matching my regex (even though I allow up to two decimals). Turns out that it always appended the character that I pressed at the END of the string it was testing, even though I was inserting it in the middle.
如果我的输入中有 100,然后尝试插入一个小数以使其成为 10.0,Ian 的修复没有考虑到这一点,并说它与我的正则表达式不匹配(即使我允许最多两位小数)。事实证明,它总是将我按下的字符附加到它正在测试的字符串的末尾,即使我将它插入中间。
My change was to store the original value on "keypress", then on "keyup" (or "change" if you prefer), it does the checking of the new value. If invalid, then it reverts back to the original.
我的更改是将原始值存储在“keypress”上,然后在“keyup”(或“change”,如果您愿意)上,它会检查新值。如果无效,则恢复为原始状态。
Unfortunately it does update the model briefly, but at least it lets you type characters in the middle or beginning of the input value and still match against the regex correctly. In Angular 1.3, we can probably use ng-model-options="{debounce:250}" to counter this. Having any code that relies on this model change be indempotent helps immensely.
不幸的是,它确实短暂地更新了模型,但至少它允许您在输入值的中间或开头键入字符,并且仍然正确匹配正则表达式。在 Angular 1.3 中,我们可能可以使用 ng-model-options="{debounce:250}" 来解决这个问题。让任何依赖此模型更改的代码都是幂等的,这将有很大帮助。
usage: <input ... validate-with="/^([\d]{1,2}\.[\d]{1,2}|\.?[\d]{1,2}|100)?$/" />
.directive("validateWith", [function(){
return {
restrict: "A",
link: function($scope, $el, $attrs){
var regexp = eval($attrs.validateWith);
var origVal;
// store the current value as it was before the change was made
$el.on("keypress", function(e){
origVal = $el.val();
});
// after the change is made, validate the new value
// if invalid, just change it back to the original
$el.on("keyup", function(e){
if(!regexp.test($el.val())){
$el.val(origVal);
}
});
}
}
}]);