How to add class on ng-click? - angularjs

I have this: http://plnkr.co/edit/gJko3umteXXEye7o9StR?p=preview
How can i add class "active-link" on:
#Translate("PERSONAL_INFORMATION")
#Translate("NOTIFICATIONS")
#Translate("CHANGE_PASSWORD")
#Translate("GAME_SETTINGS")

If your using classes like active-link, x-y which have dash (-) then you have to wrap it in ' as below.
ng-class="{'active-link' : activeLink==='PersonalInfo'}"
if your classes like activeLink which are doesn't have dash (-) then you can avoid from ' but not a must.
ng-class="{activeLink : activeLink==='PersonalInfo'}"
here is the updated DEMO

Add an ng-class to your element
<div ng-click="setClass()" ng-class="class">#Translate("NOTIFICATIONS")</div>
and change the value in your function
$scope.setClass(new function(){
$scope.class = "active-link";
})

Related

Add css class when user logged ng-class

How can I use ng-class to add a Css class where I put display: none; when the user is log in?. I'm using mean.js so I first tried using
ng-show="authentication.user"
But that only makes the element to hide like visivility : hidden;
Besides I need to add other classes in elements that i keep rather if the user is logged or not where I change margins and other stuff.
I tried using in angular a condition:
$scope.logged = false;
if ($scope.authentication.user) {
$scope.logged = true;
}
and then adding the ng-class condition like this:
ng-class="logged ? 'myClass1' : 'myClass2'"
But it failed, what am I doing wrong?
ng-if="authentication.user"
will remove the element altogether unlike ng-show which hides it.
With AngularJS, the right syntax is :
ng-class="{ className : Boolean}"
A example with multiple classes from AngularJS documentation :
ng-class="{strike: deleted, bold: important, 'has-error': error}"
Or with a function :
ng-class="{ invalid : !form.validPassword()}"
Hope this will help.

How to change the class using click and hovering

View:
<a ng-repeat="control in controls | filter:name" ng-href="#{{control.id}}" ng-click="restart(control.name)" ng-class="{active: control.name == selected}">{{control.name}}
controller- app.js
$scope.restart = function (controlName) {
$scope.selected = controlName;
}
Here i have added the active class while clicking.how can i add the hover class using mouseover and remover the class using mouse-leave.
As suggested above, use ng-class with ng-mouseover and ng-mouseleave:
<div ng-class="class" ng-click="class='active'" ng-mouseover="class='hovering'" ng-mouseleave="class=''"></div>
This way, you'll have 3 event listener to a single variable (in a mutually exclusive way).
If you want to have both at the same time, use an array this way:
<div ng-class="[classClick, classHover]" ng-click="classClick='active'" ng-mouseover="classhover='hovering'" ng-mouseleave="classHover=''"></div>
Use ng-class, ng-mouseover anf ng-mouseleave:
<div ng-class='{"classtoadd": add, "active": click, "hover": hover}' ng-mouseover="add=true;" ng-mouseleave="add=false" ng-click="click = true" ng-mouseover="hover = true"></div>
Thanks for your response. i want to add 'active' class while clicking.and i want add the add the class' hover' while 'hovering'

How can I check if an element's class is active in protractor?

