正确过滤Angular中的输入字段

时间:2016-04-15 14:39:38

标签: angularjs regex angularjs-directive filter currency

我发现这个指令用于过滤货币字段,因此用户只需要输入并隐含小数。

效果很好,除非用户能够在两次按两次字母时输入一封信。我根本不希望他们能够写一封信。

我尝试更改type="number",但之后它只允许5位数,然后莫名其妙地消失。你可以在这个plunker看到这个:

http://plnkr.co/edit/Y1olj7Cdz7XKqRmE7BFb?p=preview

所以我需要在这一行中改变一些东西(正则表达式?):

var plainNumber = viewValue.replace(/[^\d|\-+]/g, '');

或以某种方式修复type =“number”以保持输入超过五位数。有人知道该怎么做吗?

2 个答案:

答案 0 :(得分:1)

我不熟悉AngularJS,但我可以告诉你的正则表达不完全符合你的意图。

你有这个:[^\d|\-+]

这是一个否定的char类。所有非数字,非+,非-和非|都匹配。另请注意,\d包含的内容超过[0-9],因为它可能会匹配波斯数字等。

我会使用:[^-+0-9]。通过将-直接放在^之后,它不需要转义。

您的解决方案的问题是您在删除字符之前等待输入字符。击键可能比你的场清除它们的速度快。

尽管在Angular或jQuery中没有任何经验,

我根据here

制作了完美无缺的作品

允许自由输入0-9。输入+-后,它永远不会添加到最后。相反,它出现在开头,覆盖任何现有的标志。也许你应该只运行代码片段并看看自己:



var app = angular.module('App', []);

app.controller('MainCtrl', function($scope) {});

app.directive('inputRestrictor', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ngModelCtrl) {
      var pattern = /[^+0-9-]/g;

      function fromUser(text) {
        if (!text)
          return text;

        var rep = /[+]/g;
        var rem = /[-]/g;
        rep.exec(text);
        rem.exec(text);
        var indexp = rep.lastIndex;
        var indexm = rem.lastIndex;
        text = text.replace(/[+-]/g, '');
        if (indexp > 0 || indexm > 0) {
          if (indexp > indexm) text = "+" + text;
          else text = "-" + text;
        }
        var transformedInput = text.replace(pattern, '');
        ngModelCtrl.$setViewValue(transformedInput);
        ngModelCtrl.$render();
        return transformedInput;
      }
      ngModelCtrl.$parsers.push(fromUser);
    }
  };
}]);

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.3.0-rc.2" data-semver="1.3.0-rc.2" src="  https://code.angularjs.org/1.3.0-rc.2/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="App">
    <div ng-controller="MainCtrl">
      <input type="text"  ng-model="inputValue" input-restrictor>
      <input type="submit" ng-click="getdata()" />
    </div>
  </body>

</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我从你的问题中得到的是:

  1. 只接受数字,用''
  2. 替换其他所有内容
  3. 保留2位小数
  4. 过滤用户的输入并以用户类型
  5. 反映/修改输入元素的值

    将输入值与ng-model绑定时,实际上幕后有两个主要值:$viewValue$modelValue。他们之间的简单关系是这样的:

    input DOM value -> $viewValue -> $modelValue

    $parsers仅在$viewValue$modelValue之间有效。因此问题是当您在parser中插入新的$parsers时,修改后的值只会影响$modleValue,因为您只需在解析函数中返回一个新值。

    $parsers是:

      

    每当控件从DOM读取值时,作为管道执行的函数数组。函数按数组顺序调用,每个函数都将返回值传递给下一个。最后一个返回值将转发到$ validators集合

    更多信息:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController# $解析器

    解析器函数中返回的值不会影响$viewValue,因此您需要做的是更改该值并反映输入DOM元素。

    代码示例:

    app.directive('format', ['$filter', function ($filter) {
        return {
            require: 'ngModel',
    
            link: function (scope, elem, attrs, ctrl) {
                if (!ctrl) return;
    
                ctrl.$parsers.unshift(function (viewValue) {
                    var plainNumber = viewValue.replace(/[^\d|\-+]/g, '');
                    //use angular internal 'number' filter
                    plainNumber = $filter('number')(plainNumber/100,2);
    
                    //update the $viewValue
                    ctrl.$setViewValue(plainNumber);
                    //reflect on the DOM element
                    ctrl.$render();
                    //return the modified value to next parser
                    return plainNumber;
                });
            }
        };
    }]);
    

    工作的plnkr在这里:http://plnkr.co/edit/aoBWhJhlJLiEhBm5hRNX?p=preview

    最后,当你输入第6位并消失的原因是:

    当您输入6位数时,浏览器会将您输入的数字转换并格式化为这种格式:'1,234.56'(注意COMMA',',分隔符可能会推迟到不同的浏览器上),您将看到控制台中有角度的警告:

      

    指定值“1,234.56”不是有效数字。该值必须与以下正则表达式匹配: - ?(\ d + | \ d +。\ d + + |。\ d +)([eE] [ - +]?\ d +)?

    由输入元素type='number'的限制引起,angular将执行额外的内部验证,以匹配由角度本身定义的规则。