Get DOM element attribute of parent container with AngularJS - javascript

I'am quite new to AngularJS and I try to achieve to following: on click on some outer element and also on click on it's child elements I want to get some attribute of the outer element.
In jQuery this seems to bubble up easily when i click the subelement. In Angular, the function I put on "ng-click" on the outer element gets called, but the attribute can't be fetched...
I put my example with Angular and jQuery here: http://www.allcontrasts.com/external/angular-jquery/index.html
The critial code is the following:
HTML:
<body ng-app="testApp" ng-controller="testController" >
<div class="angulardiv" ng-click="myAlert($event);" data-id="321">ANGULAR
<div class="sublement">
Subelement
</div>
</div>
<div class="jquerydiv" data-id="321">JQUERY
<div class="sublement">
Subelement
</div>
</div>
</body>
Angular-Code:
var app = angular.module('testApp', []);
app.controller('testController', function($scope) {
$scope.myAlert = function(event) {
var elem = angular.element(event.target);
var dataId = elem.attr('data-id');
alert(dataId);
}
});
jQuery:
$(document).ready(function() {
$('.jquerydiv').click(function() {
alert($(this).attr('data-id'));
})
});
How can I achieve with Angular what jQuery does in this case?

Ok, in this case the soultion was pretty easy, I could change my HTML to:
<div class="angulardiv" ng-click="myAlert(321);">ANGULAR
<div class="sublement">
Subelement
</div>
</div>
...just passing the needed ID directly as a parameter to the function.
And then changed the Angular Code to:
var app = angular.module('testApp', []);
app.controller('testController', function($scope) {
$scope.myAlert = function(obj) {
alert(obj);
}
});

Related

How to replace a child div on it's existing parent div using angularjs?

I have the following code.
html:
<div ng-controller="Test">
<div ng-click="first()" ng-hide="seconddiv">First
<div ng-click="second()" ng-show="seconddiv">Second</div>
</div>
</div>
js:
var app = angular.module('app',[]);
app.controller('Test',function($scope){
$scope.first = function(){
alert("first clicked");
}
$scope.second = function(){
alert("second clicked");
}
});
On executing the above code:
a). I should see only First by default(I can see one now: First) - it is fine now
b). then, if I click on First, then it should execute it's first() method, then First should be replaced with Second(on UI) - it's not coming
c). then, if I click on Second, then it should execute it's second() method only, (it should not execute any other methods like first() except second() method) - it's not coming
I request you to please help me regarding this that how can we do this? Thanks in advance!
Please note that Html <div> structure should not change, so it should be same.
Created Fiddle .
Go the Angular Way.
You will have just one function, toggle. Which will toggle the value of variable first from true to false and vice versa.
Depending on value of first you will show either div with content as First or that with content as Second.
You will also refactor your HTML a bit as follows
<div ng-controller="Test">
<div ng-if="first" ng-click="toggle()">First</div>
<div ng-if="!first"ng-click="toggle()">Second</div>
</div>
And in your JS you will do
var app = angular.module('app',[]);
app.controller('Test',function($scope){
$scope.first = true;
$scope.toggle = function(){
$scope.first = !$scope.first;
}
});
====
EDIT:
Alternatively, you don't even need the toggle function. Just use ng-click expression.
<div ng-controller="Test">
<div ng-if="first" ng-click="first=!first">First</div>
<div ng-if="!first"ng-click="first=!first">Second</div>
</div>
And in JS
app.controller('Test',function($scope){
$scope.first = true;
});

Understanding the working of ngClick and ngDblclick

I was trying to figure out how ngClick and ngDblclick work in angularjs. The problem is that even while clicking twice, instead of calling doubleclick function once. Angular calls click function twice and double click function once.
HTML:
<div ng-controller="MyCtrl">
<div class="button" ng-click="click()" ng-dblclick="dblclick()">
Click
</div>
<div class="button" ng-click="reset()">
Reset
</div>
<div>
clicked:{{clicked}}
</div>
<div>
double clicked : {{dblclicked}}
</div>
</div>
JS:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.clicked = 0;
$scope.dblclicked = 0;
$scope.click = function(){
$scope.clicked++;
};
$scope.dblclick = function(){
$scope.dblclicked++;
};
$scope.reset = function(){
$scope.clicked = 0;
$scope.dblclicked = 0;
};
}
JsFiddle here
But this is not the case in jQuery wherein $(someElement).click() and $(someElement).dblclick() work as expected, which seems to be the ideal way to do it.
I have a fair idea that this is happening because they are implemented as directive in angular. Wherein in jQuery it works by listeners.
I see that you can eliminate this by using $evalAsync, but what reckons me is why we need such an extra burden to achieve something which is very obvious.
Can someone tell me how to handle the scenario. Thanks in advance.

AngularJS: Changing variable for an ng-switch using dynamically generated DOM

