What?

The ui-validate and ui-validate-async directives makes it very easy to create custom validator expressions.

e-mail

This e-mail is black-listed! This e-mail is already taken! Verifying e-mail on server...
is form valid: {{form.$valid}}

email errors: {{form.email.$error | json}}
email pending: {{form.email.$pending | json}}

password

Passwords do not match!
is form valid: {{form.$valid}}

password errors: {{form.confirm_password.$error| json}}

Why?

Angular.js comes with several built-in validation mechanisms for input fields (ngRequired, ngPattern etc.) but using an arbitrary validation function requires creation of custom directives to interact with angular's validation mechanism. The ui-validate directive makes it easy to use any function(s) defined in scope as a validator function(s). A validator function will trigger validation on both model and input changes.

<input name="email" ng-model="email"
                        ui-validate="{blacklist : 'notBlackListed($value)' }"> Is e-mail black-listed? {{!!form.email.$error.blacklist}}
                        ui-validate-async="{alreadyExists: 'doesNotExist($modelValue)' }"> Is e-mail already registered? {{!!form.email.$error.alreadyExists}}
                        <input name="password" required ng-model="password"> <input name="confirm_password"
                        ui-validate=" '$value==password' "
                        ui-validate-watch=" 'password' "> Passwords match? {{!!form.confirm_password.$error.validator}} ...
                        $scope.notBlackListed = function(value) { var blacklist = ['bad@domain.com','verybad@domain.com']; return blacklist.indexOf(value)
                        === -1; }

How?

ui-validate

Create an expression inside a string. If it evaluates to truethe input is valid, the rule name will be validator by default.

ui-validate=" 'validateFoo($value)' " Input is valid: {{!!myForm.myInput.$error.validator}}

Or define multiple rules by creating an object where the key is the rule name and the value is the expression string.

ui-validate="{foo:'valFoo($value)', bar:'$value == someVar'}" Foo rule passes: {{!!myForm.myInput.$error.foo}} Bar rule
                        passes: {{!!myForm.myInput.$error.bar}}

Use ui-validate-watch or ui-validate-watch-collection to watch expressions. With ui-validate-watch-object-equality you can enable deep watching:

ui-validate-watch="'myValue'"
ui-validate-watch-collection="'myArrayOrObject'"
ui-validate-watch="'myDeepNestedObject'" ui-validate-watch-object-equality="true"

ui-validate-async

Create an expression inside a string. Expresion must return a promise. The rule name will be validatorAsync by default. Until promise is fulfilled, rule is placed on $pending list. if promise is rejected, validation fail.

ui-validate-async=" 'validateAsyncFoo($value)' " Input is valid: {{!!myForm.myInput.$error.validatorAsync}}

Or define multiple rules by creating an object where the key is the rule name and the value is the expression string.

ui-validate-async="{fooAsync:'valAsyncFoo($value)'}" fooAsync rule passes: {{!!myForm.myInput.$error.fooAsync}}