custom directive

angularJS provides us the facility to create our own directives which is called custom directives. We have to register this directive in a module. We create directives in camel case. However, when we apply in the html code we use hyphen (-). Custom directives are the function, which return JSON Objects.


Example of custom directive

In the following example, I am creating a directive just to display hello world.

		
<head>
  <script src="angular.js"></script>
    <script>
    var x=angular.module('m1',[]);
        x.directive('ngHello',function(){
           return{
               template:"hello world"
           } 
        });
    </script>
</head>
<body data-ng-app='m1'>
    <div>
        <ng-hello></ng-hello>
    </div>
</body>
		
		

As you can see that, I have used template property in custom directives. Template is used to display on html template. I have used <ng-hello> as an element like tag. We can also use it like attribute with another html tag in the following manner:-

		
		<div ng-hello> 
    </div>
		
		

Now if you want to restrict your tag to element only then we can use following property in custom directives:-

		
		var x=angular.module('m1',[]);
        x.directive('ngHello',function(){
           return{
               template:"hello world",
               restrict:'E'
           } 
        });
		
		

If we need to restrict it attribute only then we will use ā€˜Aā€™ instead of ā€˜Eā€™.

Custom Directives with Shared Scope

By default, custom directives use shared scope, which means custom directives are able to access the controller data in which it is called.

example of shared scope

In the following example, I have created a custom directive, which shows the records of employee. I called this directives inside the controller in which employee data is defined.

		
		<!DOCTYPE html>
<html>
<head>
   <script src="angular.js"></script>
	<script>
	var x=angular.module('m1',[]);
		x.directive('showEmp',function(){
			return{
				template:'<table border="1"><tr><th>ID</th><th>Name</th>'+
            '<th>Salary</th><th>gender</th></tr><tr ng-repeat="emp in employee">'+
            '<td>{{emp.id }}</td><td>{{emp.name}}</td><td>{{emp.salary}}</td>'+
                 '<td>{{emp.gender}}</td></tr></table>'
			}
		});
		x.controller("con1",function($scope){
            $scope.employee=[
                {id:101,name:'isha',salary:15000,gender:'f'},
                {id:102,name:'neha',salary:13000,gender:'f'},
                {id:103,name:'pooja',salary:25000,gender:'f'},
                {id:104,name:'rahul',salary:5000,gender:'m'},
                {id:105,name:'sakshi',salary:45000,gender:'f'}
         ];
        });
	</script>
</head>
<body ng-app="m1">
<div ng-controller="con1"><show-emp></show-emp></div>
</body>
</html>
		
		

Now execute this code and it will show the following output

		
		custom directive
		Figure 1
		
		

Custom Directive with Isolated Scope

If we need to isolate our custom directive from controller and allow it to use only those data, which pass to it, then we use isolated scope.

We can use isolated scope in following two manner:-

  • @ (Which means string)
  • = (Which means object)

Isolated scope with @ (string)

If we need to take string as an input parameter as a string then we will use @ in the following manner:-

		
		x.directive('showEmp',function(){
			return{
				scope:{ name: '@'},
				template:'User name is {{name}}'
			}
		});

		

We will pass this string to directive in the following manner:-

		
		<show-emp name='isha'></show-emp>
		
		

Now execute this code and you will get following result

		
		custom directive with isolated string
		Figure 2
		
		

Isolated Scope with = (object)

If we need to pass the complete object to custom directive then we will use = in following manner:-

		
		<!DOCTYPE html>
<html>
<head>
   <script src="angular.js"></script>
	<script>
	var x=angular.module('m1',[]);
		x.directive('showEmp',function(){
			return{
				scope:{ employee: '='},
				template:'<table border="1"><tr><th>ID</th><th>Name</th>'+
            '<th>Salary</th><th>gender</th></tr><tr ng-repeat="emp in employee">'+
            '<td>{{emp.id }}</td><td>{{emp.name}}</td><td>{{emp.salary}}</td>'+
                 '<td>{{emp.gender}}</td></tr></table>'
			}
		});
		x.controller("con1",function($scope){
            $scope.employee=[
                {id:101,name:'isha',salary:15000,gender:'f'},
                {id:102,name:'neha',salary:13000,gender:'f'},
                {id:103,name:'pooja',salary:25000,gender:'f'},
                {id:104,name:'rahul',salary:5000,gender:'m'},
                {id:105,name:'sakshi',salary:45000,gender:'f'}  ];
        });
	</script>
</head>
<body ng-app="m1">
<div ng-controller="con1"><show-emp employee='employee'></show-emp></div>
</body>
</html>

		
		

When you will execute this page, it will show the completed table.

Note: - isolated scope with = (object) will work with two way binding.


Isolated custom directives with two way binding

In the above example, I have mentioned that with the help of object we can implement two way binding.

I have added a method in controller, which will increment the salary in the following manner:-

		
		$scope.salaryincrement=function(){
				for(var p in $scope.employee){
					$scope.employee[p].salary++;
				}
			}

		
		

Now I have added a button inside custom controller and bind this button using ng-click with a method. I will take this method name as an input value from the user who will use this custom controller for that I have to use & inside custom controller in the following manner :-

		
		x.directive('showEmp',function(){
			return{
				scope:{ employee: '=', inc:'&' },
				template:'<table border="1"><tr><th>ID</th><th>Name</th>'+
            '<th>Salary</th><th>gender</th></tr><tr ng-repeat="emp in employee">'+
            '<td>{{emp.id }}</td><td>{{emp.name}}</td><td>{{emp.salary}}</td>'+
                 '<td>{{emp.gender}}</td></tr></table>'+
	'<div><input type="submit" value="IncrementSal" ng-click=inc()></div>'
			}
		});
		
		

Now call this custom directive and pass the function name in the following manner:-

		
		<show-emp employee='employee' inc='salaryincrement()'></show-emp></div>
		
		

Now execute this code and you will get following output:-

		
		custom directive with two way binding
		Figure 3
		
		

Now click on button and you will find the increment value

		
		custom directive with object 
		Figure 4