This is a little difficult to explain since I can't extract the code that I'm having the most difficulty with. The best I can do is a simple fiddle of what I'm trying to accomplish: https://jsfiddle.net/yLkukw5p/
HTML:
<div ng-app = "myApp" ng-controller = "parentController" ng-switch = "properties.selectedMethod">
<div ng-controller = "childController" ng-switch-when = "id">
<a ng-click = "survey()">
Change div
</a>
</div>
<div ng-switch-when = "date">
div changed
</div>
</div>
JS:
var app = angular.module('myApp', []);
app.factory('vars', function() {
var properties = {};
properties.selectedMethod = 'id';
function setselectedMethod(string){
properties.selectedMethod = string;
}
return {
properties : properties,
setselectedMethod : setselectedMethod
};
});
app.controller('parentController', function($scope, vars) {
$scope.properties = vars.properties;
$scope.setSearchMethod = function(method){
vars.setselectedMethod(method);
}
});
app.controller('childController', function($scope, $rootScope, $http, vars) {
$scope.properties = vars.properties;
$scope.survey = function() {
vars.setselectedMethod("date");
}
});
Basically, I want to be able to change the variable value in a factory shared between child and parent controllers. The only hiccup I'm running into is that in my case, the child div is dynamically generated, and that seems to be the only thing different between the fiddle and my code. I have some JavaScript that adds this DOM:
<div onclick = angular.element('#anotherdiv').scope().setSearchMethod('id');> More Info </div>
where anotherdiv is a div within the childController. When I click this div, I know by debugging that it runs the code in the vars factory, but it doesn't update other values? I'm using the "dot" trick so I would think the variables are references and not "shadowing" as some other posts suggested. Any thoughts?
EDIT: Updated the fiddle to be more accurate: https://jsfiddle.net/yLkukw5p/1/
It looks like the onclick function using angular.element is the one causing trouble, but I don't know how to work around it.

dynamically add another component

I have a componentA (like a container) and what I'm trying to do is to add dynamically B components when a button is pressed. (I want to have a list of B components)
The following line helps me to add a B component (it works perfectly)
<div class="bclass" bDirective ></div>
But the problem is that I want to do this when the button is pressed. So I've tried the following function but it doesn't work.
$scope.addBComponent = function(){
var temp = document.createElement('div');
temp.innerHTML = '<div class="bclass" bDirective ></div>';
document.getElementById("container").appendChild(temp);
};
Thanks,
Later edit:
bDirective is a directive that I've made who creates a square with some data in it. By pressind the add button I want to add that square. So, my problem is, how can I set one directive to a dynamically created div ?
More HTML code would have been helpful but anyways.
I am assuming you want to append one more element(component) below div on click. Since your code looks like an angular JS script, I am answering it in angular
<div class="bclass" bDirective ng-bind-html="divHtmlVar"></div>
<button ng-click="addBComponent ()">append</button>
$scope.divHtmlVar = '<div>test html</div>';
$scope.addBComponent = function(){
$scope.divHtmlVar = $scope.divHtmlVar + '<div>New div</div>';
};
You need to use the $compile service
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope, $compile) {
$scope.addBComponent = function() {
var temp = document.createElement('div');
temp.innerHTML = '<div class="bclass" b-directive>dd</div>';
document.getElementById("container").appendChild(temp);
$compile(temp)($scope);
};
})
app.directive('bDirective', function() {
return {
template: '<span>This is a test content</span>'
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app" ng-controller="AppController">
<button ng-click="addBComponent()">Add</button>
<div id="container"></div>
</div>
Note: You should not do dom manipulation as done in addBCompoment in a controller, it should go to a directive if possible

How to update a ng-include value when I click someWhere else than a div with angular?

I've this very simplified html:
<div ng-controller="Ctrl">
<div ng-include="template"></div>
</div>
My template1.html only contains:
<div id="i1" ng-click="clickFunction()">Content of template1.html</div>
The template2.html:
<div id="i2"> Content of template2.html </div>
And the following JS :
function Ctrl($scope) {
$scope.template = 'template1.html';
$scope.clickFunction = function () {
$scope.template = 'template2.html';
}
}
When I click on my included template my second template is loaded in place of the first one.
What is the clean Angular method to replace back the template2 with the template 1 when I click everywhere else on my page (but not in my ng-include div)?
Here a basic fiddle if it can help.
Edit :
I've tested to add the following code into my controller but the template view isn't updated (but the console.log yes, very strange behaviour...):
jQuery('html').click(function() {
console.log('Click on HTML')
$scope.template = 'template1.html';
});
jQuery('#i2').click(function(event){
event.stopPropagation();
});
If you are modifying the model outside angular environment, you have to use apply() method of scope to update.
$scope.template = 'template1.html';
$scope.$apply();
Also I updated the fiddle such that it meets your requirement.
Fiddle

Categories

Resources