How to Write a Custom Directive in AngularJS

How to Write a Custom Directive in AngularJS
COMMENTS ()
Tweet

Hey guys,

In my previous post, we’ve given the Introduction of Angular JS along with its feature details. In this post, I’ll show you how to create a Custom Directive in AngularJS and how that can be used.

Tutorial

You can also download a zipped version of the source code used from this link 

Live Demo

A video demo of this tutorial is available here Live Demo

What are Directives?

Directives are basically markers on a DOM element (such as an attribute, element name, comment or CSS class) that respond to AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element (for example via Event Listeners), or to transform the DOM element and its children.
Although there are a number of directives available in the AngularJS library (for instance ng-repeat, ng-click, ng-submit etc.) which can help you implement two way binding behaviors and other more complex functions, there some times where you may need to design your own custom directive in order to implement a particular custom functionality.

For Example:

While using ng-repeat directive, suppose you have a complex template for each object and the code becomes too convoluted if you use the template in the same html file. In this case, you can use a custom directive (as shown below) and name it whatever you like.

Controller.js
angular.module('Flapper', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.items = [{
    name: ‘Ruby Gem’,
    price: '$46’
  }, {
    name: ‘Flapper Special’,
    price: '$100’	
  }];
}])
.directive('myItems', function() {
  return {
    restrict: “E”,
    templateUrl: 'listing.html',
    scope: {listitem: ‘=item’}
  };
});
Index.html
<div ng-repeat=”item in items”>
  <items-info></items-info>
</div>

 

In the above code, we are simply using a template “listing.html” file and returning HTML in it. As you can see from this snippet, it’s pretty easy to write a custom directive. If you are wondering about the properties and options used in the code above, they you need not worry.

When you define a directive, you have to return a behavior with some options identifying the nature of the directive. Of course some of these have default values but you can set to these to other values as well. For example:

 

      The

Restrict

    property used in the code snippet above, can be set to

  • “A” – If we want our directive as an attribute in the element
  • “E” – If we want our directive as an element OR
  • “C” – If we want our directive to only match the class name
  • The other option you can use is Scope, which is very helpful if you want to map the outer scope (usually the Controller’s scope) to the directive’s inner scope or Isolated Scope. What this does is that it simply takes each instance of the array of objects and allows us access it in the new template. If you take a look at the above code snippet, this will become clearer to you.
  • Lastly, you can also define a directive Controller in the code above as an option, if you want a controller’s behavior in the template.

Some Other Interesting Examples of Custom Directives

When you’re working with AngularJS, it’s not a very good approach to use jQuery to handle your custom logic, even though jQuery events and plugins can be used in a directive and can be applied on DOM elements. For example the jQuery Date Picker plug-in. Using this plug-in with AngularJS really restricts versatility with which this plug-in can be used.

So I’ve created a custom directive which can be applied on any element, which will act as a date picker. The most interesting thing here is that the date picker (or any other plugin which requires initialization) is only initialized once within your DOM and is directly mapped to the elements (as shown below).

Directives.js
App.directive('datePicker', function() {
    return {
        restrict: 'A',
        require : 'ngModel',
        link: function(scope, element, attrs) {
            element.css("cursor", "pointer");
            element.css("background-color", "white");
            element.datepicker({
                autoSize: true,
                yearRange: attrs.range,
                dateFormat: attrs.format,
                changeMonth: true,
                changeYear: true,
                maxDate: attrs.maxdate,
                minDate: attrs.mindate,
                onSelect: function(dateText, inst) {
                    ngModelCtrl.$setViewValue(dateText);
                    scope.$apply();
                }
            })
        }
    };
});
index.js
<input 
 readonly="readonly" 
 size="23" 
 type="text" 
 date-picker 
 range="1910:2030" 
 mindate="-34y" 
 format="yy-mm-dd" 
 maxdate="-14y" 
 id="dateedit" 
 placeholder="Birthday" 
 data-ng-model="personalInfo.birthday" 
 class="form-control">

 

As you can see in the code snippet above, in the directives.js file, I have created a datepicker directive within the App module. And in the index.html I have used that directive on the input field. I’ve also used some additional attributes in the input field like range mindate format etc. as arguments, to pass to the datepicker directive as custom values. Suppose you have to use a custom range and format in the jQuery datepicker. You can access that by defining custom attributes to the input and use the attrs parameter in the link function, to deal with those custom attributes from the input field.

There are other parameters as well such as scope and element which you can use. The Scope of a directive helps you to redefine or modify the scope of a controller you are using, while the Element parameter returns the current element on which you have applied the directive.

Directives.js
App.directive('datePicker', function() {
    return {
        restrict: 'A',
        require : 'ngModel',
        link: function(scope, element, attrs) {
            element.css("cursor", "pointer");
            element.css("background-color", "white");
            element.datepicker({
                autoSize: true,
                yearRange: attrs.range,
                dateFormat: attrs.format,
                changeMonth: true,
                changeYear: true,
                maxDate: attrs.maxdate,
                minDate: attrs.mindate,
                onSelect: function(dateText, inst) {
                    ngModelCtrl.$setViewValue(dateText);
                    scope.$apply();
                }
            })
        }
    };
});

 

Conclusion

In this tutorial I showed you how to create your very own Custom Directive in AngularJS, instead of using one of the built in ones. You can also use this same approach for other directives. For example, you can create a custom Safari Handler directive, when elements are not binding or stop working on the Safari browser. In that case, you can handle the situation with your own custom logic in a directive. You can also create a directive for listing items on a page.

In my next post,we will learn how to use Angular JS Filters

CALL

USA408 365 4638

VISIT

1301 Shoreway Road, Suite 160,

Belmont, CA 94002

Contact us

Whether you are a large enterprise looking to augment your teams with experts resources or an SME looking to scale your business or a startup looking to build something.
We are your digital growth partner.

Tel: +1 408 365 4638
Support: +1 (408) 512 1812