AngularJS ng-if Ternary Conditional Attribute Use - html

Lets assume below sudo code, As you professionals can see I want to use Ternary kind of condition with ng-if to apply different HTML title attribute.
I tried it as below but it did not work
<td>
<span ng-if="isOk == true ? title ="Is Ok" : title ="Is Not Ok"></span>
</td>
I know I can achieve what I want applying ng-if in <td> level using below code
<td ng-if="isOk == true">
<span title ="Is Ok"></span>
</td>
<td ng-if="isOk != true">
<span title ="Is Not Ok"></span>
</td>
But I want to know weather I can use less code like Ternary check and achieve what I want with ng-if?
I thank you professionals in advace

As it was specified in this thread: if else statement in AngularJS templates, you can use ternary condition this way:
<span title="{{isOk ? 'Is Ok' : 'Is Not Ok'}}"></span>

Related

How to change color of a badge programmatically

i would like to know how can i change the color of a badge programmtically in angular.
i would like to be able to set the color of the badge initially to white and if the percVLRiskTotal is equal a specific value, then the color of the badge should be set to green for an example.
css:
<span class="badge badge-purple">{{percVLRiskTotal}} <span class="clr-sr-only"></span></span>
There are multiple ways to set a style class conditionally in Angular. For your case, you could do something like:
<span class="badge" [class.badge-green]="percVLRiskTotal === 1000">
{{percVLRiskTotal}} <span class="clr-sr-only">
</span>
This will apply the class named badge-green to the span element if the value of the percVLRiskTotal property equals 1,000.
More information can be found here.
based on your sample I think u can use ngClass like this:
[ngClass]="{'badge-purple': yourCondition === 'Option'}"
or for multiple conditions:
[ngClass]="{'badge-purple': yourCondition1 === 'Option1', 'badge-red' : yourCondition2 === 'Option2' }"
There are many methods to achieve. This
here I think you can use the ngStyle directive provided by angular
<span class="badge" [ngStyle]="{'background-color': percVLRiskTotal == 50 ? 'green':'blue'}">{{percVLRiskTotal}} <span class="clr-sr-only"></span>

Cleanly perform null checks in Angular HTML Template

I'm wondering if there's a way to shorten the code here:
<td class="value">
{{nonprofitRating?.financialRating?.performanceMetrics?.fundraisingEfficiency == null || ... == undefined ? ... : 'N/A' }}
</td>
to something more clean without adding getters to my .component.ts file. Is there a way to shorten the variable in Angular to something like in the below code block? This is information loaded into an NonprofitRating object from an API fetch call that may or may not be null or undefined, so I would prefer not to have 20 getters or 20 different variables in my .component.ts file for cleanliness purposes.
<td class="value" let fundraisingEfficiency = ...chained undefined check statement...>
{{fundraisingEfficiency == null || ... == undefined ? fundraisingEfficiency.toFixed(2) : 'N/A' }}
</td>
I ended up using ngSwitch to cleanly handle situations where the variable chaining would be too long, and avoid repetition. It also makes it very clean for handling if / else / then statements without mucking up the component.ts file, in my opinion.
<td class="value" [ngSwitch]="nonprofitRating?.accountabilityRating?.accountabilityTests?.materialDiversionOfAssets?.toLowerCase()">
<mat-icon *ngSwitchCase="'pass'" style="color: green" style="color: green">check_circle_outline</mat-icon>
<mat-icon *ngSwitchCase="'remediated'">remove_circle_outline</mat-icon>
<mat-icon *ngSwitchCase="'fail'" style="color: red">cancel</mat-icon>
<p *ngSwitchDefault>N/A</p>
</td>

Xpath issues selecting <spans> nested in <td>

