Evaluating expression inside angular directive - angularjs

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.

Related

Angular.js: How to use ng-model outside its scope

I have searched a lot for this and couldn't get an appropriate answer. I am sorry if i am asking this question again. I am new to Angular.js
my code:
<table>
<tr>
<th ng-repeat="x in setno" ng-init="parentset=$index">SET {{ x.alpha }}</th>
</tr>
<tr ng-repeat="(parentset,ques) in selected">
<td ng-repeat="x in setno">
<select ng-model="ques" ng-options="y.name for y in topics"></select>{{ques.qid}}
</td>
<td>{{$parent.ques.qid}}hi</td>
</tr>
<tr>
<td ng-repeat="x in setno">
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>
</td>
</tr>
</table>
The ques ng-model is working fine just after the select tag but inside td tag only. How can i use it outside that particular tag.
ie, here:
<td>{{$parent.ques.qid}}hi</td>
and here:
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>?
I have tried $parent and without it, but its not working.
Where am i going wrong?
The select tag has his own scope so you have to extend an object in the parent scope if you want to use "ques" out of the select tag.
To do so, create an object (a $scope variable) in the parent :
$scope.test;
And extends it in the select (the child scope) :
ng.model = "test.ques";
Then you can access "ques" out of the select tag.

angular smart-table plugin/directive wont work

I am trying to use smart-tables, Select row plugin, I have added 'smart-table' to my application, like so var myApp = angular.module('myApp', ['ui.bootstrap','smart-table']);
I have also changed the first line of the directive (since it didn't work to just copy-paste it), I changed this:
ng.module('smart-table').directive('stSelectRow', ['stConfig', function (stConfig)
To this: myApp.directive('stSelectRow', ['stConfig', function (stConfig) {
In my html I have this
<table st-table="displayedCollection" st-safe-src="safeCollection" class="table">
<thead>
<tr>
<th>Title</th>
<th>FieldOne</th>
<th>FieldTwo</th>
<th>FieldThree</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in displayedCollection">
<td> {{row.Title}} </td>
<td> {{row.FieldOne}} </td>
<td> {{row.FieldTwo}} </td>
<td> {{row.FieldThree}} </td>
</tr>
</tbody>
If I remove the st-select-row="row" st-select-mode="multiple" the table works, but obviously not the row selection
I am guessing I'm missing some dependency or something, I have only added smart-table.min.js to my application, but I think that should be enough, the directive (select row plugin) is added inside my app.js file. What could it be?
It is because the documentation on the site isn't exactly clear. But it does say
...and the class attribute st-selected is set on the tr element.
You have to define the CSS for st-selected for it to "work":
.st-selected{
background: #216eff !important;
color: white !important;
}

What does reverse=!reverse means in angular orderby?

I am sorting data with AngularJS. I see in AngularJS documentation https://docs.angularjs.org/api/ng/filter/orderBy an example. I don't understand what does reverse=!reverse means in index.html. Here is the code:
div ng-controller="ExampleController">
<table class="friend">
<tr>
<th>Name
(^)</th>
<th>Phone Number</th>
<th>Age</th>
</tr>
<tr ng-repeat="friend in friends">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
</table>
</div>
I did as in the example. It works but I don't understand what does the expression reverse=!reverse means?
When you click the link for Phone Number or Age, the sorting of the list is put in reverse order by those columns. reverse=!reverse; just toggles the value of that variable from true to false or from false to true before it's passed to the order function.

table with ng-repeat not displaying correctly

Folks I am using a simple ng-repeat directive to display data in table.
However when the directive renders, the first column takes up all the space and dis-figures the table.
Take a look at the plnkr here :
http://plnkr.co/edit/Hahh4uyQ130zOS8noC3D
please focus on the file layout.html
<table>
<thead>
<tr ng-repeat="element in header" class="header-cells" style="width:{{element.width}}px">
<th drop-down-sort-menu>{{element.column}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="element in body">
<td ng-repeat="h in header" row="{{$parent.$index}}" col="{{$index}}" style="width:{{element.width}}px">{{element[h.column]}}
</td>
</tr>
</tbody>
</table>
I am sure it's something minor. any clues
I believe you problem is that for the headers, you have 4 TRs with only one TH, as opposed to one TR with 4 THs. For this reason, the cells on your headers are not matching the cells on your body.
Do the first ng-repeat at the TH level.
Give it a try and let me know.

angularJS - Repeating tr's in a table, but dynamically adding more rows while looping

Since examples always tell more then just words here is what I would like to do in another language
<tr>
<c:forEach items="${items}" var="item">
<td>...</td>
<td>...</td>
<td>...</td>
<c:if test="${item.showWarning}">
</tr><tr><td colspan="3">${item.warning}</td>
</c:if>
</tr>
So this will loop over a set of items and show some properties of these items. If there is a warning, a new row will be added underneath the current row in which the warning will be shown. However, how can I do this in angularJs? If I put a ng-repeat on the tr, it will stop at the first end tag of tr. I have read on some other threads that this is not very easily done, but how can it be done? And yes, I really do want to use a table. Here is my contrived example with angularjs which is obviously not working as I would like it to. Any pointers how this can be done?
JSBin example with tr-ng-repeat
Currently (1.0.7/1.1.5) you can't output data outside the ng-repeat, but version 1.2(see youtube video AngularJS 1.2 and Beyond at 17:30) will bring the following syntax(adapted to your example):
<tr ng-repeat-start="item in items">
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr ng-repeat-end ng-show="item.showWarning">
<td colspan="3">{{item.warning}}</td>
</tr>
The idea is that whatever is between -start and -end will be repeated including the -end element.
One solution that I can think of is having multiple tbody tags within the same table. Here is a discussion on the use of multiple tbody tags within the same table.
So, for your issue, you could have the following setup:
<table ng-controller="ItemController">
<thead>
<th>Name</th>
<th>Description</th>
<th>warning?</th>
</thead>
<tbody ng-repeat="item in items">
<tr>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item.warning}}</td>
</tr>
<tr ng-show="item.warning">
<td colspan="3" style="text-align: center">Warning !!!</td>
</tr>
</tbody>
</table>
Repeat the table body as many times as there are entries for the table and within it have two rows - one to actually display the row entry and one to be displayed conditionally.
You can repeat over the tbody
<tbody ng-repeat="item in items">
<tr>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item.warning}}</td>
</tr>
<tr ng-show="item.warning">
<td colspan="3">Warning !!!</td>
</tr>
</tbody>
Also you do not need to wrap the ng-show expression in {{}}, you can just use item.warning

Resources