How to hide the label text when the value is empty? - angularjs

Within a table cell, I am listing several items that are populated using ng-repeat, using the structure below. However, for some entries, properties such as "user.favcolor" are blank. What's the easiest way to hide text such as "Favorite color:" in that case so that I don't end up with a row that has "Favorite color:" and no value beside it?
<table>
<thead>
<tr>
<th>Price</th>
<th>Plan Contents</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tip in tips">
<td>{{tip.priceMonthly}}</td>
<td><span>Name: {{user.name}}</span>
<span>ID: {{user.id}}</span>
<span>Favorite color: {{user.favcolor}}</span>
</td>
</tr>
</tbody>
</table>

You can use the ng-show directive for this:
<span ng-show="user.favcolor">Favorite color: {{user.favcolor}}</span>
The ng-show works such that the element is only shown if the expression evaluates to true. An empty string here will evaluate to false hiding the entire element.
Alternatively, you can also specify a default value:
<span>Favorite color: {{user.favcolor || "Not specified" }}</span>
In this case, if user.favcolor evaluates to a false, it will print Not specified instead.

Related

Colorize function not working after updating 2D Array

I am using a duo of ng-repeat's to create a matrix table, but after updating the data the coloring function (a simple return 'green' if the argument is above 0) stops working.
When I load the first (fake) data the colors work just fine, but after any updates it stops working. When initializing the 2d array it will always load and display properly. I have found no debug errors or problem with the logic.
Jfiddle
UPDATE**: I created a simple function that changes a few values in the 'original' 2D-array and I still face the problem with it not updating colors. I am pretty positive this is an AngularJS problem (shortcoming?) and not an issue with the data itself.
HTML
<!-- MATRIX TABLE -->
<div class="center w80" >
<div id = "MatrixTable2">
<table border="1">
<thead>
<tr>
<th></th> <!-- blank -->
<th ng-repeat="ppp in PlayerIDList">{{ppp.name}}</th>
</tr>
</thead>
<tbody>
<tr width="50px" ng-repeat="row in Matrix" >
<td class="rowlabel">{{PlayerIDList[$index].name}}</td>
<td width="50px" ng-repeat="col in row track by $index" ng-class="::funcGetColorByBool({{col}})">{{col}}</td>
</tr>
</tbody>
</table>
</div>
<!-- END MATRIX TABLE -->
I believe your problem is the class binding, the :: prefix means this expression is only evaluated once.
"::funcGetColorByBool({{col}})"
Also, you need to fix your expression to pass in the value of col:
from:
ng-class="::funcGetColorByBool({{col}})"
to:
ng-class="funcGetColorByBool(col)"
Here is a working plunker.

Expand/collapse odd row in AngularJs

I want to expand/collapse a row, I want to hide all odd rows and on clicking '+' button those hidden row should get visible, my current code is allowing me hide all the odd rows but on clicking '+' button all row are getting visible, my use case is to show only the odd row which is next to clicked even row.
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
<tbody ng-repeat="test in ctrl.SearchResults">
<tr ng-if="$even">
<td>
<button ng-click="ctrl.expanded = !ctrl.expanded" expand>
<span ng-bind="ctrl.expanded ? '-' : '+'"></span>
</button></td>
<td>{{test.apName}}</td>
<td>{{test.type}}</td>
</tr>
<tr ng-show="ctrl.expanded" ng-if="$odd">
<td></td>
<td>{{test.apName}}</td>
<td>{{test.type}}</td>
</tr>
</tbody>
</table>
The reason all the rows expand when you hit the plus, is that the variable expanded is on the controller. So all the rows are 'listening' to the same variable.
As atfornes pointed out in his answer, you could use the $index to identify each row. Another solution is to keep track of the current index on the controller and check for per row if he must be showed:
<tr ng-show="ctrl.expanded == $index" ng-if="$odd">
And on the click event of the plus sign you could have
ctrl.expanded = $index
Or you could handle this in the controller. In this case you can create a method on the controller which accepts the index and then set this index value to the controller's variable expanded.
At the button ng-click code, you could store the current $index with a code like:
<button ng-click="ctrl.expanded = !ctrl.expanded; ctrl.index = $index" expand>
then, you can change the ng-show condition to only display the item if ctrl.expanded and $index === ctrl.index + 1:
<tr ng-show="ctrl.expanded && $index === ctrl.index +1" ng-if="$odd">

Evaluating expression inside angular directive

