【问题标题】:angularjs: allows only numbers to be typed into a text boxangularjs:只允许在文本框中输入数字
【发布时间】:2013-04-12 01:20:20
【问题描述】:

在 angularjs 中是否有任何可用的功能只允许在文本框中输入数字like

【问题讨论】:

标签: javascript ruby-on-rails angularjs numeric


【解决方案1】:

此代码显示了如何防止输入非数字符号的示例。

angular.module('app').
  directive('onlyDigits', function () {

    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, modelCtrl) {
            modelCtrl.$parsers.push(function (inputValue) {
                if (inputValue == undefined) return '';
                var transformedInput = inputValue.replace(/[^0-9]/g, '');
                if (transformedInput !== inputValue) {
                    modelCtrl.$setViewValue(transformedInput);
                    modelCtrl.$render();
                }
                return transformedInput;
            });
        }
    };
});

【讨论】:

  • 谢谢。我简化了非数字剥离,写了一个测试:gist.github.com/henrik/769d49136744ddcaa1dc 在写这篇文章的时候,代码是 JS 但测试是 CoffeeScript。我想很快两者都会成为 CoffeeScript。
  • 双击字母键会失败
  • 正如 Blowsie 所指出的,此代码并非在所有情况下都有效。这是一个有效的 jsfiddle,我正在尝试更新此答案以使用:jsfiddle.net/thomporter/DwKZh
  • 如果要显式禁用空格输入,则该指令应与 ng-trim=false 一起使用
  • 用户可以输入空格。在解析器之前添加attrs.$set('ngTrim', "false"); 以防止空格。
【解决方案2】:

HTML

 <input type="text" name="number" only-digits>

// 只需输入 123

  .directive('onlyDigits', function () {
    return {
      require: 'ngModel',
      restrict: 'A',
      link: function (scope, element, attr, ctrl) {
        function inputValue(val) {
          if (val) {
            var digits = val.replace(/[^0-9]/g, '');

            if (digits !== val) {
              ctrl.$setViewValue(digits);
              ctrl.$render();
            }
            return parseInt(digits,10);
          }
          return undefined;
        }            
        ctrl.$parsers.push(inputValue);
      }
    };
});

// 类型:123 或 123.45

 .directive('onlyDigits', function () {
    return {
      require: 'ngModel',
      restrict: 'A',
      link: function (scope, element, attr, ctrl) {
        function inputValue(val) {
          if (val) {
            var digits = val.replace(/[^0-9.]/g, '');

            if (digits.split('.').length > 2) {
              digits = digits.substring(0, digits.length - 1);
            }

            if (digits !== val) {
              ctrl.$setViewValue(digits);
              ctrl.$render();
            }
            return parseFloat(digits);
          }
          return undefined;
        }            
        ctrl.$parsers.push(inputValue);
      }
    };
 });

