"Use expression as" in ng-repeat - angularjs

Building a table I am deep within nested ng-repeats.
Depending on a scope variable I have to display/use a different field from my objects.
Is there a shorter way to adress the decision/field call in a way that could look like 'from now on use expression as myVar'?
Currently my code looks very ugly and basically always repeating a pattern like direction==='sources' ? connection.target.X : connection.source.X
As I am already pretty deep I cannot simply rearrange my array in Controller first.
This is just a small part of it:
<strong>{{direction==='sources' ? connection.target.name : connection.source.name}}</strong>
<br>
<a ng-click="goToEntityUsingReport(direction==='sources' ? connection.target.id : connection.source.id)">
<i class="fa fa-plus-square-o"></i>
</a>
<a ng-show="hasFurtherConnections(direction==='sources' ? connection.target.id : connection.source.id)" ng-click="setEntityFocus(direction==='sources' ? connection.target.id : connection.source.id)">
<i class="fa fa-chevron-circle-right"></i>
</a>
{{getEntityTotal(direction==='sources' ? connection.target.id : connection.source.id) | acCurrency}} total)

You can assign this expression on the return statement of a function in your controller in order to look cleaner.
e.g.
$scope.getValueBasedOnProperty(connection, prop) {
if($scope.direction === 'sources') {
return connection.target[prop];
}
else {
return connection.source[prop]
}
}
Then in the view:
<strong>{{getValueBasedOnProperty(connection, 'name')}}</strong>
<br>
<a ng-click="goToEntityUsingReport(getValueBasedOnProperty(connection, 'id')">
<i class="fa fa-plus-square-o"></i>
</a>
<!-- And goes on ... -->

Related

variable value depending on the view

I'm trying to make an angularjs app, I used the angularJS routing for the different views.
What I'm trying to do is have a variable that changes its value depending on the view I'm in, I tried to make a function :
$scope.set_variable = function(param){
$rootScope.variable = param;
}
then call the function with ng-click in HTML :
<div class="collection blue" ng-controller="AccueilCtrl">
<i class="material-icons mdi-action-home "></i> Accueil <span class="badge white lighten-2">Vous êtes ici</span>
<i class="material-icons mdi-action-supervisor-account "></i> Effectifs
<i class="material-icons mdi-action-today "></i> Absences
<i class="material-icons mdi-action-room "></i> Carto
</div>
but that wasn't a success, could you please help me do it ? or tell me why this isn't working ?
Thank you
In the controller of each view, inject $rootScope and then change the value of the variable using :
$rootScope.variable = value;
No need for different functions or ng-click because the controller is excecuted on its own when the view is called

Angularjs: how change icon when item is clicked

I know that this question has already some answers/solutions but none of them works for me most probably because this is the first time when I'm trying to implement something using Angularjs.
I have a div (title) that expands some info when it's clicked and I want to change the icon inside of it when that info is visible...
This is my code:
<div class="title" ng-click="view_variables(request)">
<i class="glyphicon glyphicon-chevron-right"></i>
</div>
And this is what I tried to do, but not working because the div will not show the expanded info anymore:
<div class="title" ng-click="view_variables(request) = !view_variables(request)">
<i ng-class="{'glyphicon glyphicon-chevron-right':!view_variables(request), 'glyphicon glyphicon-chevron-left': view_variables(request)}"></i>
</div>
Controller code:
$scope.view_variables = function(req){
if (!req.enabled_variables && !req.disabled_variables) {
$http.get('/api/files/' + $scope.file_id + '/requests/' + req.id + '/variables')
.success(function(data){
variables = data.data;
req.enabled_variables = [];
req.disabled_variables = [];
for (i=0; i<variables.length; i++) {
if (variables[i].disabled == true) {
req.disabled_variables.push(variables[i]);
} else {
req.enabled_variables.push(variables[i])
}
}
});
}
req.show_variables = !req.show_variables;
}
The view_variables function doesn't return anything, so it will always be treated as false.
You want something like this:
<div class="title" ng-click="view_variables(request)">
<i ng-class="{'glyphicon glyphicon-chevron-right':!request.show_variables, 'glyphicon glyphicon-chevron-left': request.show_variables}"></i>
</div>
I think the problem is what you have going on in the ng-click attribute. By using "view_variables(request) = !view_variables(request)" are you not calling the view_variables function twice? Also, it seems strange to be assigning a value to a function call.
I would just keep ng-click="view_variables(request)" as you had in the first line of code, then have the view_variables function set a boolean somewhere in scope ($scope.data.view_vars) and have that determine ng-class for your i element.
Good luck!
--EDIT: Now that you've put up your controller, req.show_variables looks like a useful candidate
Calling a function inside ng-class is a bad idea. Why don't you use a flag for it.
eg.
inside controller-
$scope.view_variables = function(request){
//your code
$scope.isExpanded = !$scope.isExpanded;
};
and in html
<div class="title" ng-click="view_variables(request)">
<i class="glyphicon" ng-class="{'glyphicon-chevron-right':!isExpanded, 'glyphicon-chevron-left':isExpanded}"></i>
</div>
May be Better this way using ng-show directive:
<div class="title" ng-click="view_variables(request)">
<i class="glyphicon glyphicon-chevron-right" ng-show="!view_variables(request)"></i>
<i class="glyphicon glyphicon-chevron-left" ng-show="view_variables(request)"></i>
</div>
You could use ng-if directive like so:
<div class="title" ng-click="view_variables(request)">
<i class="glyphicon glyphicon-chevron-right" ng-if="!view_variables(request)"></i>
<i class="glyphicon glyphicon-chevron-left" ng-if="view_variables(request)"></i>
</div>
assuming view_variables(request) returns true or false... maybe could replace it for req.show_variables.

angularjs how to trigger changes on object in scope

I have the $scope object (array of objects) like this
$scope.parts = [];
(content of $scope.parts is changing during 'run-time', not just filled once per page load)
Later, it some custom directive i show those parts in such manner:
<li ng-repeat="part in parts">
<span>{{part.name}}
<i class="fa fa-check"
tooltip="some tooltip"
...
</i>
</span>
</li>
According to some logic, i want to change 'fa-' class and tooltip text.
I can do it like this
<i class="fa"
ng-class="haveDescr(part.name)"
//and in directive's controller
$scope.haveDescr = function (partName) {
return someCondition ? 'fa-check' : 'fa-question-circle';
};
and so on for the tooltip, and... for every attribute i want to change?
Is there a better way, than to write a scope "check-function" for every attribute? How can i trigger changes in every single part/property of $scope.parts and do the DOM changes described above? What is the right "angular way" for this? Or, maybe it is possible to 'intercept' ng-repeat action and do everything there?
You can use ng-class with an 'object' expression.
<i class="fa" ng-class="{'fa-check' : part.name, 'fa-question-circle' : !part.name}">
You can use ng-class and title
<i ng-class="{'fa-check':showFaCheck(part.name), 'fa-question': !showFaCheck(part.name) }" title="{{getTooltip(part.name)}}"/>
Fiddle http://jsfiddle.net/4PYZa/303/

AngularJS ng-class multiple conditions with OR operator

