How to do a logic operation in Angular Template - angularjs

All:
I wonder how can I set a OR operator on a HTML string in Angualar Template, something like:
<div>{{value || <h6>No Header for now.</h6>}}</div>
The logic is if value is a string but not undefined, we show the value text, otherwise we show a error "No Header for Now" wrapped up by <h6>.
I do not know why this expression can not be correctly interpreted?
Thanks

This can be solved with ng-if:
<div ng-if="value">value</div>
<div ng-if="!value"><h6>No Header for now.</h6></div>
You can add specific attributes (e.g. class) and/or directives (e.g. ng-click) on each <div>.
The problem with using a single element is that you have to repeat your condition several times:
<div ng-class="{ value: 'class1', !value: 'class2' }"
ng-click="value ? action1() : action2()"
ng-bind-html="value || html">
</div>

You have to put a string, not an expression: <h6>No Header for now.</h6> is an invalid js expression. '<h6>No Header for now.</h6>' is a string and can be displayed in the {{ }}.
<div>{{value || '<h6>No Header for now.</h6>' }}</div>
or
<div>{{value != null ? value : '<h6>No Header for now.</h6>' }}</div>
I'm convinced the 2nd works.
EDIT:
If you want to add html code in the {{ }}, it is another problem. See AngularJS : Insert HTML into view, the filter 'sanitize' in 2nd answer should help you ( call {{ '<h1>test</h1>' | sanitize }} and it should work.
EDIT 2:
In a js file:
angular.module('yourapp')
.filter("sanitize", ['$sce', function($sce) {
return function(htmlCode){
return $sce.trustAsHtml(htmlCode);
}
}]);
In view:
<div>{{value || '<h6>No Header for now.</h6>' | sanitize }}</div>
In dont know if you need 'ngResource' to use $sce, if it doesn't work, you will have to install angular-resource :/

Related

angularjs uib-timepicker add variable runtime

I am using uib-timpicker for dates as input from user the problem is i want to add key to my data on runtime if something changes on the div e.g i want to add variable etiming.clockOut.edited to my data here is the code:
<div style="float:left" uib-timepicker key-handler="" data-ng-model="etiming.clockOut.time" ></div>
if you want to add dynamic key on change then simply use:
ng-change="etiming.clockOut.edited=true"
<divuib-timepicker key-handler="" ng-change="etiming.clockOut.edited=true" data-ng-model="etiming.clockOut.time" ></div>
or
create a function and on ng-change call the created function and assign anything you want in the function in your case :
<div uib-timepicker key-handler="" ng-change="callFunction(etiming.clockOut)" data-ng-model="etiming.clockOut.time" ></div>
and in js file
$scope.callFunction = function(data) {
data.edited =true //or false as you wish
}

Use angular translate with parameters and HTML

I have a translation label with parameters and html :
{
"myLabel": "There is <b>{{param}}</b> value."
}
I don't arrive to pass my parameter and to get the HTML interpreted. I try many option :
Option 1 : Use ng-bind-html with translate filter
<p ng-bind-html="{{'myLabel' | translate:{param: vm.myParam} }}"></p>
But I get this error :
angular.js:14642 Error: [$parse:syntax] http://errors.angularjs.org/1.6.5/$parse/syntax?p0=%7B&p1=invalid%20key&p2=2&p3=%7B%7B'general.help.notion.text3'%20%7C%20translate%3A%7BnbButton%3A%20vm.nbBtn%7D%20%7D%7D&p4=%7B'general.help.notion.text3'%20%7C%20translate%3A%7BnbButton%3A%20vm.nbBtn%7D%20%7D%7D
at angular.js:88
at r.throwError (angular.js:15200)
at r.object (angular.js:15189)
at r.primary (angular.js:15078)
at r.unary (angular.js:15066)
at r.multiplicative (angular.js:15053)
at r.additive (angular.js:15044)
at relational (angular.js:15035)
at r.equality (angular.js:15026)
at r.logicalAND (angular.js:15018) "<b ng-bind-html="{{'general.help.notion.text3' | translate:{nbButton: vm.nbBtn} }}">"
Is there a way to use ng-bind-html with a parameter ?
Option 2 : Use translate directive
<p translate="myLabel" translate-values="{'param': vm.myParam}"> </p>
But what I get is for example : There is <b>2</b> value.
My current sanitize strategy for angular translate is escaped, I tried with sanitize but in french all my accent are converted into their html code, for example : Déroulement d'un chapitre
I also try the escapeParameters and sanitizeParameters strategies and always I get : There is <b>2</b> value.
Do you know how I can achieve that ?
Thanks in advance
Takeshi
Try something like this:
<p ng-bind-html="'myLabel' | translate"></p>
Remember to include $sce service.
You could use the $translate service in order to get the string translated in the controller (providing the param as parameter), then set the translated value to a var and bind (ng-bind-html) this var in the view.
Something like this (I did not use the controllerAs syntax for brevity):
controller js
$scope.message = "About to be translated..."
$translate('myLabel', {param: 1}).then(function (text) {
$scope.message = $sce.trustAsHtml(text);
}, function (textID) {
$scope.message = $sce.trustAsHtml(text);
});
view
<p ng-bind-html="message"></p>
Working Plunker
Remember to inject the $sce service.

value of progressbar doesnt work

theres my progress bar code:
<div class="col-sm-4" ng-repeat="var in payloadNbrMissionParStatut">
<h4 class="no-margin">{{var.number}}</h4>
<progressbar value={{tom}} class="progress-xs no-radius no-margin" type={{gg}} ng-if="var.des=='Clos' ? gg='danger' : var.des=='En cours'? gg='warning' :gg='info' " ></progressbar>
{{var.des}}
</div>
the problem is in the value: when i populate it with static data it works good, but when i populate wit data come from the controller it doesnt work.
var is a reserved JS keyword. As errors inside directive expressions are silent, you aren't seeing any alerts because it's simply being ignored. Change var to something else and it should work.

checking multiple condition in ng-if

I need to check 4 conditions in ng-if which are boolean conditions. If any of them is true, I need to display some div.
Is there any simple and better way to do it please?
<div ng-if="ctrl.survivor || ctrl.doctor || ctrl.patient || ctrl.beneficiary">
<div ng-bind-html=" {{ myContent }}">
</div>
</div>
In general, complex logic inside of angular expressions is a code smell:
hard to read
hard to debug
hard to test
In general, I try to avoid boolean logic or anything else that indicates complexity in angular expressions that I write or code review. Instead, I recommend that you extract the logic into a controller method and call the controller method directly. This allows you to also write a nice unit test for it. The final code that I would recommend would look something like this:
<div ng-if="ctrl.isApplicable()">
<div ng-bind-html=" {{ myContent }}"></div>
</div>
In the controller:
class Ctrl {
...
isApplicable() {
return survivor || ctrl.doctor || ctrl.patient || ctrl.beneficiary;
}
...
}

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>

Resources