(function() {
var app = angular.module('myapp', [])
app.controller('ctrl1', function($scope) {
$scope.myField = "";
});
app.directive('zipCheck', function($q) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
// add an async validator to the form's validators
ctrl.$asyncValidators.zipCheck = function(modelValue, viewValue) {
// don't validate if empty or less than 5 chars
if (ctrl.$isEmpty(modelValue) || modelValue.length < 5) {
return $q.resolve();
}
// the actual http call
/*
return $http.get('/checkZip?zip='+modelValue)
.then(function(response) {
// handle response as appropriate
return response == "valid";
});
*/
// simulate the http request
var deferred = $q.defer();
window.setTimeout(function() {
if(modelValue == "90210") {
deferred.resolve();
}
else {
deferred.reject();
}
}, 500);
return deferred.promise;
};
}
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myapp" ng-controller="ctrl1">
<form name="myForm">
<!-- note the zip-check attribute - this is the validation directive -->
Zip Code: <input name="myField" ng-model="myField" zip-check />
<!-- validation feedback - checking, invalid, valid -->
<span ng-show="myForm.myField.$pending.zipCheck">...</span>
<span ng-show="myForm.myField.$error.zipCheck">✖</span>
<span ng-show="myField.length >= 5 && myForm.myField.$valid">✔</span>
</form>
</div>