(function(module) {
'use strict';
module.controller("outClickCtrl", function($scope, $log) {
// Dropdown ---------------------------------------------------
$scope.showText = true;
$scope.options = [
{ value: 'Option 1' },
{ value: 'Option 2' },
{ value: 'Option 3' }
];
$scope.currentOption = $scope.options[0];
$scope.toggleEdit = function() {
$scope.showText = !$scope.showText;
};
$scope.selectOption = function(option) {
$scope.currentOption = option;
};
// Example text on div element
$scope.textExample1 = 'DEFAULT TEXT EXAMPLE 1';
$scope.textExample2 = 'DEFAULT TEXT EXAMPLE 2';
$scope.clickOnExample1 = function() {
$scope.textExample1 = 'CLICK ON EXAMPLE 1';
}
$scope.outClickChangeExampleText1Callback = function() {
$scope.textExample1 = 'OUTSIDE CLICK ON EXAMPLE 1';
}
$scope.changeExampleText1Init = function() {
$scope.textExample1 = 'OVERRIDE BY INIT ON EXAMPLE 1';
}
// Example 2
$scope.clickOnExample2 = function() {
$scope.textExample2 = 'CLICK ON EXAMPLE 2';
}
$scope.outClickChangeExampleText2Callback = function() {
$scope.textExample2 = 'OUTSIDE CLICK ON EXAMPLE 2';
}
// Dropdown events
$scope.status = {
isopen: false
};
$scope.toggled = function(open) {
$log.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.isopen = !$scope.status.isopen;
};
});
module.directive("outClick", function() {
return {
restrict: 'AE',
scope: {
outClickCallback: '&', // pass callback to excecute when click outside element
outClickInit: '&', // pass method to excecute when init the directive
outClickInitCount: '=' // pass to init count +1 for elements like dropdown (simulate one click)
},
link: function(scope, element) {
var inside = false;
var count = -1;
if (scope.outClickInitCount) {
count++;
}
if (scope.outClickInit) {
scope.outClickInit();
}
document.addEventListener('click', function() {
count = count > -1 ? count + 1 : count;
if (!inside && count > 1) {
count = -1;
scope.outClickCallback();
scope.$apply();
}
inside = false;
});
element[0].addEventListener('click', function() {
inside = true;
count = 0;
});
}
};
});
}(angular.module('outClick', ['ui.bootstrap'])));
<div ng-app="outClick" ng-controller="outClickCtrl">
<h3>Example with element DIV and content text</h3>
<h4>with init method</h4>
<div out-click out-click-callback="outClickChangeExampleText1Callback()" out-click-init="changeExampleText1Init()" ng-click="clickOnExample1()">Click on me for change the next text: "{{ textExample1 }}"</div>
<h4>without init method</h4>
<div out-click out-click-callback="outClickChangeExampleText2Callback()" ng-click="clickOnExample2()">Click on me for change the next text: "{{ textExample2 }}"</div>
<hr>
<h3>Example with Dropdown</h3>
<div ng-if="showText" ng-click="toggleEdit()">Click to edit with dropdown. Current option selected: <strong>"{{ currentOption.value }}"</strong></div>
<div ng-if="!showText" class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled"
out-click out-click-callback="toggleEdit()" out-click-init-count="true">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-click="selectOption(option)" ng-repeat="option in options"> {{option.value}} </li>
</ul>
</div>
</div>
External resources loaded into this fiddle: