Angular / JS验证未按箭头向下清除/重新验证

时间:2015-10-06 16:03:30

标签: javascript jquery angularjs validation

我有一个表单,用于检查信用卡到期日期是在当前日期之前还是之后。在大多数情况下,它的工作原理。但是,如果您以特定方式导航表单,则验证无法正常工作。

基本上,如果您使用鼠标点击字段,一切正常。如果使用箭头键切换值,则不会。

这可以在下面的代码和代码集中看到here

如果您首先关注“文本”框,请选择“缩放月”,然后选择“箭头”或“1”或“2”,然后将“选项卡”设置为“年份”。在这里,向下箭头到2015年,你会看到文字说日期必须在今天之后。 (这是在2015年10月写的,所以测试将根据你看这篇文章的时间而改变)。这里的文字是预期的。不期望的是,如果你在同一个框中向下箭头,那么文字就不清楚了。基本上,即使模型中发生了某些变化,ng-show也不会重新测试代码。如果你向下箭头到2017年,文字隐藏,一切正常。更奇怪的是,你现在可以按照你想要的方式向上和向下箭头,并且评估按预期工作。

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

app.controller('ccDate', function($scope) {
  $scope.ccExpireMonths = [{
    id: 1,
    name: "1"
  }, {
    id: 2,
    name: "2"
  }, {
    id: 3,
    name: "3"
  }, {
    id: 4,
    name: "4"
  }, {
    id: 5,
    name: "5"
  }, {
    id: 6,
    name: "6"
  }, {
    id: 7,
    name: "7"
  }, {
    id: 8,
    name: "8"
  }, {
    id: 9,
    name: "9"
  }, {
    id: 10,
    name: "10"
  }, {
    id: 11,
    name: "11"
  }, {
    id: 12,
    name: "12"
  }]
  $scope.expireMonth = "";
  var currentDate = new Date();
  $scope.currentYear = currentDate.getFullYear();

  function getCreditCardExpireYears() {
    var expireYears = new Array();
    var i;
    for (i = 0; i < 8; i++) {
      expireYears[i] = $scope.currentYear + i;
    };
    return expireYears;
  }
  $scope.ccExpireYears = getCreditCardExpireYears();
  $scope.validateCCExpireDate = function() {
    var today = new Date();
    var minDate = new Date(today.getFullYear(), today.getMonth());
    var ccExpireDate = new Date($scope.expireYear, $scope.expireMonth - 1);
    return ccExpireDate < minDate;
  };
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="App">
  <div ng-controller="ccDate">
    <div class="row">
      <div class="form-group col-md-12">
        <label for="some=text">Some Text</label>
        <input type="text" id="some-text">
      </div>
    </div>
    <div class="row">

      <div class="form-group col-md-2">
        <label for="expire-month" required="">Exp. Month</label>
        <select id="expire-month" class="form-control ng-valid ng-valid-required ng-dirty ng-valid-parse ng-touched" title="Select the card expiration month" ng-model="expireMonth" ng-options="month.id as month.name for month in ccExpireMonths" ng-required="expireMonth"
        required="required">
        </select>

      </div>
      <div class="form-group col-md-2">
        <label for="expire-year" required="">Exp. Year</label>
        <select id="expire-year" class="form-control ng-valid ng-valid-required ng-dirty ng-valid-parse ng-touched" title="Select the card expiration year" ng-model="expireYear" ng-options="year for year in ccExpireYears" ng-required="expireYear" required="required">

        </select>
      </div>
      <div class="form-group col-md-3">
      </div>

    </div>
    <div class="row">
      <div id="expire-month-value" ng-show="validateCCExpireDate() && expireMonth && expireYear" class="error-text form-group col-md-3 ng-hide">Month/Year combination must not be in the past.</div>
    </div>
  </div>
</body>

1 个答案:

答案 0 :(得分:0)

在Chrome(可能是Firefox)中,它似乎是一个已知问题: https://github.com/angular/angular.js/issues/4216

  

gkalpak于6月17日发表评论

     

@iiminov,如前所述,这是一个已知问题,是由于Chrome中的一个错误。   在解决错误之前,解决方案/解决方法是使用显式空选项。

     

(目前尚不清楚你要展示的是什么(以及它与已经讨论过的演示有什么不同)。)

更多细节和解决方法: https://github.com/angular/angular.js/issues/9134

  

Narretz于8月13日发表评论

     

我刚刚结束了这个问题的一些重复,所以这里有一个简短的回顾:

     

Chrome(Blink)/ Safari(webkit)在删除选项时没有触发更改的错误。错误归档为https://code.google.com/p/chromium/issues/detail?id=415505

     

Firefox基本上遵循规范&#34;精神。通过键盘更改选择值时不触发更改,但Chrome和IE会执行此操作,因此可能会被视为错误。跟踪为https://bugzilla.mozilla.org/show_bug.cgi?id=126379

     

作为一种解决方法,您可以添加一个指令来触发keyup上的change事件(感谢@gkalpak):

directive('changeOnKeyup', function changeOnKeyupDirective() {
    return function changeOnKeyupPostLink(scope, elem) {
        elem.on('keyup', elem.triggerHandler.bind(elem, 'change'));
    };
});