如何重写angular的type=number验证



我正在编写一个指令,将验证瑞典社会安全号码(personnummer)。用于像这样的输入元素:

<input type="text" ng-model="pnr" pnrvalidator />

瑞典社会安全号码的格式为yyyymmdd-nnnn,例如19121212-1212

只要我使用type="text",我的指令就可以工作。但由于我希望数字键盘能在移动浏览器上使用,然后改为type="number":

<input type="number" ng-model="pnr" pnrvalidator />

那么我的验证器只有在我的输入中没有输入破折号(-)时才能工作,例如191212121212。如果我输入19121212-1212,那么它不是一个有效的数字。类ng-invalid ng-invalid-number被添加到我的输入元素

当我编写指令时,我遵循了如何修改内置验证器https://docs.angularjs.org/guide/forms的文档但它似乎不适用于type=number验证,或者我错过了什么?我正在使用angular 1.3(和1.4)。

我的指令代码:

angular.module('example').directive('pnrvalidator', function(){
return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {

    var validatePnr = function(inputString){
        /*
        * My validation logic here. Removed for this example
        */
    };

    ctrl.$validators.number = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          // consider empty models to be valid
          return true;
        }
        if (validatePnr(viewValue)) {
          // it is valid
          return true;
        }
        // it is invalid
        return false;
    };
    }
};
});

一个活塞与我的例子http://plnkr.co/edit/OFYG06YEFwKg8zrLYVN1?p=preview

你可以通过标签中的novalidate属性告诉HTML不验证HTML表单。当你在angularjs中进行验证时,你不需要再通过HTML进行验证。

http://www.w3schools.com/tags/att_form_novalidate.asp

HTML将不允许除数字或小数以外的任何内容(当使用step="any"考虑有效时,这将强制angular认为它无效…但是,您可以在控制器中创建自己的验证方法:

$scope.validated = function(){
      if (null !== $scope.pnr) ){
        $scope.pnr = $scope.pnr.split("-").join();
        if(typeof parseInt($scope.pnr, 10) = 'integer') return true;
            else return false;
      } else {
        return false;
      }
    };

这只是一个随机验证,不一定是你想要的…

然后让它有一个ng类"error",如果验证===false

类似于:

<form name="myForm" ng-submit="validated && submittedSSN">
ng-class="{strike: deleted, bold: important, 'has-error': error}"
<input type="number" ng-class=" {error: !validated}" ng-model="pnr" pnrvalidator />
</form>

CSS还必须有一些错误。

.error {
   background: red;
    border:red;
    color: lime;
}

——注意这是一个疯狂的笑话…

https://docs.angularjs.org/api/ng/directive/ngClass

也看到:iPhone UIWebview:如何强制一个数字键盘?这可能吗?如何在AngularJS表单中添加自定义验证?

根据这个你可以做type="tel"只在Safari上工作

我对<input type="number"/>和包含破折号的数字的自定义验证的问题做了更多的研究,例如1234-1234。现在看来,解决这个问题是不可能的。(我想使用type="number"来获得移动浏览器上的数字键盘)

可以通过删除我的指令链接函数中的所有解析器来禁用angular的数字验证

ctrl.$parsers = [];

然后angular说它是一个有效的数字,并添加ng-valid-number类。但这没有帮助,因为浏览器(IE11除外)将返回一个空字符串时,输入一个数字中间包含破折号例如1234-1234。

根据How to get raw value <输入type>场吗?根据HTML规范,这是浏览器的正确行为,可以用下面的代码进行测试:

<!DOCTYPE html>
<html>
  <head>
    <script data-require="jquery@2.1.4" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
  </head>
  <body>
    <h1>Input test</h1>
    <input type="number" id="myInput"/>
    Value=<span id="myValue"></span>
    <script>
      $('#myInput').keyup(function(){
        var value = $(this).val();
        $('#myValue').text(value);
      });
    </script>
  </body>
</html>

你可以使用type="tel",但在iOS上你会得到一个没有破折号的数字键盘。所以这对我也没用。一篇很棒的博客文章,描述了不同浏览器对不同输入类型的支持:http://www.smashingmagazine.com/2015/05/form-inputs-browser-support-issue/

在HTML 5.1规范中,提出了另一个属性'inputmode',可以具有值'numeric' inputmode="numeric"。Inputmode应该告诉浏览器哪种输入机制对用户在表单控件中输入内容最有帮助。https://html.spec.whatwg.org/输入模式:-the-inputmode-attribute。但目前还没有浏览器支持。http://www.wufoo.com/html5/attributes/23-inputmode.html

所以现在看来我必须使用<input type="text"/>

最新更新