martedì 25 novembre 2014

Input (HTML) validation calling a WEB API method (Part II)

AngularJS v. 1.2.14, WEB API (.NET Framework 4.51)

Based on my last post (http://diegoparolin-codeplus.blogspot.it/2014/10/input-html-validation-calling-web-api.html) I have added a custom Directive to my code, like this.

I first changed the javascript code, where I have created a custom Directive with inside the service that calls the WEB API. (factory).

(function() {
  var app = angular.module('verifyUser-registerUser', []);

  app.factory('checkFiscalCodeService', function ($q, $http) {
      var checkCode = function (value) {
        var deferred = $q.defer();

        $http({
          url: './Api/AccountAPI/CheckFiscalCode',
          method: 'GET',
          params: {
            fiscalCode: value
          }
        })
          .success(function (data) {
            deferred.resolve(data);
          })
          .error(function (reason) {
            deferred.reject(reason);
          });

        return deferred.promise;
      };
      return {
        CheckCode: function(value) {
          return checkCode(value);
        }
      };
    });

  app.directive('checkFiscalCode', ['checkFiscalCodeService', function (checkFiscalCodeService) {
      return {
        // restrict to an attribute type.
        restrict: 'A',

        // element must have ng-model attribute.
        require: 'ngModel',

        // scope = the parent scope
        // elem = the element the directive is on
        // attr = a dictionary of attributes on the element
        // ctrl = the controller for ngModel.
        link: function(scope, elem, attr, ctrl) {

          // add a parser that will process each time the value is
          // parsed into the model when the user updates it.
          ctrl.$parsers.unshift(function(value) {
            var valid = false;
            if (value != null && value.length === 16) {
              checkFiscalCodeService.CheckCode(value).then(function(response) {
                if (response === 'true') {
                  ctrl.$setValidity('validator', true);
                  valid = true;
                } else {
                  ctrl.$setValidity('validator', false);
                }
              }, function(errorResponse) {
                ctrl.$setValidity('validator', false);
              });
            } else {
              ctrl.$setValidity('validator', false);
            }
           
            return value;
          });

          // add a formatter that will process each time the value
          // is updated on the DOM element.
          ctrl.$formatters.unshift(function (value) {
            if (value != null && value.length === 16) {
              checkFiscalCodeService.CheckCode(value).then(function(response) {
                if (response === 'true') {
                  ctrl.$setValidity('validator', true);
                }
              }, function(errorResponse) {
                ctrl.$setValidity('validator', false);
              });
            }

            // return the value or nothing will be written to the DOM.
            return value;
          });
        }
      };
    }]);

  app.controller('RegisterUserController', [
    '$scope', '$http', function($scope, $http) {

    // Do something …

    }
  ]);   
})();

Therefore I have modified my html page in this way:

<div ng-controller="RegisterUserController as registerUser">
    <div class="form-container">
        <form name="form" class="form-horizontal" ng-submit="form.$valid && registerNewUser()" novalidate>
            <div class="row">
                <div class="col-md-7 col-md-offset-2">
<div class="form-group">
                        <label for="inputFiscalCode" class="col-md-4 control-label">Fiscal code</label>
                        <div class="col-md-8">
                            <input name="inputFiscalCode" type="text" class="form-control" id=" inputFiscalCode " ng-model="fiscalCode"
                                   required placeholder="Fiscal code" check-fiscal-code
                                   ng-class="{true: 'ng-invalid ng-dirty'}[submitted]">
                            <span ng-show='form.inputFiscalCode.$error.validator && form. inputFiscalCode.$dirty'>Fiscal code is not valid!</span>
                        </div>
                    </div>
<div class="form-group">
                        <div class="col-md-offset-6 col-md-4">
                            <button type="submit" class="btn btn-primary" ng-click="submitted=true">Register</button>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>

This is the same result:


Bye bye!