Here is the solution you requested:
- I implemented a
custom directive
- This directive, named
click-outside
, listens for clicks on elements where it is applied.
- If the click occurs outside of the targeted
element
, it will hide the specified div
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.showDropdown = false;
$scope.hide = function(){
$scope.showDropdown = false;
}
$scope.helloClick = function(){
$scope.showDropdown = !$scope.showDropdown;
}
}
});
app.directive('clickOutside', function ($document) {
return {
restrict: 'A',
scope: {
clickOutside: '&'
},
link: function (scope, el, attr) {
$document.on('click', function (e) {
if (el !== e.target && !el[0].contains(e.target)) {
scope.$apply(function () {
scope.$eval(scope.clickOutside);
});
}
});
}
}
});
.xyz{
border:1px solid red;
width:200px;
height:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div click-outside="hide()">
<div class="hello" ng-click ="helloClick()">hello</div>
<div class="xyz" ng-if="showDropdown">xyz</div>
</div>
</div>
Please test the above code snippet
Take a look at the live DEMO
Note about the directive:
el !== e.target && !el[0].contains(e.target)
Here, 'e' represents the clicked element and 'el' is the element to which the directive is attached. This condition checks if the clicked element is not the same as the target element with the directive. If not, it will hide the specified div
scope.$eval(scope.clickOutside);
This line evaluates the attribute and triggers the function provided in click-outside="hide()"