I want to add classes based on a condition in angularJs, I am following below method and it is working fine, Is there any best practice?
<div ng-if="client.status != 2" class="list-primary">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
<div ng-if="client.status == 2" class="list-primary text-muted">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
You can use ng-class for this:
<!-- apply class 'text-muted' when client.status == 2 -->
<div class="list-primary" ng-class="{ 'text-muted': client.status == 2 }">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
In angular 1.1.5+ you can use javascript ternary operator.
<div ng-class="client.status == 2 ? 'text-muted' : 'other-class'" class="list-primary ">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
I hope this helps
Have a look at ng-class which is provided in AngularJS. Documentation here:
https://docs.angularjs.org/api/ng/directive/ngClass
Related
I'm fairly new to Angular, and I'm working on a simple flashcard website. Here's my current relevant HTML:
<div id="flashcards" class="row">
<div class="flashcard col-sm-6 col-md-4 col-lg-3"
ng-repeat="card in cards">
<div class="flashcard-inside"
ng-class="{'flipped' : card.flipped}">
<div class="flashcard-btns">
<button ng-click="flip(card)" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i>
</button>
<button ng-click="remove(card)" class="btn btn-danger">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="flashcard-front">
<textarea ng-model="card.front"
class="form-control
flashcard-content"
ng-tabindex="{-1 : card.flipped}">
</textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back"
class="form-control flashcard-content"
tabindex="card.flipped ? 0 : -1">
</textarea>
</div>
</div>
</div>
</div>
I'm making a flashcard for each card in cards.
My remove and flip functions are fairly simple:
$scope.flip = (card) =>
card.flipped = !card.flipped;
$scope.remove = (card)=>
$scope.cards = $scope.cards.filter(obj=> obj.front!=card.front || obj.back!=card.back);
As you can see above, I've tried ng-tabindex="{-1 : card.flipped}" and I've tried tabindex="card.flipped ? 0 : -1" and several other combinations with no luck. I was hoping someone more experienced in Angular could point me in the right direction. It seems my problems would be solved if I could get a hold of the DOM element from the card variable in my flip scrips, and set its tabindex attribute with jQuery, however I can't seem to access the element for the textarea (which would be nice because I'd also like to focus it later).
There is no need to use ng-attr-tabindex, it can simply be done with interpolation:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
The problem with the code in the question is that the interpolation needs double curly brackets ({{ }}).
The ng-attr-* syntax is only necessary in exotic situations.
For more information, see
AngularJS Developer Guide - Interpolation
AngularJS Developer Guide - ngAttr for binding to arbitrary attributes
Credit to #Phix for the suggestion to use ng-attr.
The relevant part is ng-attr-tabindex="{{card.flipped ? -1 : 0}}" and the same but with !card.flipped instead of card.flipped.
My full code is:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
ng-attr-tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
ng-attr-tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
Angular Docs
i need to show one and hide others.
in jquery i used 'this':
$('div').click(functiuon(){ this.show() });
maybe in Angular we can you use something like that?
<div class="toggle">
<span ng-click="this=!this ? true : false"></span><br/>
<span ng-if="this" >
111111111
</span>
</div>
<div class="toggle">
<span ng-click="this=!this ? true : false"></span><br/>
<span ng-if="this" >
2222222222222
</span>
</div>
etc this, this , this
I need to use only one varible for all blocks.
Any dom element interaction like clicking an element should be done within the directive and you can follow this to achieve what you want:
var app = angular.module('demoapp', []);
app.directive('toggleIt', function() {
return {
restrict: 'A',
link: function(scope, el, attrs) {
console.log(el.find('span'));
el.find('span').eq(0).on('click', function() {
el.find('span').eq(1).toggleClass('hide show');
});
}
};
});
.show{display:block;}
.hide{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='demoapp'>
<div data-toggle-it class="toggle">
<span>toggle1</span>
<br/>
<span class='spn show'>
111111111
</span>
</div>
<div data-toggle-it class="toggle">
<span>toggle2</span>
<br/>
<span class='spn hide'>
2222222222222
</span>
</div>
<div data-toggle-it class="toggle">
<span>toggle3</span>
<br/>
<span class='spn hide'>
3333333333333
</span>
</div>
</div>
You can use ng-hide for hiding an element on true or ng-show for showing an element on true:
<div class="toggle">
<span ng-click="pop1=!pop1 ? true : false"></span><br/>
<span ng-show="pop1" >
111111111
</span>
</div>
<div class="toggle">
<span ng-click="pop2=!pop2 ? true : false"></span><br/>
<span ng-show="pop2" >
2222222222222
</span>
</div>
You can use ng-if, ng-show, ng-hide, ng-class (in conjunction with css), and ng-switch.
ng-show, ng-hide and ng-if have kind of the same logic behind them (if the given variable is true/false, show/hide the following content). There are some performance differences between them, but this subject is out of scope.
Showing/hiding elements with ng-class is just a particular use case of it, but its achievable nonetheless.
To sum it up, ng-hide, ng-show, ng-if hide/show elements based on the truth evaluation of a given variable, while ng-class toggles a class, like
$('#someElement').toggleClass('randomClassName');
Example:
HTML
<div ng-app="exampleApp" ng-init="switchr1 = true; switchr2 = true; switchr3 = true; switchr4 = show; ">
<h2>ng-if</h2>
<div class="toggle">
<span ng-click="switchr1 = switchr1 ? false : true">click me</span><br/>
<span ng-if="switchr1" >
shown by ng-if
</span>
</div>
<h2>ng-show</h2>
<div class="toggle">
<span ng-click="switchr2 = switchr2 ? false : true">click me</span><br/>
<span ng-show="switchr2" >
shown by ng-show
</span>
</div>
<h2>ng-hide</h2>
which is the same thing as ng-show, but with reversed logic<br>
<div class="toggle">
<span ng-click="switchr3 = switchr3 ? false : true">click me</span><br/>
<span ng-hide="!switchr3" >
shown by ng-hide
</span>
</div>
<h2>ng-class</h2>
<div class="toggle">
<span ng-click="switchr4 = (switchr4=='show') ? 'hide' : 'show'">click me</span><br/>
<span ng-class="switchr4" >
hidden by ng-class
</span>
</div>
</div>
Notice, that you initiate switchr1, switchr2 and so on in the ng-init directive. You could have also done that in the js code, using $scope, but I did it this way for the sake of simplicity.
JS
var app = angular.module('exampleApp', []);
CSS
.hide {
display: none;
}
.show {
display: initial;
}
I also wrote some working code/full example for you:
http://codepen.io/VanTudor/pen/EKYZwM
I'm trying to create a means to toggle dynamically created rows of information. I've tried using ng-init, and then passing it to a function, but I'm screwing up somewhere and I can't seem to wrap my head around how or if this is possible. The gap, I believe, is in getting the concatenated scope variable to be referenced elsewhere. I'm using Bootstrap 3 and AngularJS 1.5.
The HTML:
<div class="row" data-ng-repeat="equipment in task.equipment">
<div class="col-md-12">
<h4 class="green-text">
{{ equipment.equipId }}
<small class="green-text">
<i class="glyphicon"
data-ng-class="{'glyphicon-triangle-bottom': field{{ $index }}, 'glyphicon-triangle-right': !field{{ $index }}}"
data-ng-init="equipment['field' + $index] = true"
data-ng-click="toggleTaskEquip('field{{ $index }}')">
field{{ $index }}: I WANT THIS TO WORK</i>
</small>
</h4>
</div>
<div data-ng-show="field{{ $index }}">
...stuff here...
</div>
</div>
The JS:
$scope.toggleTaskEquip = function(toggleBool)
{
if (toggleBool === true)
$scope.isTaskEquipOpen = false;
else if (toggleBool === false)
$scope.isTaskEquipOpen = true;
};
If I understand the problem correctly, you want to be able to toggle the boolean created in the ng-init with a click.
I think you need this:
<div class="container-fluid">
<div ng-controller="MyCtrl">
<div class="row" data-ng-repeat="equipment in task.equipment">
<div class="col-md-12">
<h4 class="green-text">
{{equipment.equipId}}
<small class="green-text">
<i class="glyphicon"
data-ng-class="{'glyphicon-triangle-bottom': isVisible, 'glyphicon-triangle-right': !isVisible}"
data-ng-init="isVisible = true"
data-ng-click="isVisible = !isVisible">I WANT THIS TO WORK</i>
</small>
</h4>
</div>
<div data-ng-show="isVisible">
...stuff here...
</div>
</div>
</div>
</div>
You don't even need the function toggleTaskEquip on the $scope.
JSFiddle here.
ng-repeat creates a new scope for each template instance, so you can just create a separate isVisible for each equipment with isVisible = true in the ng-init.
i've got a big performance issue.
I'm in a ng-repeat block (and i'm using track by id to improve performances).
In this block i'm generating the following dom:
1)button1A button1B
2)button2A button2B
3)button3A button3B
4)button4A button4B
5)button5A button5B
6)button6A button6B
There are some ng-show and ng-disabled in that page, on a variable that is set by ng-click on those buttons.
Performances are very poor.
On mobile we are using ng-mobile and\or fastclick for 300ms delay removing, but it seems that it tooks a lot of time to "update variables and the dom" after clicking on a button.
How can i improve performances?
Thanks a lot!
Edit: here is some code:
<div class="row" ng-repeat="date in dateRanges track by date.value">
<div ng-show="!date.custom" class="col-xs-14 col-sm-15 date-filter no-rel">
<div class="button-container button-radio"><button data-ng-class="{'radiob disabled': getDate() != date,'radiob active': getDate() == date}" ng-click="setDate(date)"></button></div>
<div class="button-container button-text">
<button class="select-date" ng-click="setDate(date)">{{date.title}} {{date.noDetails ? '' : date.start | date:'dd/MM/yyyy'}} {{date.noDetails ? '' : '-'}} {{date.noDetails ? '' : date.end | date:'dd/MM/yyyy'}}</button>
</div>
</div>
<div ng-if="date.custom" class="col-xs-2 col-sm-1 date-filter">
<button data-ng-class="{'radiob disabled':getDate() != date,'radiob active':getDate() == date}" ng-click="setDate(date)"></button>
</div>
<div ng-if="date.custom" class="col-xs-14 col-sm-15 date-filter no-rel">
<div class="row" data-ng-class="{'has-error': hasErrorComune && criteriRicerca_DateRange.custom}">
</div>
<div class="col-md-16 mrg-t-10 text-center">
<button id="Undo" ng-click="Undo()" class="btn btn-esci mrg-r-10">Undo</button>
<button type="submit" id="dropdownMovimentiConferma" ng-click="Operation()" data-ng-disabled="criteriRicerca_DateRange.custom && (hasErrorComune || hasErrorStart || hasErrorEnd)" class="btn btn-primary">OK</button>
</div>
You're testing on real mobile (harware) or emulator?
If on real, check task manager and cpu utilization.
i have this situation
<div ng-repeat="test in current">
<div ng-if="test.view == null">
<i class="icon ion-checkmark"></i>
</div>
</div>
but test.view== null doesn't work, neither just checking for test.view or test.view == ''
any ideas?
thanks
edit:
in the loop, sometimes test.view, has a value sometimes is NULL if i do:
<div ng-if="!test.view">1</div>
<div ng-if="test.view">2</div>
i will only see 1
You should check for !test, here is a fiddle showing that.
<span ng-if="!test">null</span>
See the correct way with your example:
<div ng-if="!test.view">1</div>
<div ng-if="!!test.view">2</div>
Regards, Nicholls
You can also use ng-template, I think that would be more efficient while run time :)
<div ng-if="!test.view; else somethingElse">1</div>
<ng-template #somethingElse>
<div>2</div>
</ng-template>
Cheers
Here is a simple example that I tried to explain.
<div>
<div *ngIf="product"> <!--If "product" exists-->
<h2>Product Details</h2><hr>
<h4>Name: {{ product.name }}</h4>
<h5>Price: {{ product.price | currency }}</h5>
<p> Description: {{ product.description }}</p>
</div>
<div *ngIf="!product"> <!--If "product" not exists-->
*Product not found
</div>
</div>