【讨论】:

  • 您的第二个示例(// 类型:123 或 123.45)允许输入多个小数位,例如11.22..33.....444 将返回有效。
  • 我认为我们可以使用以下 if (digits.split('.').length > 2) digits = digits.substring(0, digits.length - 1);
  • 为什么 angularjs 中的代码如此冗长,而普通 javascript 中的代码却很简单以满足相同的要求??
  • 如何将其限制为 2 位数字?
  • @Bharath 仅限制 2 个小数 --> if (digits.split('.').length > 1) { digits = digits.substring(0, digits.indexOf('.') + 3); }
【解决方案3】:

我只是在输入指令中使用了 ng-keypress。

HTML:

<input type="text" ng-keypress="filterValue($event)"/>

JS:

$scope.filterValue = function($event){
        if(isNaN(String.fromCharCode($event.keyCode))){
            $event.preventDefault();
        }
};

【讨论】:

  • 虽然这不是真正的“角度方式”,但它似乎是防止用户输入的相对安全的选择
  • 这看起来很简单,虽然非角度的方式可能会阻止一些,但我绝对喜欢这种方法。不得不添加另外两个必须允许的情况,event.which === 8 和 event.which === 46(分别用于退格和删除)
  • 不错的解决方案!我使用@Markiv 评论改进了new answer 中的代码,允许编辑、提交和导航。
  • 我喜欢这个解决方案,尽管值被修剪 => 我稍微改变了条件以防止按下空格键: if( isNaN(String.fromCharCode($event.keyCode)) || $event.keyCode === 32)
  • Keypress 事件已弃用,部分浏览器(即 Chrome)不支持。 Keydown 事件也很可疑 - 在某些设备 Nexus4 上,它不会报告正确的键码。唯一真正的方法(afaik)是不使用字符,而是使用实际的真实文本。
【解决方案4】:

此功能正是您所需要的。 http://docs.angularjs.org/api/ng.directive:input.number

编辑:

您可以将 jquery 插件包装到指令中。我在这里创建了一个示例:http://jsfiddle.net/anazimok/jTJCF/

HTML:

<div ng-app="myApp">
    <div>
        <input type="text" min="0" max="99" number-mask="" ng-model="message">
            <button ng-click="handleClick()">Broadcast</button>
    </div>

</div>

CSS:

.ng-invalid {
    border: 1px solid red;
}

JS:

// declare a module
var app = angular.module('myApp', []);

app.directive('numberMask', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            $(element).numeric();
        }
    }
});

【讨论】:

  • 不完全是 OP 所要求的。您的解决方案提供输入验证(即在检测到非数字时显示错误),但用户仍然可以在文本框中键入非数字。
  • @AliHasan 这不应该是正确答案,因为它没有回答问题。
【解决方案5】:

这是最简单、最快的方法,只允许输入数字。

<input type="text" id="cardno" placeholder="Enter a Number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' required>

谢谢

【讨论】:

  • 如果你能把它放在一个指令中,那就完美了
  • 退格和删除也不起作用 -) 需要添加额外的检查
  • 问题是只允许输入数字,如果你想要更多,那么当然可以进行相应的定制。所以这只是一个建议,并不是所有问题的具体答案。
  • 我觉得这就是命运之道
【解决方案6】:

以安东的回答为基础——

angular.module("app").directive("onlyDigits", function ()
{
    return {
        restrict: 'EA',
        require: '?ngModel',
        scope:{
            allowDecimal: '@',
            allowNegative: '@',
            minNum: '@',
            maxNum: '@'
        },

        link: function (scope, element, attrs, ngModel)
        {
            if (!ngModel) return;
            ngModel.$parsers.unshift(function (inputValue)
            {
                var decimalFound = false;
                var digits = inputValue.split('').filter(function (s,i)
                {
                    var b = (!isNaN(s) && s != ' ');
                    if (!b && attrs.allowDecimal && attrs.allowDecimal == "true")
                    {
                        if (s == "." && decimalFound == false)
                        {
                            decimalFound = true;
                            b = true;
                        }
                    }
                    if (!b && attrs.allowNegative && attrs.allowNegative == "true")
                    {
                        b = (s == '-' && i == 0);
                    }

                    return b;
                }).join('');
                if (attrs.maxNum && !isNaN(attrs.maxNum) && parseFloat(digits) > parseFloat(attrs.maxNum))
                {
                    digits = attrs.maxNum;
                }
                if (attrs.minNum && !isNaN(attrs.minNum) && parseFloat(digits) < parseFloat(attrs.minNum))
                {
                    digits = attrs.minNum;
                }
                ngModel.$viewValue = digits;
                ngModel.$render();

                return digits;
            });
        }
    };
});

【讨论】:

  • 你应该使用ngModel.$setViewValue(digits) 而不是ngModel.$viewValue = digits,这样它就会命中ngModelController 和ngForm 钩子的其余部分。我需要这个,因为它是一个必填字段,当我输入一个字母(没有显示)时,表单被标记为有效 - 错误。
  • 这个指令的问题是如果你输入了合法的数字并且错误地输入了字母,你的字段将被删除。
