Custom Form Validation Directive

http://angularjs.org/

by jacobwsmith

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular-messages.js"></script>
<div ng-controller="myCtrl">
    <form name="form">
        <label>Test Profanity:
            <input type="text" name="test" 
                ng-model="test" 
                required 
                blacklist="{{bad}}"
            />
        </label>
        <span ng-messages="form.test.$error">
         <span class="invalid" ng-message="required">Required Field</span>
         <span class="invalid" ng-message="blacklist">
          The phrase contains a blacklisted word</span>
          </span>
        <br>
        <br>
        <button type="submit">Submit</button>
    </form>
</div>

CSS

html, body {
    margin: 20px;
    font-size: 14px;
    font-family: 'Arial';
}
label input{
    display: block;
}
input {
    padding: 3px;
    margin-top: 3px;
    margin-bottom: 3px;
    font-size: 14px;
    font-family: 'Arial';
}
input.ng-invalid-required {
    background-color: rgb(250, 255, 189);
}
.invalid{
    display: block;
    color: red;
    font-size: 11px;
}

JavaScript

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

angular.module('app').controller('myCtrl', function ($scope) {
    $scope.test = '';
    $scope.bad = 'fuck,shit';
});

app.directive('blacklist', function (){ 
   return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
          
          var blacklist = attr.blacklist.split(',');
          
          ngModel.$parsers.unshift(function (value) {
              var pass = true;
              
              // lower case the value of the input
              var val = value.toLowerCase();
              
              // blacklist word is exact
              if(blacklist.indexOf(val) !== -1){
                  pass = false;
              }else {
                  for(var i=0;i<blacklist.length;i++){
                      
                      // blacklist word is the first
                      if(val.substring(0, blacklist[i].length+1) === blacklist[i] + ' '){
                          pass = false;
                      }    
                      
                      // blacklist word is the last word, or with a question mark, or with a period
                      else if(val.substring(val.length - blacklist[i].length - 1, val.length) === ' ' + blacklist[i] || 
                              val.substring(val.length - blacklist[i].length-2, val.length) === ' ' + blacklist[i] + '?' ||
                             val.substring(val.length - blacklist[i].length-2, val.length) === ' ' + blacklist[i] + '.'){
                          pass = false;
                      } 
                      
                      // blacklist word exists in the sentence with spaces on both sides
                      else if(val.indexOf(' ' + blacklist[i] + ' ' ) !== -1){
                          pass = false;
                          break;
                      }
                  }
              }
             ngModel.$setValidity('blacklist', pass);
             return value;
          });
     ...