2015-10-06 2 views
0

У меня есть форма, которая проверяет, существует ли срок действия кредитной карты до или после текущей даты. По большей части это работает. Однако, если вы перемещаете форму определенным образом, проверка не работает совершенно правильно.Угловая/JS Валидация не очистка/повторная калибровка по стрелке вниз

В принципе, если вы используете мышь, чтобы нажимать на поля, все работает так, как должно. Если вы используете клавиши со стрелками для переключения значений, это не так.

Это можно увидеть в коде ниже и в кодефе, я сделал here.

Если вы начинаете с фокусировки на текстовом поле, вкладке «Месяц месяца» и стрелке вниз до 1 или 2, тогда перейдите к Exp Year. Здесь стрелка до 2015 года, и вы увидите текст, говорящий, что дата должна быть после сегодняшнего дня. (Это написано в октябре 2015 года, поэтому тест изменится в зависимости от того, когда вы посмотрите на этот пост). Текст здесь ожидается. Что не ожидается, если вы стрелка вниз до 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

Похоже, это известная проблема в Chrome (и, вероятно, Firefox): https://github.com/angular/angular.js/issues/4216

gkalpak прокомментировал 17 июня

@iiminov, как уже Это известная проблема, и это связано с ошибкой в ​​Chrome. До тех пор, пока ошибка не будет решена, решение/обходное решение должно использовать явный пустую опцию.

(Это не ясно, что вы пытаетесь продемонстрировать (и как это отличается от демоса, которые уже обсуждались).)

Подробнее и обходной путь здесь: https://github.com/angular/angular.js/issues/9134

Наррец прокомментировал 13 августа

Я только что закрыл некоторые дубликаты этой проблемы, так что вот краткое описание:

Chrome (Blink)/Safari (webkit) имеет ошибку, которая не срабатывает при смене варианта. Ошибка, указанная как 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')); 
    }; 
}); 
Смежные вопросы