AngularJS: Understanding Custom Directive

While working on one of the applications being developed on the AngularJS framework, I came across a situation where I had to add a reusable and independent functionality on a DOM element. This could easily be done using JQuery. However, since the app was being developed using AngularJS, the best practice was to stick to that only, which was made easy with the AngularJS “Directive” tool.

Directive is one of the most powerful tools of AngularJS, and it includes attributes such as ng-show, ng-include, and ng-bind. In addition to this, AngularJS allows developers to define custom directives that express the application specifications and requirements much more clearly and semantically than regular HTML elements.

What is a Directive?

In the simplest terms, a directive in AngularJS is a reusable component. Directives in AngularJS encapsulate all the behavioral properties and functionalities of an element in a semantic way, thereby keeping all of the functionality grouped together. This helps to keep track of changes of one HTML section in one place rather than tracking the changes on a global level in a script.

A more formal definition of a directive is: In AngularJS, a directive is a JavaScript factory function defined inside an AngularJS module that holds a set of instructions for the HTML compiler for defining a specified behavior of a DOM element.

Defining a Directive

This section lists simple steps to define a custom directive in an AngularJS module. First, we need to define an Angular app.

var myApp = angular.module(‘myApp’, []);

Now, define a directive.

myApp.directive(‘myDirective’, function() {
	return {
		restrict: ‘E’,
template: ‘<h1>I made a directive!</h1>’
	};
});

This defines a directive. restrict: 'E' means “restrict the usage of this directive to only Elements.” Thus we embed this directive in the HTML page as

<body ng-app=“myApp”>
	<my-directive></my-directive>
</body>

This code piece is equivalent to

<body ng-app=“myApp”>
	<h1>I made a directive!</h1>
</body>

Note that AngularJS maps the naming conventions from HTML’s my-directive to JavaScript”s myDirective.

This is a basic example of definition and usage of a directive. The following is a more advanced example.

Consider a use case where we need an HTML structure to display movie titles. The HTML snippet looks like this:

<div class="movie">
    <div class="title">
        Movie Title
    </div>
    <div class="movie">
        Movie name
    </div>
</div>

The code given above seems rich in terms of CSS classes and HTML tags, but the code is not repeatable. In a case where multiple movies will need to be displayed, this code structure would become messy. Moreover, if at a later stage there comes a requirement to add a movie poster and some other functionality to the movie section, the code will need to be modified at multiple places, which is not sustainable.

Instead, we can use directive in this situation.

First, we define the Angular app and controller. Note that the list of movies is defined in the controller.

var myApp = angular.module('myApp', []);

myApp.controller('myController', function($scope) {
    $scope.movies = ['Ice Age', 'Frozen'];
});

Next, define the directive.

myApp.directive('myMovie', function() {
  return {
    restrict: 'E',
    transclude: 'true',
    template: '<span ng-transclude></span>',
    link: function(scope, element, attr){
          element.append("<strong>"+attr.title+"</strong>");
    }
  };
});

Now, embed the directive in the HTML code.

<div ng-app="myApp" ng-controller="myController">
    <div ng-repeat="movie in movies">
<my-movie title="{{movie}}">
    Movie Title :  
</my-movie>
    </div>
</div>

The output is

directive1

Ta-da!

Examine the Directive

A directive is, thus, implemented as a function, which returns an object, called Data Definition Object (DDO), that configures the directive’s behavior and template. restrict, template, etc., are the fields of this object.

restrict: defines the type of HTML element which can act as a trigger for the directive.

  • E: Element – the directive is used as an HTML tag
  • A: Attribute – the directive is used as an HTML attribute
  • C: Class – the directive is used as a CSS (in an element’s class=”…” definition)

transclude: specifies whether to transfer and include the original inner content of the directive’s HTML markup (‘Movie Title :’) in the destination markup (which is defined in the template).

template: specifies the HTML content that should be added to the HTML result of the directive.

There’s More…

Let’s further experiment with the directive.

  1. More movies can be added to the movies in the controller.
    $scope.movies = ['Ice Age', 'Frozen', 'Aladdin', 'Tangled', 'Cars'];

    The output
    directive2

  2. Different functions for different movies can be added. Let’s add some content to the movies section depending on the movie title.
    Modify the directive’s link function

    link: function(scope, element, attr){
            element.append("<strong>"+attr.title+"</strong>");
            if(attr.title === 'Ice Age'){
                element.append("<br> say hi to Manny!");
            }
            else {
                element.append("<br> all hail the Snow Queen!");
            }
          }

    The output
    directive3

Angular provides several other fields in directive. When these fields are used in conjunction, they truly make directive perform magic on the HTML page.

Advantages

Directives are useful in creating repeatable and independent code. They modularize the code by clubbing requirement-specific behavioral functions in one place, rather than creating some objects in the central controller and manipulating them using multiple JavaScript methods. Such a modular code will have multiple directives that handle their own functionalities and data, and work in isolation from other directives. As an added benefit, the HTML page and Angular scripts becomes less messy and more organized.

Conclusion

