Click only on child element - angularjs

I made a directive that I insert it in the div parent to restrict some things (such restrictions that I do not put in the example), but I also want to listen when you click on the second element only in the second element, how can I listen when you click?
note: I just want to insert in div father the directive
angular
.module('MyApp', [])
.directive(
'clickMe',
function() {
return {
link: function(scope, element) {
element.on('click', function() {
console.log('click');
});
},
};
}
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div click-me>
clickeame
<div id="one">
click 2
</div>
</div>
</div>

Change your directive as follows,
angular
.module('MyApp', [])
.directive(
'clickMe',
function() {
return {
link: function(scope, element) {
element.on('click', function(event) {
if (event.target.id == "one") {
console.log('click');
}
});
},
};
}
);
DEMO
angular
.module('DemoApp', [])
.directive(
'clickMe',
function() {
return {
link: function(scope, element) {
element.on('click', function(event) {
if (event.target.id == "one") {
console.log('click');
}
});
},
};
}
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="DemoApp">
<div click-me>
clickeame
<div id="one">
click 2
</div>
</div>
</div>

This would be an alternative way to add the event listener to only the child
https://codepen.io/anon/pen/eGzBQm
angular
.module('MyApp', [])
.directive(
'clickMe',
function() {
return {
link: function(scope, element) {
element.find("div").on('click', function(event) {
console.log('click');
});
},
};
}
);

Related

How to bind multiple custom events in angularjs?

I need to bind custom events in angularjs(1.x) and I tried with the following code,
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://www.polymer-project.org/components/polymer/polymer.html" rel="import">
<link href="https://www.polymer-project.org/components/paper-button/paper-button.html" rel="import">
<div ng-app="demo-app">
<div ng-controller="DemoController">
<template bind-angular-scope is="auto-binding">
<paper-button raised on-tap="{{clickMe}}" on-mouseover="{{mouseOver}}">click me</paper-button>
</template>
<pre><code>{[{text}]}</code></pre>
</div>
</div>
Script
<script>
angular.module('demo-app', [])
.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
})
.directive('bindAngularScope', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
for (k in scope) {
if (!element[0][k]) {
element[0][k] = scope[k];
}
}
}
}
})
.controller('DemoController', function ($scope) {
$scope.text = '';
$scope.clickMe = function () {
$scope.text += '\nyou clicked me!!';
$scope.$apply();
};
$scope.mouseOver = function () {
$scope.text += '\nyou hovered me!!';
$scope.$apply();
}
});
</script>
This is not working.Could you point out me the issue or Is there is any solution for binding custom events(multiple) ? Do we need to create a custom directive for each of them ?
Note:
The above code is referred from the following url,
How to bind custom events in AngularJS?
Thanks in advance!
angular.module('demo-app', [])
.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
})
.directive('bindAngularScope', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
for (k in scope) {
if (!element[0][k]) {
element[0][k] = scope[k];
}
}
elem.bind('click', function() {
/* Place your click logic here * /
});
}
}
})

Make directive function accessible in parent scope without events

I have a directive with an isolated scope and want to call its function to update data from the parent controller without using events.
var myApp = angular.module('MyApp',[]);
myApp.directive('myDirective', function() {
return {
scope: {},
link: function(scope) {
scope.update = function() {
alert('Directive updated!');
}
}
}
});
function MyCtrl($scope) {
$scope.updateDirective = function() {
// make me call update() function in directive
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyCtrl">
<button ng-click="updateDirective()">Update!</button>
<span my-directive></span>
</div>
You could apply this solution.
In this way you are passing a variable in two way binding:
my-directive="myFunction" in the html
and myFunction: '=myDirective' in the directive)
Then assign the function in the directive:
scope.myFunction = function () {
alert('Directive updated!');
}
In this way you can use a function defined in a directive.
var myApp = angular.module('MyApp', []);
myApp.directive('myDirective', function () {
return {
scope: {
myFunction: '=myDirective'
},
link: function (scope) {
scope.myFunction = function () {
alert('Directive updated!');
}
}
}
});
function MyCtrl($scope) {
$scope.myFunction = {};
$scope.updateDirective = function () {
console.log( $scope.myFunction );
$scope.myFunction();
// make me call update() function in directive
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyCtrl">
<button ng-click="updateDirective()">Update!</button> <span my-directive="myFunction"></span>
</div>
You could tackle this issue by introducing a new directive that is required by your isolated directive. Conveniently, you can assign the controller to this new directive.
Once required you then 'register' your isolated directive to the 'parent' directive as the target for your function. In the code snippet below I only provided a way to add 1 directive, but you could easily extend this to be an array of child directives. A good of example of such a setup are tabs, where each tab is a child directive of a common tabs directive.
angular.module("MyApp", []);
angular.module('MyApp').directive("myParentDirective", function(){
return {
controller: function ($scope) {
var childUpdate;
this.registerChild = function(_childUpdate_){
childUpdate = _childUpdate_;
};
$scope.updateDirective = function() {
childUpdate();
};
}
};
});
angular.module('MyApp').directive('myDirective', function() {
return {
require: '^myParentDirective',
scope: {},
link: function(scope, element, attrs, myParentController) {
myParentController.registerChild(update);
function update() {
alert('Directive updated!');
}
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div my-parent-directive>
<button ng-click="updateDirective()">Update!</button>
<span my-directive></span>
</div>
</div>

eventlistener with element.on on <video> in a angular directive doesn't trigger

If I use something like this in a directives link function:
var vdo = element.find('video')[0];
vdo.on('loadstart', function () {
console.log('onloadstart');
});
The code isn't executed. Instead I have to use:
vdo.onloadstart = function() {
console.log('onloadstart');
};
or
vdo.addEventListener('loadstart', function () {
console.log('onloadstart');
});
Can someone explain me why? And is it a problem to use addEventListener at all?
The angular way would be a custom directive:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.src = 'w3schools.com/html/mov_bbb.mp4';
$scope.myFunc = function() {
alert('loadstart!');
};
}
myApp.directive('onLoad', function() {
return {
restrict: 'A',
scope: {
func: '&onLoad'
},
link: function(scope, element) {
element.on('loadstart', function() {
scope.func();
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<video controls on-load="myFunc()">
<source ng-src="{{src}}">
</video>
</div>

angularjs bind data and display from hardcode and or service

Hello i have my directive:
myApp.directive('hoverDirective',function($document){
return function(scope, element, attr){
scope:{value:'foo'};
element('mouseover',function(event){
console.log(event);
});
}
});
And I have it working:
<div hover-directive>
{{value}}
</div>
But now I want to hardcode data in directive, and get it by factory.
I read about scope:{value:'foo'}. But i have error while i was putting it inside of return function.
Can anyone help ?
UPDATE: I try putting code inside of return function no results.
Please see here : http://jsfiddle.net/qeCDL/
HTML:
<div ng-app="app">
<div ng-controller="firstCtrl">
<div hover-directive></div>
</div>
</div>
JS:
var app = angular.module('app', []);
app.directive('hoverDirective', function () {
return {
scope: {},
restrict: 'AE',
controller: function () {
},
template: '<h3>{{value}}</h3>',
link: function (scope, element, attrs) {
scope.value = "hove me";
element.on('mouseover', function (event) {
console.log(scope.value);
});
}
};
});
app.controller('firstCtrl', function ($scope) {
});

Weird thing going on with nested directives AngularJS

I am having a problem with nested directives, in particular within the hide-element directive.
Firstly, there is an edit-mode directive that does not seem to work with ngAnimate. It would still hit hit addClass fade on button, but would not have ng-animate binded.
I tried moving the hide-element to a sibling element at divColumn and the edit-element directive works and does the animation on both buttons and divColumn.
It just doesn't work when they are nested. Why is that?
(I'm new to AngularJS, kindly enlighten me)
HTML
<!-- ngview has UIController everything here is nested within ngview -->
<h3>Data Page</h3>
<div class="divContainer" ng-mouseenter="fadeToggle()" ng-mouseleave="fadeToggle()">
<div style="overflow:hidden">
<div class="divHeader">Data Name</div>
<div class="divHeader">Parent Data</div>
<div class="divHeaderHidden" hide-element="isHidden">Edit</div>
</div>
<div ng-controller="myController">
<div ng-repeat="data in datas">
<div class="divRow" ng-mouseenter="fadeToggle();" ng-mouseleave="fadeToggle();">
<div class="divColumn">
{{data.name}}
</div>
<div class="divColumn">
{{data.parentData.name}}
</div>
<div class="divColumnHidden" hide-element="isHidden">
<button class="editColumnBtn" ng-click="editToggle()" edit-mode="isEdit">Edit</button>
<button class="removeColumnBtn" edit-mode="isEdit">Remove</button>
</div>
</div>
</div>
</div>
Angular
app.factory('Data', function($http) {
var dataService = {
getDepartment: function() {
var promise = $http.get('http://localhost/orgchart/app/json/data').then(function(response) {
return response.data;
});
return promise;
}
};
return dataService;
});
app.controller('UIController', ['$scope', function fadeController($scope) {
$scope.fadeToggle = function () {
this.isHidden = !this.isHidden;
};
}]);
app.controller('myController', ['$scope', 'Data', function myController($scope, Data) {
Data.getData().then(function(data) {
$scope.data = data;
});
$scope.editToggle = function() {
this.isEdit = !this.isEdit;
};
}]);
app.directive('editMode', ['$animate', function ($animate) {
return function(scope, element, attrs) {
scope.isEdit = false;
scope.$watch(attrs.editMode, function (newVal) {
if(newVal) {
$animate.addClass(element, 'fade');
}
else {
$animate.removeClass(element, 'fade');
}
});
};
}]);
app.directive('hideElement', ['$animate', function ($animate) {
return function(scope, element, attrs) {
scope.isHidden = true;
scope.$watch(attrs.hideElement, function (newVal) {
if(newVal) {
$animate.addClass(element, 'fade');
} else {
$animate.removeClass(element, 'fade');
}
});
};
}]);
app.animation(".fade", function() {
return {
addClass: function(element, className) {
TweenMax.to(element, 0.3, {opacity: 0});
},
removeClass: function(element, className) {
TweenMax.to(element, 0.3, {opacity: 1});
}
};
});

Resources