AngularJS Custom Directives

Directive controls the rendering of the HTML inside an AngularJS application. Directives such as ng-click, ng-show/ng-hide, ng-repeat, and many others found in the AngularJS core script make it easy to get started using the framework. Directives are a core function of AngularJS that gets run when the DOM is compiled by the compiler.

It is possible to implement our own directives. AngularJS enables us to create new directives so that we can encapsulate and simplify DOM manipulation. Custom directives are used to extend the functionality of HTML. A custom directive simply replaces the element for which it is activated.

How Custom Directives Work


During the process of bootstrap AngularJS find the matching element and do a one time activity using the compile method of the custom directive and then process the element using the link() method of the custom directive. In AngularJS we can create the custom directive for the following types of elements.

Element directives: Directive activates when a matching element is encountered. Restrict mode is defined by “E”.

Example:
<ng-directives></ng-directives>

Attribute: Directive activates when a matching attribute is encountered. Restrict mode is defined by “A”.

Example: 
<span ng-directive></span>

CSS:
Directive activates when a matching css style is encountered. Restrict mode is defined by “C”.

Example:
<span class="ng-directive"></span>

Comment:
Directive activates when a matching comment is encountered. Restrict mode is defined by “M”.

Example
<!-- directive: ng-directive -->

Let us create custom directives


Now we read how to create custom directives. We start with some simple examples and move towards some complex custom directives.

Example 1
  1. <html>  
  2.   
  3. <head>  
  4.     <title>Angular JS Example</title>  
  5.     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js">  
  6.         </script>  
  7.         <style>  
  8.             .sparkline  
  9.             {  
  10.                 background-color: brown;  
  11.                 font-size: large;  
  12.                 height: 100px;  
  13.                 width: 200px;  
  14.                 color: aqua  
  15.             }  
  16.         </style>  
  17.   
  18. </head>  
  19.   
  20. <body>  
  21.     <h2>AngularJS Custom Directive Example</h2>  
  22.     <div ng-app="mainApp">  
  23.         <divng-demo>  
  24.             </div>  
  25.             </div>  
  26.   
  27. </body>  
  28. <script>  
  29.     var mainApp = angular.module("mainApp", []);  
  30.     mainApp.directive('ngDemo', function()  
  31.     {  
  32.         return  
  33.         {  
  34.             restrict: 'A',  
  35.             template: '<div class="sparkline">This is simple Custom Directive of Element Type</div>'  
  36.         }  
  37.     });  
  38. </script>  
  39.   
  40.   
  41. </html>  
Output

output

In the above example we created a custom directive using the following code.
  1. mainApp.directive('ngDemo', function()  
  2. {  
  3.     return  
  4.     {  
  5.         restrict: 'A',  
  6.         template: '<div class="style_">This is simple Custom Directive of Element Type</div>'  
  7.     }  
  8. });  
In the above code we defined the name of the directive (ngDemo). Type of the directive is an attribute that is defined by restrict: ‘A’. Here the restrict option is used to define the type of element for which this directive will invoke. In template option we define the text (template) that replaces the content of the element that invokes this directive. Template is an option where we are specifying the html that will be appended or append.

<divng-demo></div>

Using the above code we invoked the directive. Notice that when we invoke it (ng-demo) and the name of directive (ngDemo), both are not the same. This is because AngularJS will handle translating the camel cased name when we define it to the snake case when we invoke it.

Method to build a directive


In AngularJS we can create the custom directive in two ways. First method is returning a directive description object that we performed in the last example. The second method is using a “link” function. Building a directive with the link function is usually enough for relatively simple directives. We will read about this method later in this article.

The templateUrl

In the previous example we define inline template. Instead of this inline template we can define html text in a file and implement this file using the templateUrl, which will use ajax to pull the template.

Example
  1. <html>  
  2.   
  3. <head>  
  4.     <title>Angular JS Example</title>  
  5.     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js">  
  6.         </script>  
  7.         <style>  
  8.             .style_  
  9.             {  
  10.                 background-color: brown;  
  11.                 font-size: large;  
  12.                 height: 300px;  
  13.                 width: 300px;  
  14.                 color: aqua  
  15.             }  
  16.         </style>  
  17.   
  18. </head>  
  19.   
  20. <body>  
  21.     <h2>AngularJS Custom Directive Example</h2>  
  22.     <div ng-app="mainApp">  
  23.         <divng-demo>  
  24.             </div>  
  25.             </div>  
  26.   
  27. </body>  
  28. <script>  
  29.     var mainApp = angular.module("mainApp", []);  
  30.     mainApp.directive('ngDemo', function()  
  31.     {  
  32.         var directive = {};  
  33.         directive.restrict = 'A'/* restrict this directive to elements */  
  34.         directive.templateUrl = "index.html"/* Url for template*/  
  35.         return directive;  
  36.     });  
  37. </script>  
  38.   
  39.   
  40. </html>  
