Angular指令忽略非数字输入。

21

我必须编写一些适用于IE8的代码。 我有一个ng-repeat创建了一个填充表格的内容:

<input production-qty type="text" class="input-mini" maxlength="3" ng-model="day.qtyA" ui-event="{ blur : 'updateProduction(day)' }" ng-disabled="day.type=='H'">

IE8不支持type=number

我希望有一个指令,可以忽略在该输入框中敲击的非数字按键……即0-9

我不想让用户输入abc等无效数据破坏模型,然后告诉他们这个值是无效的。与其后来告诉他们值无效,我宁可一开始就不让他们输入无效数据。


请参考 https://dev59.com/2mgu5IYBdhLWcg3wDS6j#12947995 中的示例,了解如何构建自定义验证器。 - Mark Rajcok
我不认为那会对我有所帮助。我不仅仅是想阻止数据进入模型...而且要防止它们出现在屏幕上。我想通过使用指令将输入类型=数字实现为类型=文本。 - Jason
很抱歉那个回答并不是特别有用。可以使用 $parser 来过滤在输入文本框中显示的内容。请查看我在答案中编写的 plunker。 - Mark Rajcok
4个回答

43

HTML:

<input production-qty type="text" maxlength="3" ng-model="qty1">

指令:

app.directive('productionQty', function() {
  return {
    require: 'ngModel',
    link: function (scope, element, attr, ngModelCtrl) {
      function fromUser(text) {
        var transformedInput = text.replace(/[^0-9]/g, '');
        console.log(transformedInput);
        if(transformedInput !== text) {
            ngModelCtrl.$setViewValue(transformedInput);
            ngModelCtrl.$render();
        }
        return transformedInput;  // or return Number(transformedInput)
      }
      ngModelCtrl.$parsers.push(fromUser);
    }
  }; 
});

Plunker参考链接。

另请参见在输入框中使用ng-model过滤器。我的答案是基于pkozlowski.opensource的答案。

我尝试了ng-pattern,但它并不能过滤文本框中显示的内容。它将$scope.qty1设置为undefined,但不需要的字符仍然会出现在文本框中。


1
这对我没有用,我不得不在函数fromUser的第一行添加以下代码:如果(text === undefined)返回文本; - epitka
1
@MarkRajcok - 在更频繁地使用Angular后,我意识到我可以将其作为“filtered-input”指令更加可用,该指令将正则表达式作为属性传递 :-) - Jason
如果我想要向输入添加2个指令 - 每个都通过push()添加到modelCtrl.$parsers中,该怎么办?在这种情况下似乎只有“梯子”被执行。 - Matthias Max
谢谢您的回答,对我很有帮助,我使用了angularjs 1.3.x。如果有人需要帮助,我最终添加了以下内容以防止光标在无效字符上跳到末尾:if(transformedInput !== inputValue) { var el = element[0]; var cursorPosition = el.selectionStart - 1; // minus one because the character entry advances the cursor position ngModelCtrl.$setViewValue(transformedInput); ngModelCtrl.$render(); el.setSelectionRange(cursorPosition, cursorPosition); } - zai chang
该方法在解析后移除了$error.required。 因此,$error.required验证器不再与此解析方法一起使用。 - sudhir
显示剩余2条评论

8

HTML:

<input type="number" name="graduationYear" ng-model="gradYear" only-num>

指令:

directive('onlyNum', function() {
    return function(scope, element, attrs) {

        var keyCode = [8, 9, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110];
        element.bind("keydown", function(event) {
            //console.log($.inArray(event.which,keyCode));
            if ($.inArray(event.which, keyCode) === -1) {
                scope.$apply(function() {
                    scope.$eval(attrs.onlyNum);
                    event.preventDefault();
                });
                event.preventDefault();
            }

        });
    };
});

这个功能很好,唯一的问题是它阻止了 CTRL+a - Guss

0

首先在 js 文件中包含以下代码:numericInput.js

指令:

.directive('numeric', function() {
    return function(scope, element, attrs) {

        $(element[0]).numericInput({ allowFloat: true });

    };
})

HTML:

 <input type="text" numeric />

演示 数字演示


1
尝试输入负数。 - Ronnie Overby
使用此<input type="number" numeric />...但您仍未输入减号,必须使用向下箭头键输入负数。 - Nishchit

-2

不是指令,而是我只使用:

控制器:

    $scope.blockNonNumber = function (val, field){

       $scope[field] = val.toString().replace(/[^0-9]/g, '');

    }

HTML:

<input type="text" ng-model="price" ng-change="blockNonNumber(price, 'price')" pattern="[0-99]">

它不是指令,但也可以在指令中使用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接