How to add custom validation to an AngularJS form?

后端 未结 12 1491
既然无缘
既然无缘 2020-11-22 10:07

I have a form with input fields and validation setup by adding the required attributes and such. But for some fields I need to do some extra validation. How wou

相关标签:
12条回答
  • 2020-11-22 10:39

    Custom Validations that call a Server

    Use the ngModelController $asyncValidators API which handles asynchronous validation, such as making an $http request to the backend. Functions added to the object must return a promise that must be resolved when valid or rejected when invalid. In-progress async validations are stored by key in ngModelController.$pending. For more information, see AngularJS Developer Guide - Forms (Custom Validation).

    ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
      var value = modelValue || viewValue;
    
      // Lookup user by username
      return $http.get('/api/users/' + value).
         then(function resolved() {
           //username exists, this means validation fails
           return $q.reject('exists');
         }, function rejected() {
           //username does not exist, therefore this validation passes
           return true;
         });
    };
    

    For more information, see

    • ngModelController $asyncValidators API

    • AngularJS Developer Guide - Forms (Custom Validation).


    Using the $validators API

    The accepted answer uses the $parsers and $formatters pipelines to add a custom synchronous validator. AngularJS 1.3+ added a $validators API so there is no need to put validators in the $parsers and $formatters pipelines:

    app.directive('blacklist', function (){ 
       return {
          require: 'ngModel',
          link: function(scope, elem, attr, ngModel) {           
              ngModel.$validators.blacklist = function(modelValue, viewValue) {
                  var blacklist = attr.blacklist.split(',');
                  var value = modelValue || viewValue;
                  var valid = blacklist.indexOf(value) === -1;
                  return valid;
              });    
          }
       };
    });
    

    For more information, see AngularJS ngModelController API Reference - $validators.

    0 讨论(0)
  • 2020-11-22 10:40

    You can use ng-required for your validation scenario ("if these 3 fields are filled in, then this field is required":

    <div ng-app>
        <input type="text" ng-model="field1" placeholder="Field1">
        <input type="text" ng-model="field2" placeholder="Field2">
        <input type="text" ng-model="field3" placeholder="Field3">
        <input type="text" ng-model="dependentField" placeholder="Custom validation"
            ng-required="field1 && field2 && field3">
    </div>
    
    0 讨论(0)
  • 2020-11-22 10:40

    Here's a cool way to do custom wildcard expression validations in a form (from: Advanced form validation with AngularJS and filters):

    <form novalidate="">  
       <input type="text" id="name" name="name" ng-model="newPerson.name"
          ensure-expression="(persons | filter:{name: newPerson.name}:true).length !== 1">
       <!-- or in your case:-->
       <input type="text" id="fruitName" name="fruitName" ng-model="data.fruitName"
          ensure-expression="(blacklist | filter:{fruitName: data.fruitName}:true).length !== 1">
    </form>
    
    app.directive('ensureExpression', ['$http', '$parse', function($http, $parse) {
        return {
            require: 'ngModel',
            link: function(scope, ele, attrs, ngModelController) {
                scope.$watch(attrs.ngModel, function(value) {
                    var booleanResult = $parse(attrs.ensureExpression)(scope);
                    ngModelController.$setValidity('expression', booleanResult);
                });
            }
        };
    }]);
    

    jsFiddle demo (supports expression naming and multiple expressions)

    It's similar to ui-validate, but you don't need a scope specific validation function (this works generically) and ofcourse you don't need ui.utils this way.

    0 讨论(0)
  • 2020-11-22 10:43

    Angular-UI's project includes a ui-validate directive, which will probably help you with this. It let's you specify a function to call to do the validation.

    Have a look at the demo page: http://angular-ui.github.com/, search down to the Validate heading.

    From the demo page:

    <input ng-model="email" ui-validate='{blacklist : notBlackListed}'>
    <span ng-show='form.email.$error.blacklist'>This e-mail is black-listed!</span>
    

    then in your controller:

    function ValidateCtrl($scope) {
      $scope.blackList = ['bad@domain.com','verybad@domain.com'];
      $scope.notBlackListed = function(value) {
        return $scope.blackList.indexOf(value) === -1;
      };
    }
    
    0 讨论(0)
  • 2020-11-22 10:44

    In AngularJS the best place to define Custom Validation is Cutsom directive. AngularJS provide a ngMessages module.

    ngMessages is a directive that is designed to show and hide messages based on the state of a key/value object that it listens on. The directive itself complements error message reporting with the ngModel $error object (which stores a key/value state of validation errors).

    For custom form validation One should use ngMessages Modules with custom directive.Here i have a simple validation which will check if number length is less then 6 display an error on screen

     <form name="myform" novalidate>
                    <table>
                        <tr>
                            <td><input name='test' type='text' required  ng-model='test' custom-validation></td>
                            <td ng-messages="myform.test.$error"><span ng-message="invalidshrt">Too Short</span></td>
                        </tr>
                    </table>
                </form>
    

    Here is how to create custom validation directive

    angular.module('myApp',['ngMessages']);
            angular.module('myApp',['ngMessages']).directive('customValidation',function(){
                return{
                restrict:'A',
                require: 'ngModel',
                link:function (scope, element, attr, ctrl) {// 4th argument contain model information 
    
                function validationError(value) // you can use any function and parameter name 
                    {
                     if (value.length > 6) // if model length is greater then 6 it is valide state
                     {
                     ctrl.$setValidity('invalidshrt',true);
                     }
                     else
                     {
                     ctrl.$setValidity('invalidshrt',false) //if less then 6 is invalide
                     }
    
                     return value; //return to display  error 
                    }
                    ctrl.$parsers.push(validationError); //parsers change how view values will be saved in the model
                }
                };
            });
    

    $setValidity is inbuilt function to set model state to valid/invalid

    0 讨论(0)
  • 2020-11-22 10:45

    I recently created a directive to allow for expression-based invalidation of angular form inputs. Any valid angular expression can be used, and it supports custom validation keys using object notation. Tested with angular v1.3.8

            .directive('invalidIf', [function () {
            return {
                require: 'ngModel',
                link: function (scope, elm, attrs, ctrl) {
    
                    var argsObject = scope.$eval(attrs.invalidIf);
    
                    if (!angular.isObject(argsObject)) {
                        argsObject = { invalidIf: attrs.invalidIf };
                    }
    
                    for (var validationKey in argsObject) {
                        scope.$watch(argsObject[validationKey], function (newVal) {
                            ctrl.$setValidity(validationKey, !newVal);
                        });
                    }
                }
            };
        }]);
    

    You can use it like this:

    <input ng-model="foo" invalid-if="{fooIsGreaterThanBar: 'foo > bar',
                                       fooEqualsSomeFuncResult: 'foo == someFuncResult()'}/>
    

    Or by just passing in an expression (it will be given the default validationKey of "invalidIf")

    <input ng-model="foo" invalid-if="foo > bar"/>
    
    0 讨论(0)
提交回复
热议问题