I have the following code:
View:
<li class="active">
All Stacks
</li>
I can locate the element (tab) in the following manner:
var allStacksTab = element(by.linkText("All Stacks"));
Now how can I test, using the expect() --to see if that element/tab has the active class?
Once you grab the element as you did in your example you should be able to do the following or something similar...
allStacksTab.getAttribute('class').then(function (allClasses) {
expect(allClasses.indexOf("className") > -1).toBe(true);
});
Try to use by.cssContainingText, and if you using ES6 - it even simplier:
let allStacksTab = element(by.cssContainingText("li", "All Stacks"));
// split(' ') is needed since class might be 'inactive'
// and includes applied to string will return false positive 'true' in such case
let hasActiveClass = allStacksTab.getAttribute('class').then(classes => classes.split(' ').includes('active'))
expect(hasActiveClass).toBeTruthy('Element "All Stacks" should be active')
try something like this.
expect(element(by.linkText("All Stacks")).element(by.xpath('..')).getAttribute('class')).toEqual('active')
simple way to check if the class contains active:
var allStacksTab = element(by.linkText("All Stacks"));
allStacksTab.getAttribute('class')).toContain('active');`

ngClass string binding expression with class map

Is it possible to use ngClass with an expression AND a class map? I want to conditionally add a class based on the existence of a variable as well as use that variable in the expression that creates the class.
For instance, if isActive() is true and getStatus() returns "valid" I want the class list to be "element element--active element--valid". If getStatus() returns undefined I want the class list to be "element element--active".
<div
class="element"
ng-class="{
'element--active': ctrl.isActive(),
'element--{{ ctrl.getStatus() }}': ctrl.getStatus()
}"></div>
Doesn't seem to work.
<div
class="element element--{{ctrl.getStatus()}}"
ng-class="{
'element--active': ctrl.isActive()
}"></div>
Works but then there's an extra hanging "element--" if getStatus() returns undefined.
Do I have to add a method in my controller to handle the class generation?
i'd suggest to make just one function call to get the classes. It will make it cleaner and have the class logic in one place.
In your controller:
this.getElementStatus = function(){
var rules = {active:this.isActive()}; //Prefix with element-- {element--active:}
rules[this.getStatus()] = true; //Prefix with element--, rules['element--' + this.getStatus()] = true
return rules;
}
and your view would just be:
<div
class="element"
ng-class="ctrl.getElementStatus()"></div>
It seems like your element-- is redundant with the rule instead make use of cascadeability(CSS) property. and define rules as :
Example:
.element.active{ /*....*/ }
.element.success {/*...*/}
.element.error{/*...*/}
This will help in maintenance, gets more verbose and get to the natural way of adding css rules and could remove these kind of complexities from the view.
You could as well do:
<div class="element"
ng-class="{'active': ctrl.isActive(), '{{ctrl.getStatus()}}':true}"
or :
<div class="element"
ng-class="[ctrl.isActive() ? 'active' : '', ctrl.getStatus()]"
If you don't mind getting a true added as a rule(should not affect anything anyways) then,
<div class="element"
ng-class="[!ctrl.isActive() || 'element--active' , 'element--' + ctrl.getStatus()]">
You can use class and ng-class map on the same element. But since your class name is dynamic you will have to something like this.
<div
ng-class="'element '
+ (ctrl.isActive() ? ' element--active' : '')
+ (ctrl.getStatus() ? ' element--' + ctrl.getStatus() : '')"></div>

Change class of just one element in an ngRepeat

I have an ng-repeat. And I would like to change the class of just that element vs the entire group.
<button ng-class="defaultClass" ng-repeat="tube in node.Tubes" ng-click="toggleBtn(tube)">{{"Tube " + ($index + 1)}}</button>
with the above HTML on my ng-click I can pass the tube, which really only gives me the data passed from the API, if I console.log(this) I see the class name in an element called $$watchers but that seems odd to change it from there.
$scope.toggleBtn = function (element) {
console.log(element);
console.log(this);
}
In my controller I have $scope.defaultClass = "btn btn-off"; but if I change that with the function it changes every element.
How can I only change the class of the element clicked?
Continuing from the comments. Than you can't use $scope variable for that, because, as you said, it will be the same. TO solve this you need to use ng-class properly.
Docs: https://docs.angularjs.org/api/ng/directive/ngClass (see an example at the bottom of the page)
<button ng-class="{'btn-on' : tube.toggled, 'btn-off' : !tube.toggled}" ng-repeat="tube in node.Tubes" ng-click="toggleBtn(tube)">{{"Tube " + ($index + 1)}}</button>
http://plnkr.co/edit/WKLJ45yRYu1583C2ZnfT?p=preview
I'm not sure I understand if that's what you want, but you can use:
<button class="btn" ng-repeat="tube in node.Tubes" ng-class="{'btn-off':!toggled, 'btn-on':toggled}" ng-click="toggled = !toggled">{{"Tube " + ($index + 1)}}</button>
no need to add any code to the controller in this case.
These other answers are excellent. However, I would like to point out another method for this. Let's say you were looping through an array of receipts. For example, in the controller you had receipts in scope:
$scope.receipts = [ ... ];
And on the front-end you were looping through these receipts:
<div ng-repeat="receipt in receipts">{{ receipt.[attribute] }}</div>
One way to keep track of unique classes is to add a "class" key to the receipt objects. For example a receipt would look like:
receipt { 'id': '1', 'class' : ' ... ' }
On the front-end, you would determine the class using ng-class:
<div ng-repeat="receipt in receipts">
<div ng-class="receipt.class"></div>
</div>
And then, you could pass the receipt and its ID to a toggleButton() method like so:
<div ng-repeat="receipt in receipts">
<div class="btn" ng-click="toggleClass(receipt.id)"></div>
<div ng-class="receipt.class"></div>
</div>
And then within the controller you could simply update the class for that particular receipt (assuming here there is a method getReceipt() that gets a receipt from the array $scope.receipts):
$scope.toggleClass = function(id) {
getReceipt(id).class = { ... }
}
This would dynamically change the class for that single receipt based on the logic within the toggleClass() function.

Resources