AngularJS Custom Directives

AngularJS Custom Directives

Directives are core part of AngularJS framework. We can create our own custom directives in AngularJS as per business needs. There are other methods for creating and using AngularJS directives except built-in. Methods of using directives in AngularJS

  1. Page Directives
  2. Custom Directives

Page Directives

These are very simple and used by ngInclude directive to insert static HTML templates. The most common purpose is to hold the uniform rule across the whole web application by creating and re-using wherever required. No controllers are required. Note: apostrophe ( ' ) must required in ng-include, otherwise it will not work.

<!-- apostrophe must required -->
<div ng-include="'product-title.html'"></div>

Example

  • HTML
  • HTML
  • Result
<!-- product-title.html -->
<h3>{{product.name}}<em class="float-right">{{product.price | currency}}</em></h3>
<!--
index.html
using ng-include and ng-repeat directive
-->
<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <!-- bootsrap CDN -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

  <!-- AngularJS CDN -->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
  <script>
    angular.module('myApp', [])
    .controller('productController', ['$scope', 'function($scope) {
      $scope.products = [
                          {name: 'Apple', price: 14.50},
                          {name: 'Orange', price: 10.25},
                          {name: 'Banana', price: 8.10}
                        ];
    }]);
  </script>
</head>
<body>
  <div ng-controller="productController" style="background-color: rgb(252, 249, 192); padding: 15px; width: 50%;">
    <div ng-repeat="product in products">
      <!-- page directive -->
      <div ng-include="'product-title.html'"></div>
    </div>
  </div>
</body>
</html>

{{product.name}}{{product.price | currency}}


Custom Directives

Above result can be achieved by directive method with more strict rules. We can create Element directive or Attribute directive by using restrict option. restrict option can be set to
  • 'A' - attribute name
  • 'E' - element name
  • 'C' - class name
  • 'M' - comment
restrict option can be combined like 'AEC' syntax
.directive("productTitle", function() {
  return {
    restrict: 'E',      // E for element
    templateUrl: 'product-title.html';
  }
});
inline template
.directive("productTitle", function() {
  return {
    restrict: 'E',      // E for element
    template: '<h3>{{product.name}}<em class="pull-right">{{product.price | currency}}</em></h3>'
  }
});
Element directive
<product-title></product-title>
Attribute directive
<h3 product-title></h3>

Best Practice: Use Element directive for UI Widget and Attribute directive for small mix-in like tool-tip feature.

Example

/*
app.js
custom directive
*/
'use strict';

// creating new module
angular.module('myApp', [])

.controller('productController', ['$scope', function($scope) {
  // JSON data in scope object
  $scope.products = [
                      {name: 'Apple', price: 14.50},
                      {name: 'Orange', price: 10.25},
                      {name: 'Banana', price: 8.10}
                    ];
}])

.directive("productTitle", function() {
  return {
    restrict: 'E',      // E for element
    template: '<h3>{{product.name}}<em class="float-right">{{product.price | currency}}</em></h3>'
  }
});
<!DOCTYPE html>
<!--
index.html
-->
<html ng-app="myApp">
<head>
  <!-- bootsrap CDN -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">

  <!-- AngularJS CDN -->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
  <script src="app.js"></script>
</head>
<body>
  <div ng-controller="productController">
    <div ng-repeat="product in products">
      <!-- custom element directive -->
      <product-title></product-title>
    </div>
  </div>
</body>
</html>

{{product.name}}{{product.price | currency}}