2

Is it feasible and not particularly arduous to create a validation framework that could be used in the following manner:

var myValidations = 
[
 {   'A',
      'This is required',
       function(item) {return item != null;}
    },
    {
     'B',
      "Max 10 chars",
       function(item) {return item.length <=10 && item.length >0;}
    },
    {
     'C',
      'Must start with Z',
       function(item) {return item[0] == 'Z'}
    }];

    $scope.model.Message.AddValidation('A');
    $scope.model.Message.AddValidation('C');

    $scope.onSave = function()
    {
        if(!$scope.model.IsValid)
        {
            // $scope.model.errors
        }

    }

<input type="text" ng-model="model.Message"/>

What might be involved to get a basic implementation going?

Perhaps there are existing AngularJS Validation frameworks with similar usage concepts I've yet to stumble upon?

4
  • 2
    Why not to use ng-form that allows dynamic validation and on fields you can have ng-required, also you have standard min, max for input fields, and use regex validation for thi item[0] == 'Z' type of verifications? Commented Sep 17, 2015 at 19:26
  • 2
    Yes, AngularJS already provides a validation framework to do what you are thinking. Commented Sep 17, 2015 at 19:40
  • Use docs.angularjs.org/guide/forms . If you need to implement your model of validator (defined on js), you can to create directives using $compile phase to convert to angular form validation. Commented Sep 17, 2015 at 19:59
  • I suppose I am looking for an approach that forgoes the use of Angular Directives and allows me to place validators directly to my model. This then allows me to dynamically bind validation to form elements. Commented Sep 18, 2015 at 10:47

3 Answers 3

4

This is how you would do it using the latest version of angular, and building custom validation directives that use AngularJS's validation framework:

Step 1: Add Some Style

This is to make things look nice...

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

<style>
  ul {
    margin: 0;
    padding:0;
  }
</style>

Step 2: Add AngularJS Libraries

You need the core AngularJS libraries and ngMessages:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-messages.min.js"></script>

Step 3: Define your Validation Directives

Yes, I know there are already pre-defined AngularJS directives for "required" and "max length", but this is an SO answer and it's important that you know how to define ones yourself.

app.directive('rqrd', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ngModel) {
      ngModel.$validators.rqrd = function(modelValue, viewValue) {
        var value = modelValue || viewValue;
        return value != null && value != undefined && value != '';
      }
    }
  }
});

app.directive('max', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ngModel) {
      var maxValue = parseInt(attr.max);
      ngModel.$validators.max = function(modelValue, viewValue) {
        var value = modelValue || viewValue;
        return value.length > 0 && value.length <= maxValue;
      }
    }
  } 
});

app.directive('startsWith', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ngModel) {
      ngModel.$validators.startsWith = function(modelValue, viewValue) {
        var value = modelValue || viewValue;
        return value && value.length > 0 && value.indexOf(attr.startsWith) == 0;
      }
    }
  } 
});

Step 4: Use your Validation Directives

<form name="form">

  Favorite Color   <br />
  <input name="color" ng-model="color" rqrd max="10"  />  
  <ul ng-messages="form.color.$error">
     <li ng-message="rqrd" class="label label-danger">This is required</li>
     <li ng-message="max" class="label label-danger">Max 10 chars</li>
  </ul> 
  Name <br />
  <input name="name" ng-model="name" starts-with="Z"  /> 
    <ul ng-messages="form.name.$error">
     <li ng-message="rqrd" class="label label-danger">Please enter an Age</li>
     <li ng-message="startsWith" class="label label-danger">Must start with Z</li>
  </ul> 

</form>

Checking that Form is Valid

if ($scope.form.$valid) {
   ...
}

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

    app.controller('ctrl', function($scope) {
       
    });

    app.directive('rqrd', function() {
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
          ngModel.$validators.rqrd = function(modelValue, viewValue) {
            var value = modelValue || viewValue;
            return value != null && value != undefined && value != '';
          }
        }
      }
    });

    app.directive('max', function() {
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
          var maxValue = parseInt(attr.max);
          ngModel.$validators.max = function(modelValue, viewValue) {
            var value = modelValue || viewValue;
            return value.length > 0 && value.length <= maxValue;
          }
        }
      } 
    });

    app.directive('startsWith', function() {
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
          ngModel.$validators.startsWith = function(modelValue, viewValue) {
            var value = modelValue || viewValue;
            return value && value.length > 0 && value.indexOf(attr.startsWith) == 0;
          }
        }
      } 
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-messages.min.js"></script>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">

    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

    <style>
      ul {
        margin: 0;
        padding:0;
      }
    </style>

    <h3>Example heading </h3>
    <div ng-app="app" ng-controller="ctrl">
    <form name="form">

      Favorite Color   <br />
      <input name="color" ng-model="color" rqrd max="10"  />  
      <ul ng-messages="form.color.$error">
         <li ng-message="rqrd" class="label label-danger">This is required</li>
         <li ng-message="max" class="label label-danger">Max 10 chars</li>
      </ul> 
      Name <br />
      <input name="name" ng-model="name" starts-with="Z"  /> 
        <ul ng-messages="form.name.$error">
         <li ng-message="rqrd" class="label label-danger">Please enter an Age</li>
         <li ng-message="startsWith" class="label label-danger">Must start with Z</li>
      </ul> 
    </form>
      
    </div>

Sign up to request clarification or add additional context in comments.

Comments

1

Angular already has a validation framework built in, which includes capabilities to add custom validations. This is done by creating custom directives which define validation functions, then adding those directives as attributes to your input. IE from the Angular example, we create this custom integer directive:

app.directive('integer', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$validators.integer = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          // consider empty models to be valid
          return true;
        }

        if (INTEGER_REGEXP.test(viewValue)) {
          // it is valid
          return true;
        }

        // it is invalid
        return false;
      };
    }
  };
});

Then add it to our input:

<input type="number" ng-model="size" name="size"
           min="0" max="10" integer />{{size}}<br />

And we can then access its validation status by querying form.size.$error.integer

Comments

1

A very nice framework in github https://github.com/turinggroup/angular-validator

<div class="col-sm-10">


<input  type = "text"
 name = "blur"
 validate-on="blur"
  class = "form-control"
ng-model = "form.blur"
  ng-pattern="/regex/"
  invalid-message="'You must enter the word `regex`'"
  required-message="'Yo! This field is required..'"
  required></div>

Demo here

Another well detailed example here

1 Comment

Does this validation works with Dropdown control because i am using it but it does not works on dropdown control.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.