2015-10-06 84 views
0

我有一個表格,檢查信用卡到期日是否在當前日期之前或之後。大多數情況下,它是有效的。但是,如果您以特定方式瀏覽表單,則驗證工作不正確。角度/ JS驗證不清除/重新驗證向下箭頭

基本上,如果您使用鼠標點擊字段,一切正常,它應該如此。如果您使用箭頭鍵切換值,則不會。

這可以在下面的代碼和codepen我看到here

如果您將注意力集中在文本框上,將標籤設置爲「Exp Month」並向下箭頭至1或2,然後切換至Exp Year。在這裏,箭頭到2015年,你會看到文字說日期必須在今天之後。 (這是寫在2015年10月,所以測試會根據你看這篇文章而改變)。這裏的文字是預期的。沒有預料到的是,如果你在同一個盒子裏下到2016年,文字不會清楚。實質上,即使在模型中發生了某些變化,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>

回答

0

好像它在瀏覽器(可能Firefox)的一個已知的問題: https://github.com/angular/angular.js/issues/4216

gkalpak評論06月17日

@iiminov,如已上面提到,這是一個已知的問題,是由於Chrome中的一個錯誤。 在解決該錯誤之前,解決方案/解決方法是使用明確的空白選項。

(目前尚不清楚你想要什麼證明(和它是如何從已經討論過的演示)不同。)

更多細節,在這裏解決方法: https://github.com/angular/angular.js/issues/9134

Narretz 07月13評論

我剛剛關閉這個問題有些重複,所以這裏是一個快速回顧:

當選項被移除時,Chrome(Blink)/ Safari(webkit)的錯誤不會觸發更改。 Bug提交爲https://code.google.com/p/chromium/issues/detail?id=415505

當選擇值通過鍵盤改變時,Firefox基本上遵循「規範的精神」,但Chrome和IE做了改變,所以它被認爲是一個錯誤。跟蹤爲https://bugzilla.mozilla.org/show_bug.cgi?id=126379

作爲一種變通方法,您可以添加觸發上KEYUP改變事件指令(感謝@gkalpak此):

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