I'm trying to extract text from a lot of XHTML documents with a program that uses Xpath queries to map the text into a structured table. the XHTML document looks like this
<td class="td-3 c12" valign="top">
<p class="pa-4">
<span class="ca-5">text I would like to select </span>
</p>
</td>
<td class="td-3 c13" valign="top">
<p class="pa-2">
<span class="ca-0">some more text I want to select </span>
</p>
<p class="pa-2">
<span class="ca-0">
<br>
</br>
</span>
</p>
<p class="pa-2">
<span class="ca-5">text and values I don't want to select.</span>
</p>
<p class="pa-2">
<span class="ca-5"> also text and values I don't want to </span>
</p>
</td>
I'm able to select the the spans by their class and retrieve the text/values, however they're not unique enough and I need to filter by table classes. for example only the text from span class ca-0 that is a child of td class td-3 c13
which would be <span class="ca-0">some more text I want to select </span>
I've tried all these combinations
//xhtml:td[#class="td-3 c13"]/xhtml:span[#class = "ca-0"]
//xhtml:span[#class = "ca-0"] //ancestor::xhtml:td[#class= "td-3 c13"]
//xhtml:td[#class="td-3 c6"]//xhtml:span[#class = "ca-0"]
I'm not sure how much your sample xml reflects your actual xml, but strictly based on your sample xml (AND disregarding possible namespaces issues you will probably face), the following xpath expression:
//td[contains(#class,"td-3")]/p[1]/span/text()
selects
text I would like to select
some more text I want to select
According to the doc, and to support namespaces, you should write something like this (fn:...) :
//*:td[fn:contains(#class,"td-3")]/*:p[1]/*:span
Or with a binding namespace :
node.xpath("//xhtml:td[fn:contains(#class,'td-3')]/xhtml:p[1]/xhtml:span", {"xhtml":"http://example.com/ns"})
This expression should work too (select the first span of the first p of each td element) :
//*:td/*:p[1]/*:span[1]
Side notes :
Your XPath expressions could be fixed. Span is not a child but a descendant, so we use //. We use () to keep the first result only.
(//xhtml:td[#class="td-3 c13"]//xhtml:span[#class = "ca-0"])[1]
(//xhtml:td[#class="td-3 c6"]//xhtml:span[#class = "ca-0"])[1]
Replace // with a predicate [] :
(//xhtml:span[#class = "ca-0"][ancestor::xhtml:td[#class= "td-3 c13"]])[1]
Test your XPath with : https://docs.marklogic.com/cts.validIndexPath
The solution is
//td[(#class ="td-3") and (#class = "c13)]/p/span
for some reason it sees the
<td class="td-3 c13">
as separate classes e.g.
<td class = "td-3" and class = "c13"
so you need to treat them as such
Thanks to #E.Wiest and #JackFleeting for validating and pointing me in the right direction.

Add multiple attributes based on *ngIf in Angular2?

Is it possible to add multiple attributes based on *ngIf?
My pseudo Code:
<span *ngIf="msg.active" *ngIf="msg.error" >Hallo</span>
And my output should be like this:
If msg.error == false and msg.active== true then it should be like this:
<span>Hallo</span>
If msg.error == true then it should be like this:
<span class="error" myTag="false" myTag2="false" >Hallo</span>
If msg.active == false then the span tag should be empty!
Does anybody have an idea?
i think you should try using nested ternary operator.
<span *ngIf="msg.active==true && msg.error==false? true: msg.active"> hallo <span>
try your condition using ternary operator. hope this will work
for myTag you have to use separate *ngIf
altogether in a single line it is possible as shown here,
DEMO : https://plnkr.co/edit/eKDhkuf3JO8CIKfz7Eqz?p=preview
<span *ngIf="msg.active || msg.error"
[class.error]="msg.error">
{{(msg.active==false)?'':'hello'}}
</span>

GSP/JSP for loop - first node 'selected' class

This is a GSP problem/niggle I've faced before in JSP and I'm looking for the cleanest possible solution.
Essentially, I'm using a for loop (<g:each> in GSP) to iterate through a list of items and output a HTML node for each item:
<g:each status="i" var="item" in="items">
<span class="item">${item}</span>
</g:each>
All <span> nodes contain a CSS class of item, but I want the first node to also contain a selected class. Thus, I update the code to:
<g:each status="i" var="item" in="items">
<g:if test="${i == 0}">
<span class="item selected">${item}</span>
</g:if>
<g:else>
<span class="item">${item}</span>
</g:else>
</g:each>
This seems like a complicated approach however as I'm duplicating a lot of code. Another solution is to use a custom tag library and pass the current index into it:
<g:each status="i" var="item" in="items">
<span class="item <g:getItemClass index='${i}' />">${item}</span>
</g:each>
The tag library will return selected when index is equal to 0, otherwise it won't return anything at all. Again, this adds complexity.
Other possible solutions:
Use the index in your CSS class name (very messy)
Set a class name var (). Not better than a custom tag imo.
Use scriptlets (no way)
Any other approaches to this that are clean and simple?
Thanks!
Usually it's just a:
<g:each status="i" var="item" in="items">
<span class="item ${i == 0 ? 'selected' : ''}">${item}</span>
</g:each>