表单上的冲突验证。$ error.required和表单。$ invalid

时间:2016-06-08 03:56:31

标签: javascript angularjs validation

更新:已经确认这是一个角色错误

检查:https://github.com/angular/angular.js/issues/14734#issuecomment-224558516

案例是,我正在尝试创建一个datepicker字段,用于检测输入是否为无效日期(月度和日期有效性也包括在内,如2015-02-30无效,因为没有2月30日)并且是也需要。因此,我通过指令创建了自定义表单有效性来检测无效日期。自定义有效性工作正常,但似乎$ error.required和$ invalid不同步,因为我使用了" ngModel。$ validators.available"。

这是一个工作的掠夺者:http://plnkr.co/edit/NuDGB64IetpcsaVB03T7?p=preview

你会在plunker中注意到$ error.required是 true 但是$ invalid是空白但输入无效日期时变为true,如果是日期输入有效。简而言之,当输入为空白时,表单不被视为无效,这对我的ng-class

非常需要

代码是:

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/flick/jquery-ui.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
  </head>

  <body>
      <form ng-controller="myCtrl" name="bioManagementForm" novalidate>
          Degree: <br />
          <p>Invalid Input: -- {{ bioManagementForm.in_company_since.$invalid }}</p>
          <p>Required -- {{ bioManagementForm.in_company_since.$error.required }}</p>
          <input class="form-control input-form since" ng-class="{ 'error': bioManagementForm.in_company_since.$invalid && notifications }" type="text" id="in_company_since" name="in_company_since" ng-model="input.in_company_since" ng-required="true" datepicker>
    </form>
  </body>

  <script>
    // Code goes here

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


    myApp.controller('myCtrl', function($scope){

    });


   myApp.directive('datepicker', function() {
        return {
            restrict: 'A',
            require : 'ngModel',
            link : function (scope, element, attrs, ngModel) {
                console.log(ngModel);
                datePatternCounter = [];
                // $(function(){
                    if(!scope.viewOnly){
                        element.attr("placeholder", "YYYY-MM-DD");
                    }
                    element.datepicker({
                        changeYear: true, 
                        changeMonth: true, 
                        yearRange: "1900:+50", 
                        showButtonPanel: true,
                        closeText: 'Clear',
                        dateFormat:'yy-mm-dd',
                        onSelect:function (date) {
                            ngModel.$setViewValue(date);
                            scope.$apply();
                        },
                        // Custom function that clears the date value of the model when the "Clear" button is clicked on the datepicker
                        onClose: function(date){
                            var event = arguments.callee.caller.caller.arguments[0];
                            if(Number(date) && date.length == 8){
                                // alert("dean");
                                year = date.slice(0, 4);
                                month = date.slice(4, 6);
                                day = date.slice(6, 8);
                                newDate = year+"-"+month+"-"+day;
                                ngModel.$setViewValue(newDate);
                                ngModel.$render();
                            }else{
                                // alert("armada");
                                // Code if with dash
                                // Do nothing
                            }
                            // ngModel.$error.datePattern
                            if(event['type'] == 'click'){
                                ngModel.$setViewValue(undefined);
                                ngModel.$render();
                            }
                        },
                        beforeShow: function (e, t) {
                            id = document.querySelector( '#ui-datepicker-div' );
                            angular.element(id).addClass('HideTodayButton');
                            if(element.hasClass('birth_date')){
                                element.datepicker("option", "maxDate", 0);
                            }
                        },
                    });
                // });
          // START Syntax to check if the date is valid or not in real time
                ngModel.$validators.available = function (modelValue, viewValue) {
                    if(modelValue){
                        var check = modelValue.split('-');
                        var y = parseInt(check[0], 10);
                        var m = parseInt(check[1], 10);
                        var d = parseInt(check[2], 10);
                        var date = new Date(y,m-1,d);
                        if (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d) {
                            check = true;
                        } else {
                            check = false;
                            name = ngModel.$name;
                            if(datePatternCounter.indexOf(name) == -1){
                                datePatternCounter.push(name);
                                element.parent().siblings("span.errors").append('<span class="invalid-date" ng-if="'+ngModel.$error.available+'"> * Invalid Date <br /></span>');
                            }
                        }

                    }
                    return check;
                }
                // END Syntax to check if the date is valid or not
            }
        }
    });
  </script>
</html>

1 个答案:

答案 0 :(得分:1)

如果值为空,请将日期验证程序更改为true

ngModel.$validators.available = function (modelValue, viewValue) {
    if(modelValue){
        var check = modelValue.split('-');
        var y = parseInt(check[0], 10);
        var m = parseInt(check[1], 10);
        var d = parseInt(check[2], 10);
        var date = new Date(y,m-1,d);
        if (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d) {
            check = true;
        } else {
            check = false;
            name = ngModel.$name;
            if(datePatternCounter.indexOf(name) == -1){
                datePatternCounter.push(name);
                element.parent().siblings("span.errors").append('<span class="invalid-date" ng-if="'+ngModel.$error.available+'"> * Invalid Date <br /></span>');
            }
        }
        return check; // true or false when value is not empty
    }
    return true; // empty value should be handled by ng-required, we only check format here, so return true
}