Angular js
1 Introduction to AngularJS
1-1 Overview of AngularJS
1-2 History and Evolution
1-3 Key Features and Benefits
1-4 Comparison with Other Frameworks
2 Setting Up the Development Environment
2-1 Installing Node js and npm
2-2 Setting Up Angular CLI
2-3 Creating a New AngularJS Project
2-4 Project Structure Overview
3 AngularJS Fundamentals
3-1 Understanding MVC Architecture
3-2 Data Binding
3-3 Directives
3-4 Filters
3-5 Services and Dependency Injection
4 Controllers and Scope
4-1 Introduction to Controllers
4-2 Scope and its Hierarchy
4-3 Controller Communication
4-4 Best Practices for Controllers
5 Directives
5-1 Built-in Directives
5-2 Custom Directives
5-3 Directive Scope
5-4 Directive Lifecycle
5-5 Best Practices for Directives
6 Services and Dependency Injection
6-1 Introduction to Services
6-2 Creating Custom Services
6-3 Dependency Injection in AngularJS
6-4 Service Best Practices
7 Filters
7-1 Built-in Filters
7-2 Creating Custom Filters
7-3 Filter Best Practices
8 Routing and Navigation
8-1 Introduction to AngularJS Routing
8-2 Configuring Routes
8-3 Route Parameters
8-4 Route Guards
8-5 Best Practices for Routing
9 Forms and Validation
9-1 Introduction to AngularJS Forms
9-2 Form Controls and Validation
9-3 Custom Validation
9-4 Form Submission
9-5 Best Practices for Forms
10 HTTP and AJAX
10-1 Introduction to HTTP in AngularJS
10-2 Making HTTP Requests
10-3 Handling HTTP Responses
10-4 Interceptors
10-5 Best Practices for HTTP
11 Testing in AngularJS
11-1 Introduction to Testing
11-2 Unit Testing with Jasmine
11-3 End-to-End Testing with Protractor
11-4 Test Best Practices
12 Advanced Topics
12-1 Animations in AngularJS
12-2 Internationalization (i18n)
12-3 Performance Optimization
12-4 Security Best Practices
13 Project Development
13-1 Planning and Designing the Project
13-2 Implementing Features
13-3 Testing and Debugging
13-4 Deployment
14 Conclusion
14-1 Recap of Key Concepts
14-2 Future of AngularJS
14-3 Resources for Further Learning
Custom Validation in AngularJS

Custom Validation in AngularJS

Key Concepts

1. Custom Validation Functions

Custom validation functions allow you to define specific rules for validating form inputs. These functions can be attached to form controls and are executed when the form is submitted or when the control value changes.

Example:

        app.directive('customValidator', function() {
            return {
                require: 'ngModel',
                link: function(scope, element, attrs, ngModel) {
                    ngModel.$validators.customValidator = function(modelValue, viewValue) {
                        return viewValue === 'valid';
                    };
                }
            };
        });
    

Imagine custom validation functions as security checks at an airport. Each check (function) ensures that only valid passengers (inputs) are allowed to board the plane (form submission).

2. Form and Input States

AngularJS provides various states for forms and inputs, such as $valid, $invalid, $pristine, and $dirty. These states help in tracking the validity and interaction status of form controls.

Example:

        <form name="myForm">
            <input type="text" name="myInput" ng-model="myInput" custom-validator>
            <p ng-show="myForm.myInput.$invalid">Input is invalid!</p>
        </form>
    

Think of form and input states as traffic lights. The lights (states) indicate whether the road (form) is safe to proceed (valid) or if there is an issue (invalid) that needs attention.

3. Validation Directives

Validation directives are custom directives that can be used to apply validation rules to form controls. These directives can be reused across different forms and inputs.

Example:

        app.directive('minLength', function() {
            return {
                require: 'ngModel',
                link: function(scope, element, attrs, ngModel) {
                    ngModel.$validators.minLength = function(modelValue, viewValue) {
                        return viewValue.length >= 5;
                    };
                }
            };
        });
    

Consider validation directives as reusable tools in a toolbox. Each tool (directive) can be used to perform a specific task (validation) on different projects (forms).

4. Error Messages

Error messages are used to inform users about validation errors. These messages can be displayed conditionally based on the state of the form controls.

Example:

        <form name="myForm">
            <input type="text" name="myInput" ng-model="myInput" custom-validator>
            <p ng-show="myForm.myInput.$error.customValidator">Input must be 'valid'.</p>
        </form>
    

Imagine error messages as signs on a road. Each sign (message) points out a specific issue (error) that needs to be addressed before proceeding.

5. Form Submission Handling

Form submission handling involves controlling what happens when a form is submitted. This can include preventing submission if the form is invalid or performing additional actions before submission.

Example:

        <form name="myForm" ng-submit="submitForm()">
            <input type="text" name="myInput" ng-model="myInput" custom-validator>
            <button type="submit" ng-disabled="myForm.$invalid">Submit</button>
        </form>
    

Think of form submission handling as a gatekeeper. The gatekeeper (handler) ensures that only valid forms (passengers) are allowed to pass through (submit).

6. Cross-Field Validation

Cross-field validation involves validating one input based on the value of another input. This is useful for scenarios like password confirmation or date range validation.

Example:

        app.directive('passwordMatch', function() {
            return {
                require: 'ngModel',
                link: function(scope, element, attrs, ngModel) {
                    ngModel.$validators.passwordMatch = function(modelValue, viewValue) {
                        return viewValue === scope.myForm.password.$viewValue;
                    };
                }
            };
        });
    

Consider cross-field validation as a puzzle. Each piece (input) must fit together (match) with another piece to complete the puzzle (form).

7. Asynchronous Validation

Asynchronous validation involves validating inputs by making asynchronous calls, such as checking if a username is available. This type of validation requires handling promises or callbacks.

Example:

        app.directive('uniqueUsername', function($http) {
            return {
                require: 'ngModel',
                link: function(scope, element, attrs, ngModel) {
                    ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
                        return $http.get('/api/checkUsername/' + viewValue);
                    };
                }
            };
        });
    

Imagine asynchronous validation as a background check. The check (validation) takes some time to complete, but once done, it provides crucial information (validity) about the input.

8. Custom Validators in Controllers

Custom validators can also be defined in controllers and used to validate form inputs. This approach is useful for complex validation logic that doesn't fit well within directives.

Example:

        app.controller('MyController', function($scope) {
            $scope.validateInput = function(input) {
                return input === 'valid';
            };
        });
    

Think of custom validators in controllers as specialized tools in a workshop. Each tool (validator) is designed to handle specific tasks (validation) that require detailed attention.

9. Testing Custom Validators

Testing custom validators ensures that they work as expected. This involves writing unit tests to verify the behavior of the validators under different conditions.

Example:

        describe('customValidator', function() {
            var $compile, $rootScope;
            beforeEach(module('myApp'));
            beforeEach(inject(function(_$compile_, _$rootScope_) {
                $compile = _$compile_;
                $rootScope = _$rootScope_;
            }));
            it('should validate input correctly', function() {
                var element = $compile('<form name="myForm"><input name="myInput" ng-model="myInput" custom-validator></form>')($rootScope);
                $rootScope.myInput = 'valid';
                $rootScope.$digest();
                expect($rootScope.myForm.myInput.$valid).toBe(true);
            });
        });
    

Consider testing custom validators as quality control in a factory. Each product (validator) is rigorously tested (unit tested) to ensure it meets the required standards (expected behavior).