I want my table to conditionally render its row based on whether the value is null or not. The rows have different custom entries and labels, that's why I can't just use ng-repeat. Here's the code:
<table>
<thead>
</thead>
<tbody>
<tr ng-show = "{{data.entry_1}} !== null">
<td>Custom Label 1</td>
<td>{{data.entry_1}}</td>
</tr>
<tr ng-show = "{{data.entry_2}} !== null">
<td>Custom Label 2</td>
<td>{{data.entry_2}}</td>
</tr>
.
.
.
<tr ng-show = "{{data.entry_n}} !== null">
<td>Custom Label n</td>
<td>{{data.entry_n}}</td>
</tr>
</tbody>
</table>
However, it seems that this way is not right. It's either javascript (compiler) is complaining at {{}} in the ng-show or at '!== null' or maybe both. How to evaluate an angular expression (in {{}}) inside an ng- directive?
I know that I could also evaluate this instead in the js file, but since I don't want to add further scope variables (to make my code cleaner), I chose to evaluate if it is null in the ng-show directive. Could someone tell me how to do it?
Thanks.
You were close. The curly braces are only needed to echo/print/render the value of the variable. In an expression you should never use the curly braces.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app ng-init="data = {entry_1: 'notnull', entry_2: null, entry_n: 'againNotNull'}">
<thead>
</thead>
<tbody>
<tr ng-show="data.entry_1">
<td>Custom Label 1</td>
<td>{{data.entry_1}}</td>
</tr>
<tr ng-show="data.entry_2">
<td>Custom Label 2</td>
<td>{{data.entry_2}}</td>
</tr>
.
.
.
<tr ng-show="data.entry_n">
<td>Custom Label n</td>
<td>{{data.entry_n}}</td>
</tr>
<tr ng-show="data.device">
<td>Custom Device</td>
<td>{{data.device}}</td>
</tr>
</tbody>
</table>
Use $compile service in the context of the scope inside your directive.
See https://docs.angularjs.org/api/ng/service/$compile
Edit: I agree with Martin's answer.

Only show number bigger than zero with Angular

I dont want to show the price if it's value is 0, only show the name and nothing in price then !
If its greater than 0 then it should show both name and price.
How to do that?
<tr>
<td>{{cars.name}}</td>
<td>{{cars.price}}</td>
</tr>
<tr>
<td> {{cars.name}} </td>
<td><div ng-show="cars.price > 0"> {{cars.price}} </div></td>
</tr>
Edit: if ng-show is evaluated to false it will hide the element by applying display:none; to the element style.
you can also use ng-if which will not render the element at all
Use ng-if if you don't want the cell included in the DOM, use ng-show if you want it to be included but not visible.
<tr>
<td>{{cars.name}}</td>
<td ng-if="cars.price > 0">{{cars.price}}</td>
</tr>
If you're worried about HTML validators
<tr>
<td>{{cars.name}}</td>
<td ng-if="cars.price > 0">{{cars.price}}</td>
</tr>
also works.
This will however probably skew your table a bit, since ng-show still uses display:none;. You can fix that by overriding the .ng-hide CSS class that gets assigned to hidden elements and set it to visibility: hidden; instead.

ngRepeat with Table: Change a cell's display text

I have a list of mails which I want to show in a grid (<table>). Some of these mails have attachments. For their corresponding rows, I would like to show an attachment icon in the attachment column. For rest, it should be empty.
JsFiddle: http://jsfiddle.net/6s4Z5/
My template is as follows:
<table id="resultTable">
<thead>
<tr>
<th ng-repeat="columnId in schema.columnOrder">
<img src="icon_attach.png" ng-if="columnId == 'hasAttachments'">
{{schema.columns[columnId].displayText}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in results.mails">
<td ng-repeat="columnId in schema.columnOrder">
<img src="icon_attach.png" ng-if="columnId == 'hasAttachments' && row.hasAttachments">
<span ng-if="columnId != 'hasAttachments'" >{{ row[columnId] }}</span>
</td>
</tr>
</tbody>
</table>
where schema.columnOrder is an array of columnIds to be shown in the table.
This template is working but is this the best way to implement this? Moreover, I have to add an extra <span> for ng-if statement. Can that also be removed?
You pretty much can change it to something like:
<span ng-if='your check'><img src=''/>{{row[columnId}}</span>
You could set (in the controller) the value of the column hasAttachments to be the image you want to display there.

Resources