I try to find out the good syntax for adding classes depending on angular values.
I want to activate a class regarding 2 conditions (one on live user changes, and one on loading datas) with a OR operator.
Here is the line :
<a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
<i class="fa orange" ng-class="{'fa-star': (favorite || (fav==myfav.id)), 'fa-star-o': !favorite}"></i>
</a>
I tried some different codes like this one :
ng-class="{'fa-star': favorite, 'fa-star': (fav==myfav.id), 'fa-star-o': !favorite}"
without any success.
Can someone help me finding the good syntax ?
Try this.
<a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
<i class="fa orange" ng-class="{'fa-star': favorite || fav==myfav.id, 'fa-star-o': !favorite}"></i>
No need the brackets.
Once you have to add some logic behind ng-class it's always better to stick to using the controller to do that. You can do it two of either ways: JSON syntax (same as in your HTML, just more readable) or obviously JavaScript.
HTML (JSON) Syntax
HTML
<i ng-class="getFavClassIcon(myFav.id)"></i>
JS
$scope.getFavClassIcon= function (favId) {
return {
'fa-star-o' : !$scope.favorite,
'fa-star' : $scope.favorite || $scope.fav === favId
};
};
Good Old IF-statement (JavaScript)
HTML
<i ng-class="getFavClassIcon(myFav.id)"></i>
JS
$scope.getFavClassIcon= function (favId) {
if (!$scope.favorite) {
return 'fa-star-o';
} else if ($scope.favorite) { // obviously you can use OR operator here
return 'fa-star';
} else if ($scope.fav === favId) {
return 'fa-star';
}
};
The HTML will remain the same
<a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
<i ng-class="{'fa-star-o':!favorite,'fa-star':favorite||fav===myfav.id}"></i>
</a>
But the order in which classes are present in your CSS file will matter
The fa-star class will apply either when favorite is true or fav===myfav.id returns true.
Therefore if after clicking once , suppose fav===myfav.id returns true and keeps on returning true , even when clicking again , then the class fa-star will be applied always from then on.
If by default favorite is false , then fa-star-o will be applied when template is loaded the first time, but after the first click ,when favorite is set to true , it will get removed. Then on second click , when favorite is set to false again , fa-star-o it will get applied but in this case , fa-star class will also be applied as fa===myfav.id condition would be still returning true (Assuming that is the case).
Therefore you will need to prioritize which class needs to get applied for sure when it is present on the element as case can arise when both classes can be present at the same time on the element. For example if fa-star-o class takes higher priority, then put it below the fa-star in your CSS , like for example
.fa-star {
border: 1px solid #F00;
}
.fa-star-o {
border: 1px solid #000;
}
See working demo at http://plnkr.co/edit/Dh59KUU41uWpIkHIaYrO?p=preview
You can use expression with ng-class
<i class="fa orange" ng-class="favorite || fav == myfav.id ? 'fav' : 'no-fav'"></i>
For example:
In my scenario i need to apply uppercase class in some condition and in some condition i do not need to apply that uppercase class.
inputTextCapitalSmall(assetId) {
return {
'uppercase': assetId !== 'TELEKURS' && assetId !== 'REUTERS' && assetId !== 'S&P',
};
}
<form [formGroup]="querySearchForm" >
<input autocomplete="off" matInput id="assetIdTypeValue" [ngClass]="inputTextCapitalSmall(querySearchForm.value.assetIdType)" >
</form>

Angularjs if/else statements

<div class="company_name" ng-controller="CompanyName">
<h1 class="left">
{{data.company_name}}
</h1>
</div>
What I'd like to do is make it so that if data.company_name hasn't been added through an input field, it shows a placeholder "Company name", how can that be done using angularjs?
You can use ng-if and do something like
<div class="company_name" ng-controller="CompanyName">
<h1 class="left">
<span ng-if="data.company_name === ''">
// Some placeholder
</span>
<span ng-if="data.company_name !== ''">
{{data.company_name}}
</span>
</h1>
</div>
BTW ngIf is a new directive added in v1.1.5 so you might need to upgrade your angular version
See my plunker here : http://plnkr.co/edit/qiN2XshEpay6e6zzhUKP
One way to keep the code clean is to use a filter. This piece of code adds a class to an active tab.
var filters = angular.module('filters');
filters.filter('ie', function(){
return function(v, yes, no){
return v ? yes : no;
};
});
Template
<li class="{{activeTab == 'home' | ie: 'active-class':''}}">
Home
</li>
For Using ng-if, ng-else-if, and ng-else in your project use this:
https://github.com/zachsnow/ng-elif
You can use ng-if condition for the check company name vlaue. Let's take example of
<span ng-if="driver.status_flag == 1">
<i ngif="{{driver.status_flag}}" class="icon-ok-sign icon-2x link" style="color:#090" href="#" title="Payment received" ></i>
</span>
In above example I have added condition status_flag value is 1 then the inside span value will show. Same way with your case you can add statement like
<span ng-if="data.company_name === ''">
<i ngif="{{driver.status_flag}}" class="icon-ok-sign icon-2x link" style="color:#090" href="#" title="Payment received" ></i>
</span>

Resources