How to validate against multiple fields and displa

2019-08-26 22:49发布

I want to validate a control against multiple fields. And I want to display an error indicating which field(s) caused validation to fail.

Run the following code. Change the first value to a high number (E.G. 5) and validation will pass. Change the first value to a low number (2) and validation will fail.

In the case of "2" there should be 2 errors: model3, model4 because those models are higher values than 2. Similarly for all other fields.

The validation works fine. I'm having trouble displaying the correct error messages based on the particular validation rule that failed.

Note, any field changes must re-fire validation just like it does now. You should run this snippet in full page view.

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

app.controller('MainCtrl', function($scope) { 
  $scope.model = {number: "1"};
  $scope.model2 = {number: "2"};
  $scope.model3 = {number: "3"};
  $scope.model4 = {number: "4"};
});

app.directive('theGreatest', function(){
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function($scope, $element, $attr, ngModel) {
            var compareCollection;

            // watch the attribute to get the date we need to compare against
            $attr.$observe('theGreatest', function (val) {
                console.log('compareCollection set to: ', val);
                compareCollection = JSON.parse(val);
                ngModel.$validate();
            });

            ngModel.$validators.theGreatest = function(modelValue, viewValue) {
                 console.log('validating...', modelValue);
                 console.log('compareDate: ', compareCollection);
                    
                var pass = true;
                _.map(compareCollection, function(compare){
                  console.log('comparing value: ', compare);
                  if(modelValue < compare){
                    pass = false; 
                  }
                });
        
                console.log('validation pass', pass);
                return pass;
            };
        }
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<section ng-app="app" ng-controller="MainCtrl">
<div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" />
  (change me to a high number)
  </div>
<div>second: <input ng-model="model2.number" type="text" /></div>
<div>third: <input ng-model="model3.number" type="text" /></div>
<div>fourth: <input ng-model="model4.number" type="text" /></div>
  <div>validation passed if you see a value here: {{model.number}}</div>
  <div>The following errors are not implemented correctly.  The intention is to show what I am want to accomplish</div>
  <div ng-if="!model.number">ERROR: first is less than model 2</div>
  <div ng-if="!model.number">ERROR: first is less than model 3</div>
  <div ng-if="!model.number">ERROR: first is less than model 4</div>
  
  <div ng-if="!model.number">ERROR: first is required</div>
</section>

1条回答
太酷不给撩
2楼-- · 2019-08-26 23:21

You need to send ErrorFlags array into directive and while you are validating mark those flags as false when validation fails.

HTML:

<section ng-app="app" ng-controller="MainCtrl">
    <div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" error-flags="errorFlags" />
    (change me to a high number)
    </div>
    <div>second: <input ng-model="model2.number" type="text" /></div>
    <div>third: <input ng-model="model3.number" type="text" /></div>
    <div>fourth: <input ng-model="model4.number" type="text" /></div>
    <div>validation passed if you see a value here: {{model.number}}</div>
    <div>The following errors are not implemented correctly.  The intention is to show what I want to accomplish</div>
    <div ng-if="!errorFlags[0]">ERROR: first is less than model 2</div>
    <div ng-if="!errorFlags[1]">ERROR: first is less than model 3</div>
    <div ng-if="!errorFlags[2]">ERROR: first is less than model 4</div>

    <div ng-if="!model.number">ERROR: first is required</div>
</section>

AngularJS Code:

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

app.controller('MainCtrl', function($scope) { 
  $scope.model = {number: "1"};
  $scope.model2 = {number: "2"};
  $scope.model3 = {number: "3"};
  $scope.model4 = {number: "4"};
  $scope.errorFlags = [true, true , true];
});

app.directive('theGreatest', function(){
    return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
          errorFlags:"="
        },
        link: function(scope, element, attrs, ngModel) {
            var compareCollection;

            // watch the attribute to get the date we need to compare against
            attrs.$observe('theGreatest', function (val) {
                console.log('compareCollection set to: ', val);
                compareCollection = JSON.parse(val);
                ngModel.$validate();
            });

            ngModel.$validators.theGreatest = function(modelValue, viewValue) {
                 console.log('validating...', modelValue);
                 console.log('compareDate: ', compareCollection);
              scope.errorFlags = [true, true, true];
                    console.log("Before Validation Flags", scope.errorFlags);
                var pass = true;
              var loopVariable = 0;
                _.map(compareCollection, function(compare){
                  console.log('comparing value: ', compare);
                  if(modelValue < compare){
                    pass = false;
                    scope.errorFlags[loopVariable] = false;
                  }
                  loopVariable++;
                });
              console.log("after Validation Flags", scope.errorFlags);
                console.log('validation pass', pass);
                return pass;
            };
        }
    };
});
查看更多
登录 后发表回答