【解决方案7】:

我的解决方案接受复制和粘贴并保存插入符号的位置。它用于产品成本,因此仅允许正十进制值。可以很容易地重构以允许负数或仅整数位。

angular
        .module("client")
        .directive("onlyNumber", function () {
            return {
                restrict: "A",
                link: function (scope, element, attr) {
                    element.bind('input', function () {
                        var position = this.selectionStart - 1;

                        //remove all but number and .
                        var fixed = this.value.replace(/[^0-9\.]/g, '');  
                        if (fixed.charAt(0) === '.')                  //can't start with .
                            fixed = fixed.slice(1);

                        var pos = fixed.indexOf(".") + 1;
                        if (pos >= 0)               //avoid more than one .
                            fixed = fixed.substr(0, pos) + fixed.slice(pos).replace('.', '');  

                        if (this.value !== fixed) {
                            this.value = fixed;
                            this.selectionStart = position;
                            this.selectionEnd = position;
                        }
                    });
                }
            };
        });

放在html页面上:

<input type="text" class="form-control" only-number ng-model="vm.cost" />

【讨论】:

    【解决方案8】:

    这是适合我的方法。它基于samnau anwser,但允许使用ENTER 提交表单,使用UPDOWN 箭头增加和减少数字,使用DEL,BACKSPACE,LEFTRIGHT 编辑,并使用TAB 浏览低谷字段。请注意,它适用于正整数,例如金额。

    HTML:

    <input ng-keypress="onlyNumbers($event)" min="0" type="number" step="1" ng-pattern="/^[0-9]{1,8}$/" ng-model="... >
    

    角度:

    $scope.onlyNumbers = function(event){   
        var keys={
            'up': 38,'right':39,'down':40,'left':37,
            'escape':27,'backspace':8,'tab':9,'enter':13,'del':46,
            '0':48,'1':49,'2':50,'3':51,'4':52,'5':53,'6':54,'7':55,'8':56,'9':57
        };
        for(var index in keys) {
            if (!keys.hasOwnProperty(index)) continue;
            if (event.charCode==keys[index]||event.keyCode==keys[index]) {
                return; //default event
            }
        }   
        event.preventDefault();
    };
    

    【讨论】:

      【解决方案9】:

      基于 djsiz 解决方案,包含在指令中。 注意:它不会处理数字,但可以轻松更新

      angular
              .module("app")
              .directive("mwInputRestrict", [
                  function () {
                      return {
                          restrict: "A",
                          link: function (scope, element, attrs) {
                              element.on("keypress", function (event) {
                                  if (attrs.mwInputRestrict === "onlynumbers") {
                                      // allow only digits to be entered, or backspace and delete keys to be pressed
                                      return (event.charCode >= 48 && event.charCode <= 57) ||
                                             (event.keyCode === 8 || event.keyCode === 46);
                                  }
                                  return true;
                              });
                          }
                      }
                  }
              ]);
      

      HTML

       <input type="text"
              class="form-control"
              id="inputHeight"
              name="inputHeight"
              placeholder="Height"
              mw-input-restrict="onlynumbers"
              ng-model="ctbtVm.dto.height">
      

      【讨论】:

        【解决方案10】:

        只需使用 HTML5

        <input type="number" min="0"/>
        

        【讨论】:

        • 是的,type="number" 肯定会很好用。但是当我们使用引导输入组进行这种输入时,它无法正确呈现。
        【解决方案11】:

        你可以检查 https://github.com/rajesh38/ng-only-number

        1. 它在键入时将输入限制为仅输入文本框中的数字和小数点。
        2. 您可以限制小数点前后允许的位数
        3. 如果从文本框中删除小数点,它还会修剪小数点后的数字,例如如果您输入了 123.45,然后删除了小数点,它还将删除小数点后的尾随数字并将其设为 123。

        【讨论】:

          【解决方案12】:

          你可以这样做: 将 ng-pattern 与 RegExp "/^[0-9]+$/" 一起使用,这意味着只有整数有效。

          <form novalidate name="form">
              <input type="text" data-ng-model="age" id="age" name="age" ng-pattern="/^[0-9]+$/">
              <span ng-show="form.age.$error.pattern">The value is not a valid integer</span>
          </form>
          

          【讨论】:

            【解决方案13】:

            此解决方案仅接受数字“.”和'-'

            这也限制了文本框上的空格输入。我曾使用该指令来实现相同的目标。

            请在下面的工作示例中找到解决方案。

            http://jsfiddle.net/vfsHX/2697/

            HTML:

            <form ng-app="myapp" name="myform" novalidate> 
            <div ng-controller="Ctrl">
            <input name="number" is-number ng-model="wks.number">
            <span ng-show="!wks.validity">Value is invalid</span>
            </div>
            

            JS:

            var $scope;
            var app = angular.module('myapp', []);
            
            app.controller('Ctrl', function($scope) {
                $scope.wks =  {number: 1, validity: true}
            });
            
            app.directive('isNumber', function () {
                return {
                    require: 'ngModel',
                    link: function (scope, element, attrs, ngModel) {   
                    element.bind("keydown keypress", function (event) {
                      if(event.which === 32) {
                        event.returnValue = false;
                        return false;
                      }
                   }); 
                        scope.$watch(attrs.ngModel, function(newValue,oldValue) {
                            var arr = String(newValue).split("");
                            if (arr.length === 0) return;
                            if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
                            if (arr.length === 2 && newValue === '-.') return;
                            if (isNaN(newValue)) {
                                //scope.wks.number = oldValue;
                                ngModel.$setViewValue(oldValue);
                                                ngModel.$render();
                            }
                        });
            
                    }
                };
            });
            

            【讨论】:

              【解决方案14】:

              简单易懂。 只需复制粘贴此代码即可解决您的问题。对于更多条件,只需更改模式中的值即可。您的工作将完成。

              <input type="text"  pattern="[0-9]{0,}" oninvalid="this.setCustomValidity('Please enter only numeric value. Special character are not allowed.')" oninput="setCustomValidity('')">
              

              【讨论】:

                【解决方案15】:
                <input type="phone" numbers-only >
                

                如果你只想要数字,你可以使用这种方式:)

                这里是演示click

                【讨论】:

                  【解决方案16】:

                  我遇到了类似的问题,最后挂了和事件

                  ng-change="changeCount()" 
                  

                  然后:

                  self.changeCount = function () {
                        if (!self.info.itemcount) {
                          self.info.itemcount = 1;
                        }
                   };
                  

                  所以如果插入了无效号码,用户默认为1。

                  【讨论】:

                    【解决方案17】:

                    我在this中安排了jQuery

                    .directive('numbersCommaOnly', function(){
                       return {
                         require: 'ngModel',
                         link: function (scope, element, attrs, ngModel) {
                    
                            element.on('keydown', function(event) {                  
                                // Allow: backspace, delete, tab, escape, enter and .
                                var array2 = [46, 8, 9, 27, 13, 110, 190]
                                if (array2.indexOf(event.which) !== -1 ||
                                     // Allow: Ctrl+A
                                    (event.which == 65 && event.ctrlKey === true) ||
                                     // Allow: Ctrl+C
                                    (event.which == 67 && event.ctrlKey === true) ||
                                     // Allow: Ctrl+X
                                    (event.which == 88 && event.ctrlKey === true) ||
                                     // Allow: home, end, left, right
                                    (event.which >= 35 && event.which <= 39)) {
                                         // let it happen, don't do anything
                                         return;
                                }
                                // Ensure that it is a number and stop the keypress
                                if ((event.shiftKey || (event.which < 48 || event.which > 57)) && (event.which < 96 || event.which > 105)) {
                                    event.preventDefault();
                                }
                             });
                    
                         }
                       };
                    })
                    

                    【讨论】:

                      【解决方案18】:
                       <input type="text" ng-keypress="checkNumeric($event)"/>
                       //inside controller
                       $scope.dot = false
                       $scope.checkNumeric = function($event){
                       if(String.fromCharCode($event.keyCode) == "." && !$scope.dot){
                          $scope.dot = true
                       }
                       else if( isNaN(String.fromCharCode($event.keyCode))){
                         $event.preventDefault();
                       }
                      

                      【讨论】:

                      • 允许浮点值!!
                      【解决方案19】:

                      我知道这是一篇旧帖子,但对 我的 Mai 答案的改编对我来说效果很好......

                      angular.module("app").directive("numbersOnly", function() {
                        return {
                          require: "ngModel",
                          restrict: "A",
                          link: function(scope, element, attr, ctrl) {
                              function inputValue(val) {
                                  if (val) {
                                      //transform val to a string so replace works
                                      var myVal = val.toString();
                      
                                      //replace any non numeric characters with nothing
                                      var digits = myVal.replace(/\D/g, "");
                      
                                      //if anything needs replacing - do it!
                                      if (digits !== myVal) {
                                          ctrl.$setViewValue(digits);
                                          ctrl.$render();
                                      }
                                      return parseFloat(digits);
                                  }
                                  return undefined;
                              }
                              ctrl.$parsers.push(inputValue);
                          }
                        };
                      });
                      

                      【讨论】:

                        【解决方案20】:

                        我已经完成了

                        .js

                        $scope.numberOnly="(^[0-9]+$)";
                        

                        .html

                        <input type="text" name="rollNo" ng-model="stud.rollNo" ng-pattern="numberOnly" ng-maxlength="10" maxlength="10" md-maxlength="10" ng-required="true" >
                        

                        【讨论】:

                          【解决方案21】:

                          此答案是对Leopoldo's answer 的简化和优化。

                          在每次按键时从您的输入中触发一个函数,如下所示:

                          <input type="text" ng-keydown="onlyNumbers($event);"/>
                          

                          您可以在控制器中以这种方式描述功能

                          $scope.onlyNumbers = function(event){    
                              // 'up': 38,'right':39,'down':40,'left':37,
                              // 'escape':27,'backspace':8,'tab':9,'enter':13,'del':46,
                              // '0':48,'1':49,'2':50,'3':51,'4':52,'5':53,'6':54,'7':55,'8':56,'9':57
                              var keys = { 38:true,39:true,40:true,37:true,27:true,8:true,9:true,13:true,
                                           46:true,48:true,49:true, 50:true,51:true,52:true,53:true,
                                           54:true,55:true,56:true,57:true };
                          
                              // if the pressed key is not listed, do not perform any action
                              if(!keys[event.keyCode]) { event.preventDefault(); }
                          }
                          

                          如果您使用的是 Angular 2+,您可以通过这种方式调用相同的函数:

                          <input type="text" (keydown)="onlyNumbers($event);"/>
                          

                          您的 Angular 2+ 函数应如下所示:

                          onlyNumbers(event) { // the logic here }
                          

                          【讨论】:

                            【解决方案22】:

                            使用ng-only-number 只允许数字,例如:

                            <input type="text" ng-only-number data-max-length=5>
                            

                            【讨论】:

                              【解决方案23】:
                               <input
                                  onkeypress="return (event.charCode >= 48 && event.charCode <= 57) ||                         
                                  event.charCode == 0 || event.charCode == 46">
                              

                              【讨论】:

                              • 您的回答太好了,虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
                              • 谢谢@Fraser。如果你不介意你能帮我做正确的回答吗:)
                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 2016-03-04
                              • 1970-01-01
                              • 2011-11-09
                              • 1970-01-01
                              • 2016-07-19
                              • 2017-08-11
                              • 1970-01-01
                              相关资源
                              最近更新 更多