Episode 23 of 25

Form Validation Part 2

Advanced form validation — custom validators, pattern matching, and real-time feedback.

Let's explore more advanced form validation techniques in AngularJS.

Pattern Validation

<!-- Phone number pattern -->
<input type="text" name="phone" ng-model="user.phone"
       ng-pattern="/^[0-9]{10}$/" placeholder="10-digit number">

<p ng-show="myForm.phone.$error.pattern">
    Please enter a valid 10-digit phone number.
</p>

Custom Validation with $validators

app.directive('passwordStrength', function() {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            ngModel.$validators.strength = function(value) {
                if (!value) return false;
                // Must have uppercase, lowercase, number, and 8+ chars
                var hasUpper = /[A-Z]/.test(value);
                var hasLower = /[a-z]/.test(value);
                var hasNumber = /[0-9]/.test(value);
                return hasUpper && hasLower && hasNumber && value.length >= 8;
            };
        }
    };
});
<input type="password" name="password" ng-model="user.password"
       password-strength required>

<p ng-show="myForm.password.$error.strength">
    Password must be 8+ chars with uppercase, lowercase, and number.
</p>

Confirm Password

app.directive('matchPassword', function() {
    return {
        require: 'ngModel',
        scope: { matchPassword: '=' },
        link: function(scope, element, attrs, ngModel) {
            ngModel.$validators.match = function(value) {
                return value === scope.matchPassword;
            };
            scope.$watch('matchPassword', function() {
                ngModel.$validate();
            });
        }
    };
});
<input type="password" ng-model="user.password" name="password">
<input type="password" ng-model="confirmPw" name="confirm"
       match-password="user.password">

<p ng-show="myForm.confirm.$error.match">Passwords do not match.</p>

Complete Form Example

<form name="signupForm" ng-submit="register()" novalidate>
    <input type="text" name="name" ng-model="user.name"
           required ng-minlength="2">
    <input type="email" name="email" ng-model="user.email" required>
    <input type="password" name="password" ng-model="user.password"
           required ng-minlength="8">

    <button type="submit" ng-disabled="signupForm.$invalid">
        Register
    </button>
</form>