This is angularjs custom directive tutorial. Lets see, how to make custom directives in angularjs? We will be making use of our existing guitar angularjs app which we have been working in Tutorial 14: Form Validation in AngularJS. You can download previous tutorial app here. Ok lets start, with angularjs directive. As we know that:

Angularjs Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s html compiler ( $compile ) to attach a specified behavior to that DOM element or even transform the DOM element and its children. For example, The ng-app attribute is a directive, so is ng-controller and all of the ng-, ng:, ng_, x-ng-bind, data-ng-bind prefixed attributes.

So custom directives in angularJS is your own directive with their own core functions that runs when the DOM is compiled by the compiler. Thats may be difficult. Suppose, if we want to reuse specific lines of code in different pages of our application without code duplication then we simply put that specific piece of code in a separate file and call that code using a custom directive instead of writing it over and over again. This way code is better to understand. There are four types of custom directives:

Element directives

Attribute directives

CSS class directives

Comment directives

Before implementing it in our existing angular app lets see how custom directives looks like:

Element directives

In the html file write following element tag. This tag will hold code snippet. When we want to use specific code we simply write such tags to include that code.

<guitar-reviews> ... </guitar-reviews>

Then in the JS file, write following lines to make above angularJS custom directive work.

app.directive('guitarReviews', function() { return { restrict : 'E', // used E because of element templateUrl : 'custom-directives/reviews.html' }; });

Code Explanation:

Like app.controller we defined app.directive then defined guitarReview which is the name of element tag that is being used in html but have you noticed that guitar-review is different from guitarReviews? This is because guitar-reviews’s hypen is converted into camel case so it becomes guitarReviews in js file. Next is an anonymous function which is returning something. restrict: ‘E’ says that we are defining a custom Element directive and templateUrl is pointing to code snippet file that has to be included.

Attribute directives

In the html file write following attribute inside html tag. This tag will hold code snippet. When we want to use specific code we simply write such tags to include that code.

<div guitar-reviews> ... </div>

Then in the JS file, write following lines to make above angularJS custom directive work.

app.directive('guitarReviews', function() { return { restrict : 'A', // used A because of attribute templateUrl : 'custom-directives/reviews.html' }; });

Note: AngularJS recommends that you leave simple css and normal comments instead of custom directives for css and comments.

Lets implement custom directives in our angularJS app. You can download project files here. I want to put reviews section code in a separate file and then gonna assign an element to that code snippet and use it in details.html page.

First

In partials folder create a new folder named as cDirectives to hold custom directives. Then inside cDirectives create a new file named as reviews.html that will hold reviews of user. So your folder hierarchy must look like this:

Second

Goto details.html file and cut the review area and add <user-reviews></user-reviews> tag like this:



Third

Paste the code you cut from details.html page to reviews.html page like this:

<!-- Review Tab START, it has a new controller --> <div ng-show="panel.isSelected(3)" class="reviewContainer" ng-controller="ReviewController as reviewCtrl" > <!-- User Reviews on each guitar from data.json - simple iterating through guitars list --> <div class="longDescription uReview" ng-repeat="review in guitarVariable[whichGuitar].reviews"> <h3>Review Points: {{review.star}} </h3> <p> {{review.body}} ~{{review.name}} on <date>{{review.createdOn | date:'MM/yy'}} </p> </div><!-- End User Reviews --> <!-- This is showing new review preview--> <div ng-show="add === 1" class="longDescription uReview" > <h3>Review Points: {{reviewCtrl.review.star}} <span ng-click="add=0">X</span></h3> <p> {{reviewCtrl.review.body}} ~ {{reviewCtrl.review.name}} </p> </div> <!-- Add new Review to specific guitar - click this link to show review adding pannel --> <a href ng-click="add=1" class="addReviewLink">Add review</a> <!-- form validates here using form name and .$valid and on submission we are going to addReview function with guitarID --> <form class="reviewForm" name="reviewForm" ng-submit="reviewForm.$valid && reviewCtrl.addReview(guitarVariable.indexOf(guitarVariable[whichGuitar]))" novalidate ng-show="add===1" > <div> Review Points: <!-- ng-option here is setting options, cool? --> <select ng-model="reviewCtrl.review.star" ng-options="point for point in [5,4,3,2,1]" required > </select> Email: <input type="email" ng-model="reviewCtrl.review.name" required> <button type="submit">Submit</button> </div> <textarea placeholder="Enter your experience with this guitar..." ng-model="reviewCtrl.review.body"></textarea> </form><!-- END add new review --> </div><br /><!-- END Review Tab -->

Fourth

Now is the time to add behavior to user-reviews element tag. Lets do it in controllers.js file like this (Goto end and add following code):

GuitarControllers.directive('userReviews', function() { return { restrict : 'E', // used E because of element templateUrl : 'partials/cDirectives/reviews.html' }; });

Code Explanation:

Our <user-reviews> directive name here is userReviews in camel case and hyphen is gone. Next we are saying that restrict that directive to element E and when it is called load the file in templateURL.

We just made a custom element directive. Although, you see no change in application but now our code is well managed than before. Can you make custom element directives for description and specifications? Do it yourself.

Interesting part: you can add styles to user-reviews via css like the way you assign style to a div.

Download Project files

Hope you like it. Please share my work.