I know how to add a class on click of a button in 'jQuery'
$('#button1').click(function(){
$('#div1').addClass('alpha');
});
I want to achieve same thing by angular js. I have a controller - myController1. Can someone help me do it eazily?
AngularJS has some methods called JQlite so we can use it. see link
Select the element in DOM is
angular.element( document.querySelector( '#div1' ) );
add the class like .addClass('alpha');
So finally
var myEl = angular.element( document.querySelector( '#div1' ) );
myEl.addClass('alpha');
You can use ng-class to add conditional classes.
HTML
<button id="button1" ng-click="alpha = true" ng-class="{alpha: alpha}">Button</button>
In your controller (to make sure the class is not shown by default)
$scope.alpha = false;
Now, when you click the button, the $scope.alpha variable is updated and ng-class will add the 'alpha' class to your button.
Use the MV* Pattern
Based on the example you attached,
It's better in angular to use the following tools:
ng-click - evaluates the expression when the element is clicked (Read More)
ng-class - place a class based on the a given boolean expression (Read More)
for example:
<button ng-click="enabled=true">Click Me!</button>
<div ng-class="{'alpha':enabled}">
...
</div>
This gives you an easy way to decouple your implementation.
e.g. you don't have any dependency between the div and the button.
Read this to learn about the MV* Pattern
Try this..
If jQuery is available, angular.element is an alias for the jQuery function.
var app = angular.module('myApp',[]);
app.controller('Ctrl', function($scope) {
$scope.click=function(){
angular.element('#div1').addClass("alpha");
};
});
<div id='div1'>Text</div>
<button ng-click="click()">action</button>
Ref:https://docs.angularjs.org/api/ng/function/angular.element
First thing, you should not do any DOM manipulation in controller function.
Instead, you should use directives for this purpose. directive's link function is available for those kind of stuff only.
AngularJS Docs : Creating a Directive that Manipulates the DOM
app.directive('buttonDirective', function($timeout) {
return {
scope: {
change: '&'
},
link: function(scope, element, attrs) {
element.bind('click', function() {
$timeout(function() {
// triggering callback
scope.change();
});
});
}
};
});
change callback can be used as listener for click event.
querySelector is not from Angular but it's in document and it's in all DOM elements (expensive). You can use ng-class or inside directive add addClass on the element:
myApp.directive('yourDirective', [function(){
return {
restrict: 'A',
link: function(scope, elem, attrs) {
// Remove class
elem.addClass("my-class");
}
}
}
For Angular 7 users:
Here I show you that you can activate or deactivate a simple class attribute named "blurred" with just a boolean. Therefore u need to use [ngClass].
TS class
blurredStatus = true
HTML
<div class="inner-wrapper" [ngClass]="{'blurred':blurredStatus}"></div>
In HTML
To add the class named alpha, assign any variable like showAlpha to false first and then set it to true on click.
<div data-ng-class="{'alpha' : showAlpha}"> </div>
<button ng-click="addClass()"> </button>
In JS file
$scope.showAlpha = false;
$scope.addClass = function(){
$scope.showAlpha = true;
}
try this code
<script>
angular.element(document.querySelectorAll("#div1")).addClass("alpha");
</script>
click the link and understand more
Note: Keep in mind that angular.element() function will not find directly select any documnet location using this perameters
angular.element(document).find(...) or $document.find(), or use the standard DOM APIs, e.g. document.querySelectorAll()
Related
I am trying to make custom directive in angular .I try to add input field in my view when I click on button .In other words I am trying to make one custom directive in which when user press the button it add one input field in the browser .I think it is too easy if I am not use custom directive Mean If I use only controller then I take one array and push item in array when user click on button and button click is present on controller.
But when need to make custom directive where I will write my button click event in controller or directive
here is my code
http://play.ionic.io/app/23ec466dac1d
angular.module('app', ['ionic']).controller('appcontrl',function($scope){
$scope.data=[]
}).directive('inputbutton',function(){
return {
restrict :'E',
scope:{
data:'='
},
template:'<button>Add input</button> <div ng-repeat="d in data"><input type="text"></div>',
link:function(s,e,a){
e.bind('click',function(){
s.data.push({})
})
}
}
})
I just need to add input field when user click on button using custom directive ..could you please tell me where i am doing wrong ?
can we make button template and click event inside the directive
The reason it doesn't work is because your registering your click handler with jQuery. So when the click handler fires it is out of the scope of angular so angular does not know it needs to update its bindings.
So you have two options, the first is to tell angular in the click handler, 'yo buddy, update your bindings'. this is done using $scope.$apply
$apply docs: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply
e.bind('click',function(){
s.$apply(function() {
s.data.push({});
});
});
However angular already has built in directive for handling things like mouse clicks you can just use that and let angular do the work for you. This would be the better option.
so first in your view register a click handler on your button
<button ng-click="add()">Add input</button> <div ng-repeat="d in data"><input type="text"></div>
Then in your link simply add the add() method of your scope
s.add = function () {
s.data.push({});
}
Heres a working fiddle showing both examples. http://jsfiddle.net/3dgdrvkq/
EDIT: Also noticed a slight bug in your initial click handler. You registering a click but not specifying the button to apply it to. So if you clicked anywhere in the directive, not just the button, the handler would fire. You should be more specific when registering events manually, using ids, class names attributes etc.
The e or element property of the link function is a jqlite or full jQuery object of the entire directive. If you have jQuery included before angular it will be a full jQuery object. If not it will a jqlite object. A thinned out version of jQuery.
Here is a basic example for your logic .
var TestApp = angular.module('App', []);
// controller
TestApp.controller('mainCtrl', function mainCtrl($scope) {
$scope.data = [];
$scope.addDataItem = function () {
$scope.data.push({
someFilield: 'some value'
});
console.log('pushing value ... ');
}
});
// view
<div ng-app="App" class="container" ng-controller="mainCtrl">
<button type="button" ng-click="addDataItem()">Add an input</button>
<div ng-repeat="d in data track by $index">
<custom-directive model="d"></custom-directive>
</div>
</div>
// directive
TestApp.directive('customDirective', function customDirective() {
return {
restrict: 'E',
scope: {
model: '='
},
template: 'item -> <input type = "text" />',
link: function (scope, elem, attrs) {
console.log('scope.model', scope.model);
},
controller: function ($scope) {
// do staff here
}
}
});
I am trying to find the element in html by angularjs.
Here is the html:
<button class="btn btn-primary multi-files" type="button">
<span>Choose multiple files</span>
</button>
<br/><br/>
<input ng-file-select type="file" multiple style="display: none"/><br/>
I am trying to get the button element by class name multi-files, then I tried
var multibutton = angular.element(element.getElementsByClassName(".multi-files"));
But it does not work, and tried element.find but it only works for tag.
Is there any function that can get element by id or classname in angularjs?
getElementsByClassName is a function on the DOM Document. It is neither a jQuery nor a jqLite function.
Don't add the period before the class name when using it:
var result = document.getElementsByClassName("multi-files");
Wrap it in jqLite (or jQuery if jQuery is loaded before Angular):
var wrappedResult = angular.element(result);
If you want to select from the element in a directive's link function you need to access the DOM reference instead of the the jqLite reference - element[0] instead of element:
link: function (scope, element, attrs) {
var elementResult = element[0].getElementsByClassName('multi-files');
}
Alternatively you can use the document.querySelector function (need the period here if selecting by class):
var queryResult = element[0].querySelector('.multi-files');
var wrappedQueryResult = angular.element(queryResult);
Demo: http://plnkr.co/edit/AOvO47ebEvrtpXeIzYOH?p=preview
You don't have to add a . in getElementsByClassName, i.e.
var multibutton = angular.element(element.getElementsByClassName("multi-files"));
However, when using angular.element, you do have to use jquery style selectors:
angular.element('.multi-files');
should do the trick.
Also, from this documentation "If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite.""
#tasseKATT's Answer is great, but if you don't want to make a directive, why not use $document?
.controller('ExampleController', ['$scope', '$document', function($scope, $document) {
var dumb = function (id) {
var queryResult = $document[0].getElementById(id)
var wrappedID = angular.element(queryResult);
return wrappedID;
};
PLUNKR
If you want to find the button only by its class name and using jQLite only, you can do like below:
var myListButton = $document.find('button').filter(function() {
return angular.element(this).hasClass('multi-files');
});
Hope this helps. :)
I have an HTML element that I cannot directly make changes to.
How would I add an ng-click event to it?
E.g.
<div id="myDiv"><img src="my/img/src/jpg"/></div>
How would I add an ng-click to the div? Jquery or vanilla JS answers, please.
Okay, I worked out that, as the element is being provided by a service, it doesn't exist on page load, so I have to try another way to do this.
The answer, in other circumstances, would be:
$("#myDiv").attr("ng-click", "myFunction()");
$compile($("#myDiv"))($scope);
Just make sure your element exists, when you try to add something to it!
If you're not restricted to using an ID on your element (...if you could use a class instead), then you could write a directive to bind the click handler.
You would write the directive to restrict it to that class:
<div class="myClass"><img src="my/img/src/jpg"/></div>
angular.module('myModule', [])
.directive('myClass', function () {
return {
restrict: 'C', // <-- restrict to classname
link: function (scope, el) {
el.on('click', function () {
// do stuff
})
}
};
})
This would bind a click to any element with myClass added to it.
I have an angularjs directive restricted to class. How can I add this by using addClass method in angularjs
directive
app.directive('number', function() {
return {
restrict: 'C',
link: function () {
}
};
});
code
<div id="test"></div>
I know it is possible by using jQuery like the following.
$( "#test" ).addClass( "number" );
Please help me in doing it by using angularjs
You don't need to use .addClass() angular provide ng-class directive to add class conditionally.
ng-class="{number:[condition]}"
it will add class number whenever your condition return true
yes but your directive will not be used by this I misunderstood your question previously.
You should add ng-class="yourClass" to element on view and add in your controller
$scope.yourClass = "your-new-class", not in directive
try this
link: function (lEmel) {
lElem.addClass("Foo");
}
In the link function, is there a more "Angular" way to bind a function to a click event?
Right now, I'm doing...
myApp.directive('clickme', function() {
return function(scope, element, attrs) {
scope.clickingCallback = function() {alert('clicked!')};
element.bind('click', scope.clickingCallback);
} });
Is this the Angular way of doing it or is it an ugly hack? Perhaps I shouldn't be so concerned, but I'm new to this framework and would like to know the "correct" way of doing things, especially as the framework moves forward.
You may use a controller in directive:
angular.module('app', [])
.directive('appClick', function(){
return {
restrict: 'A',
scope: true,
template: '<button ng-click="click()">Click me</button> Clicked {{clicked}} times',
controller: function($scope, $element){
$scope.clicked = 0;
$scope.click = function(){
$scope.clicked++
}
}
}
});
Demo on plunkr
More about directives in Angular guide. And very helpfull for me was videos from official Angular blog post About those directives.
I think it is fine because I've seen many people doing this way.
If you are just defining the event handler within the directive,
you do not have to define it on the scope, though.
Following would be fine.
myApp.directive('clickme', function() {
return function(scope, element, attrs) {
var clickingCallback = function() {
alert('clicked!')
};
element.bind('click', clickingCallback);
}
});
Shouldn't it simply be:
<button ng-click="clickingCallback()">Click me<button>
Why do you want to write a new directive just to map your click event to a callback on your scope ? ng-click already does that for you.
You should use the controller in the directive and ng-click in the template html, as suggested previous responses. However, if you need to do DOM manipulation upon the event(click), such as on click of the button, you want to change the color of the button or so, then use the Link function and use the element to manipulate the dom.
If all you want to do is show some value on an HTML element or any such non-dom manipulative task, then you may not need a directive, and can directly use the controller.
In this case, no need for a directive. This does the job :
<button ng-click="count = count + 1" ng-init="count=0">
Increment
</button>
<span>
count: {{count}}
</span>
Source: https://docs.angularjs.org/api/ng/directive/ngClick
myApp.directive("clickme",function(){
return function(scope,element,attrs){
element.bind("mousedown",function(){
<<call the Controller function>>
scope.loadEditfrm(attrs.edtbtn);
});
};
});
this will act as onclick events on the attribute clickme