In this post we learned about Custom Directives in AngularJS through a brief introduction and examples of their usages and their advantages. With Directives, you can create custom HTML tags, attributes, or classes to implement required functionality over an HTML section. This then becomes an independent and reusable component that can be embedded in the same or a different HTML page.

Should we take it further? How do directives interact with the controllers? How does it access its functions and members? We’ll explore this in the next blog, which is available here!

Akanksha Chaturvedi

Akanksha Chaturvedi

Software Engineer

Akanksha Chaturvedi is a Software Engineer at the 3Pillar Noida office in India. She has experience in Java technology, AngularJS, and iOS application development in Swift. She is very passionate about the design and analysis of computer algorithms, and has a keen interest in how those algorithms solve real world problems. She earned a Bachelor of Engineering in Computer Engineering from Netaji Subhas Institute of Technology (NSIT), Delhi. In her leisure time, she loves to travel, play badminton, watch tennis, and read novels.

31 Responses to “AngularJS: Understanding Custom Directive”
  1. Pritish on

    Thank you for making it so easy to understand the concepts

    Reply
  2. Rahul Kumar on

    Hi folks , I m glad to know about angular js directives .I just want to know that can it is possible in transclude we can bind the template to parent template or We can append any text,html ,string before rendering the directive into the dom .becuase here only transclude feature is mainly concern about appending while template is rendered in the dom .Is there any procedure we can provide the feasability of prepending the text .html in directive before rendering to the dom .

    Thanks
    Rahul Kumar

    Reply
  3. Frank M on

    Nice post. Thanks AKANKSHA!

    Reply
  4. Mahesh on

    Hi Akanksha,

    Very neat and clear example for customized directives thanks a lot for providing this

    Reply
  5. Phani on

    Nice Article with clear explanation.

    Reply
  6. rahul on

    Thank you.
    good explanation..

    Reply
  7. vignesh p on

    Wonderful blog.. Thanks for sharing informative blog.. its very useful to me..

    Reply
  8. Karthi on

    Excellent Article

    Reply
  9. Muthulakshmi on

    {{movie}} is printed undefined, couldn’t able to pass variables in attributes, please help. Thanks.

    Reply
  10. Sourav Ghadai on

    Actually I thing this is not sufficient to create custom directive. But your explanation and your application is good . If possible please add remaining parts to create custom directive.

    Reply
  11. san on

    should use transclude: true, instead of transclude: ‘true’,. true is a boolean and need not to use quotes.

    Reply
  12. Pruthviraj on

    Nice article. Thanks a lot for your great work.

    Reply
  13. Ashish on

    @Muthulakshmi, As she used “restrict: ‘E'”, so it only be used as a Element not Attribute, for that you can define “restrict: ‘EA’.

    Reply
  14. subramanyam on

    Nice explanation.

    Reply
  15. Subramanyam on

    Thanks Aakansha to this tutorial. This tutorial covered very basic understanding of the custom directive.

    Reply
  16. SiDDU on

    Good explanation.

    Reply
  17. praveen on

    Good Explanation on directives

    Reply
  18. Hemanth Chennavaram on

    Good explanation. for beginner’s …

    Reply
  19. Parmeshwar on

    Good Explanation with example.

    Reply
  20. ankita on

    i am getting attr.title as undefined

    Reply
  21. shilpa on

    Thank you so much.. this is the easiest article found on Internet regarding Custom directives… And well explained… Keep it up

    Reply
  22. Jayashree on

    Good explanation,Easily understood

    Reply
  23. Vaibhav Jain on

    Hi Aakansha,

    Could you please explain more about the ‘link’ field of the object. I mean, more about link’s functions parameters in wich variable the value comes in because I have seen the example where we have more parameters such as ‘ctrl’ and we operate on that. Could you please help on this.

    Thanks

    Reply
  24. Pankaj Bhagat on

    Thanks Aakansha to this tutorial. This tutorial covered very basic understanding of the custom directive.

    Reply
  25. Shiv on

    Understandable article… very nice

    Reply
  26. Anuj Kumar on

    very clear concise and working explanation with sample code. thanks

    Reply
  27. Aman Gehlot on

    Nice post, thanks.

    Reply
  28. Pradeep on

    Pretty good job. It helped a lot to quickly get so much of clarity in shortest possible time! God Bless you.

    Reply
Leave a Reply

Related Posts

Interviews from Industry Summit 2017: the Product Conference On this special double episode of The Innovation Engine, the 3Pillar team interviews many of the speakers who took the stage at Industry Summit 2017. ...
Designing the Future & the Future of Work – The I... Martin Wezowski, Chief Designer and Futurist at SAP, shares his thoughts on designing the future and the future of work on this episode of The Innovat...
The 4 Characteristics of a Healthy Digital Product Team Several weeks ago, I found myself engaged in two separate, yet eerily similar, conversations with CEOs struggling to gain the confidence they needed t...
Recapping Fortune Brainstorm Tech – The Innovation Eng... On this episode of The Innovation Engine, David DeWolf and Jonathan Rivers join us to share an overview of all the news that was fit to print at this ...
4 Reasons Everyone is Wrong About Blockchain: Your Guide to ... You know a technology has officially jumped the shark when iced tea companies decide they want in on the action. In case you missed that one, Long Isl...