var app = angular.module('plunker', []);
app.directive('uniqueUsername', function($http, errorMessages) {
return {
restrict: 'A',
require: ['ngModel', '^form'],
link: function (scope, element, attrs, ctrls) {
var ngModel = ctrls[0]
var formCtrl = ctrls[1]
var formName = formCtrl.$name
//console.log(formCtrl)
function validate(value) {
if (scope.usernames && scope.usernames.indexOf(ngModel.$viewValue) === -1) {
ngModel.$setValidity('unique', true);
errorMessages.unset(formName,'unique');
} else {
ngModel.$setValidity('unique', false);
errorMessages.set(formName,'unique', 'Username "' + value + '" is invalid')
}
}
$http.get( "usernames.json").success( function (usernames) {
scope.usernames = usernames;
validate(ngModel.$viewValue);
});
scope.$watch( function() {
return ngModel.$viewValue;
}, validate);
}
};
})
.factory('errorMessages', function () {
var messages = {}
return {
register : function (formName) {
if(angular.isUndefined(messages[formName])) {
messages[formName] = {}
}
},
set : function (formName, token, message) {
if(angular.isUndefined(messages[formName])) {
messages[formName] = {}
}
messages[formName][token] = message
},
get : function (formName, token) {
if (angular.isUndefined(token)) {
return messages[formName] || false;
} else {
return messages[formName] && messages[formName][token] || false;
}
},
unset : function (formName, token) {
angular.isDefined(messages[formName]) && delete(messages[formName][token]);
}
}
})
.directive('errorMessages', function (errorMessages) {
return {
require : '^?form',
link : function ($scope, $element, $attrs, formCtrl) {
var formName;
//If we're inside a form, assume that's our formName, otherwise use the attribute value
if (formCtrl) {
formName = formCtrl.$name
} else {
formName = $attrs.form
}
//Validate our errorMessages[formName] exists before binding, otherwise we just get undefined
if (!errorMessages.get(formName)) {
errorMessages.register(formName)
}
$scope.messages = errorMessages.get(formName)
}
}
})
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="angular.js@1.2.0-rc1" data-semver="1.2.0-rc1" src="http://code.angularjs.org/1.2.0rc1/angular.js"></script>
<link data-require="bootstrap-css@2.3.2" data-semver="2.3.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" />
<script src="app.js"></script>
</head>
<body>
<h2>Custom Validation Example</h2>
<form name="form" class="form-horizontal" novalidate>
<div class="control-group">
<label class="control-label required">Username:</label>
<div class="controls input-icon">
<input type="text" name="name" ng-model="name" unique-username="" required />
<span class="help-inline" ng-show="form.$error.unique">Username taken!</span>
</div>
</div>
<div error-messages>
<ul ng-show="messages">
<li ng-repeat="(token, mess) in messages"><strong>{{token}}:</strong>{{mess}}</li>
</ul>
</div>
</form>
<div>
<p>Note that I am no longer bound by scope, so long as I specify which form to use</p>
<div error-messages form="form">
<ul ng-show="messages">
<li ng-repeat="(token, mess) in messages"><strong>{{token}}:</strong>{{mess}}</li>
</ul>
</div>
</div>
</body>
</html>
/* Put your css in here */
[
"chuck", "norris", "foo", "bar", "sammla", "acekia"
]