Index.html

This is TemplateUrl Example.
  1. <br/>  
  2. <div class="style_">This is simple Custom Directive of Element Type<br/>  
  3.     <bstyle="color:#BFEF10">delhi is capital of India</b>  
  4.         <img src="delhi.png" />  
  5.         </div>  
Output

output

In the above example we create an index .html page and load this page using the templateUrl property,

directive.templateUrl = "index.html";


Isolating the $scope from the Directive
  1. <%@RegisterAssembly="AjaxControlToolkit"Namespace="AjaxControlToolkit"TagPrefix="ajaxToolkit"%>  
  2.     <html>  
  3.   
  4.     <head>  
  5.         <title>Angular JS Example</title>  
  6.         <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js">  
  7.             </script>  
  8.   
  9.     </head>  
  10.   
  11.     <body>  
  12.         <h2>AngularJS Custom Directive Example</h2>  
  13.         <div ng-app="mainApp" ng-controller="MyController">  
  14.   
  15.   
  16.             <userinfouser="pankaj">  
  17.                 </userinfo><br/>  
  18.                 <userinfouser="rahul">  
  19.                     </userinfo><br/>  
  20.                     <userinfouser="sandeep">  
  21.                         </userinfo><br/>  
  22.                         </div>  
  23.     </body>  
  24.   
  25.   
  26.   
  27.     <script>  
  28.         var myapp = angular.module("mainApp", []);  
  29.         myapp.directive('userinfo', function()  
  30.         {  
  31.             var directive = {};  
  32.             directive.restrict = 'E';  
  33.             directive.template = "<div> Isolate The $scope</div>";  
  34.             return directive;  
  35.         });  
  36.     </script>  
  37.   
  38.   
  39.     </html>  
Output

output
An isolate scope is a separate scope object tied to the directive. In the previous example we declare the directory, <userinfouser="pankaj"></userinfo>”. If we want to use same directory multiple times like <userinfouser="pankaj"></userinfo><userinfouser="sandeep"></userinfo>” then userinfoelements would be replaced by the same HTML template because $scope variables typically have the same values everywhere inside the same controller. Referencing $scope variables directly makes it hard to reuse the directive more than once within the same controller. So to resolve this issue we need to bind the HTML template to an isolate scope.

Example
  1. <%@RegisterAssembly="AjaxControlToolkit"Namespace="AjaxControlToolkit"TagPrefix="ajaxToolkit"%>  
  2.     <html>  
  3.   
  4.     <head>  
  5.         <title>Angular JS Example</title>  
  6.         <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js">  
  7.             </script>  
  8.   
  9.     </head>  
  10.   
  11.     <body>  
  12.         <h2>AngularJS Custom Directive Example</h2>  
  13.         <div ng-app="mainApp" ng-controller="MyController">  
  14.   
  15.   
  16.             <userinfouser="pankaj">  
  17.                 </userinfo><br/>  
  18.                 <userinfouser="rahul">  
  19.                     </userinfo><br/>  
  20.                     <userinfouser="sandeep">  
  21.                         </userinfo><br/>  
  22.                         </div>  
  23.     </body>  
  24.   
  25.   
  26.   
  27.     <script>  
  28.         var myapp = angular.module("mainApp", []);  
  29.         myapp.directive('userinfo', function()  
  30.          {  
  31.             var directive = {};  
  32.   
  33.             directive.restrict = 'E';  
  34.   
  35.             directive.template = "User : {{user.firstName}} {{user.lastName}} {{user.age}}";  
  36.   
  37.             directive.scope =  
  38.             {  
  39.                 user: "=user"  
  40.             }  
  41.   
  42.             return directive;  
  43.         });  
  44.         myapp.controller("MyController", function($scope, $http)  
  45.          {  
  46.             $scope.pankaj = {};  
  47.             $scope.pankaj.firstName = "Pankaj";  
  48.             $scope.pankaj.lastName = "Choudhary";  
  49.             $scope.pankaj.age = 21;  
  50.   
  51.             $scope.rahul = {};  
  52.             $scope.rahul.firstName = "Rahul";  
  53.             $scope.rahul.lastName = "Prajapat";  
  54.             $scope.rahul.age = 20;  
  55.   
  56.             $scope.sandeep = {};  
  57.             $scope.sandeep.firstName = "Sandeep";  
  58.             $scope.sandeep.lastName = "Sandeep";  
  59.             $scope.sandeep.age = 22;  
  60.         });  
  61.     </script>  
  62.   
  63.   
  64.     </html>  
Output

output

The compile() and link() functions


If we want to do something extra in our custom directive then everything is not possible within the HTML template, for this we can use the compile() and link() function. Both methods are used to define how the directive modifies the HTML that matches the directive.

The compile() function used a one time configuration needed of the element containing the directive. The compile() function is called only one time for each occurrence of the directive in the HTML page. The compile() function contains two parameters: element and attributes. The element parameter is a jqLite wrapped DOM element, and the attributes parameter is a JavaScript object containing properties for all the attributes of the DOM element.

The compile() function returns a link function, this link() function is called every time the element is to be bound to data in the $scope object. The link() function takes three parameters: $scope, element, and attributes. The $scope parameter is a normal scope object or an isolated scope if we specified one in the directive definition object. The element and attributes element are same as compile parameters.

Example
  1. <%@RegisterAssembly="AjaxControlToolkit"Namespace="AjaxControlToolkit"TagPrefix="ajaxToolkit"%>  
  2.     <html>  
  3.   
  4.     <head>  
  5.         <title>Angular JS Example</title>  
  6.         <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js">  
  7.             </script>  
  8.   
  9.     </head>  
  10.   
  11.     <body>  
  12.         <h2>AngularJS Custom Directive Example</h2>  
  13.         <div ng-app="mainApp" ng-controller="MyController">  
  14.   
  15.   
  16.             <userinfouser="pankaj">  
  17.                 </userinfo><br/>  
  18.                 <userinfouser="rahul">  
  19.                     </userinfo><br/>  
  20.                     <userinfouser="sandeep">  
  21.                         </userinfo><br/>  
  22.                         </div>  
  23.     </body>  
  24.   
  25.   
  26.   
  27.     <script>  
  28.         var myapp = angular.module("mainApp", []);  
  29.         myapp.directive('userinfo', function()  
  30.         {  
  31.             var directive = {};  
  32.   
  33.             directive.restrict = 'E';  
  34.   
  35.             directive.template = "User : {{user.firstName}} {{user.lastName}} {{user.age}}";  
  36.   
  37.             directive.scope =  
  38.             {  
  39.                 user: "=user"  
  40.             };  
  41.             directive.compile = function(element, attributes)  
  42.             {  
  43.                 element.css("border""2px solid blue");  
  44.   
  45.                 var linkpara = function($scope, element, attributes)   
  46.                 {  
  47.                     element.html("User First Name: <b>" + $scope.user.firstName + "</b> , User Last Name: <b>" + $scope.user.lastName + "</b>" + ", User Age: <b>" + $scope.user.age + "</b>");  
  48.                     element.css("background-color""yellow");  
  49.                 }  
  50.                 return linkpara;  
  51.             };  
  52.   
  53.             return directive;  
  54.         });  
  55.         myapp.controller("MyController", function($scope, $http)   
  56.         {  
  57.             $scope.pankaj = {};  
  58.             $scope.pankaj.firstName = "Pankaj";  
  59.             $scope.pankaj.lastName = "Choudhary";  
  60.             $scope.pankaj.age = 21;  
  61.   
  62.             $scope.rahul = {};  
  63.             $scope.rahul.firstName = "Rahul";  
  64.             $scope.rahul.lastName = "Prajapat";  
  65.             $scope.rahul.age = 20;  
  66.   
  67.             $scope.sandeep = {};  
  68.             $scope.sandeep.firstName = "Sandeep";  
  69.             $scope.sandeep.lastName = "Sandeep";  
  70.             $scope.sandeep.age = 22;  
  71.         });  
  72.     </script>  
  73.   
  74.   
  75.     </html>  
Output

output
Custom directives allow us to create the directive as per our requirement and using compile and link function we can add some external styles in custom directive.
 
Read more articles on AngularJS: