Reputation: 9247
This is first time that I am writing directive. I am trying to write directive to hide my div.This is my html:
<div id="loggedIn" close-logged-in class="fade-show-hide" ng-show="loggedInOpened" ng-cloak>
@Html.Partial("~/Views/Shared/_LoggedInPartial.cshtml")
</div>
I find element but when I click anywhere on page I dont get anything.Can someone help me how to write directive so that when shown user click anywhere on page, it will hide that div.Any suggestion?
'use strict';
angular.module("accountModule").directive('closeLoggedIn', function () {
return {
scope: {},
restrict: 'A',
link: function (scope, element, attrs) {
var loggedIn = angular.element(document.getElementById("loggedIn"));
console.log(loggedIn);
var isClosed = false;
loggedIn.on('click', function (e) {
console.log("LOGGED IN ON CLICK ", loggedIn);
});
}
}
I dont get this message "LOGGED IN ON CLICK"
Upvotes: 1
Views: 4225
Reputation: 4862
You don't need getElementById("loggedIn")
The <div>
is already there for you as the element
argument in the link function. There should rarely be any need to reference elements by their ID's in Angular.
Is this what you are trying to achieve?
html
<div hide-when-click-anywhere default-display='block'>Click anywhere to hide me</div>
js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $window) {
$scope.isHidden = false;
});
app
.directive('hideWhenClickAnywhere', function ($window) {
return {
// bind a local scope (i.e. on link function scope) property
// to the value of default-display attribute in our target <div>.
scope: {
defaultDisplay: '@'
},
restrict: 'A',
link: function (scope, element, attrs) {
var el = element[0];
// set default css display value. Use 'block' if
// the default-display attribute is undefined
el.style.display = scope.defaultDisplay || 'block';
angular.element($window).bind('click', function(){
// Toggle display value.
// If you just want to hide the element and
// that's it then remove this if block
if(el.style.display === 'none'){
el.style.display = scope.defaultDisplay || 'block';
return;
}
el.style.display = 'none';
});
}
};
});
Update
Ok after reading you comments I think this might be more what you're trying to achieve;
Take note of this line in the <button>
element defined in template.html:
ng-click="contentHidden = !contentHidden; $event.stopPropagation();"
$event.stopPropagation()
stops the event from bubbling up and triggering the 'click' listener we have defined on $window
in our directive.
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $window) {
$scope.hideOnStart = true;
});
app
.directive('panel', function ($window) {
return {
scope: {
// this creates a new 'isolate' scope
// '=' sets two-way binding between the directive
// scope and the parent scope
// read more here https://docs.angularjs.org/api/ng/service/$compile
hideOnStart: '=',
panelTitle: '@'
},
transclude: true,
templateUrl: 'template.html',
restrict: 'E',
link: function (scope, element, attrs) {
console.log(scope.panelTitle)
// div content is hidden on start
scope.contentHidden = scope.hideOnStart || false;
angular.element($window).bind('click', function(e){
// check if the content is already hidden
// if true then ignore
// if false hide the content
if(!scope.contentHidden){
scope.contentHidden = true;
// we have to manually update the scope
// because Angular does not know about this event
scope.$digest();
}
});
}
};
});
template.html
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">{{panelTitle}}
<button
type="button"
class="close"
ng-click="contentHidden = !contentHidden; $event.stopPropagation();"
aria-label="Close"
>
<span ng-hide="contentHidden">close</span>
<span ng-hide="!contentHidden">open</span>
</button>
</div>
</div>
<div class="panel-body" ng-hide="contentHidden" ng-transclude></div>
</div>
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script data-require="[email protected]" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<h1>Demo</h1>
<div class="row">
<div class="col-sm-6">
<panel panel-title="Title" hide-on-start="hideOnStart">
<h4>Content...</h4>
<p>foo bar baz</p>
</panel>
</div>
</div>
</div>
</body>
</html>
Upvotes: 3