$index always 0 when using ng-bind-html - angularjs

I have a directive that contains this markup
<tr ng-if="isComplete()" ng-repeat="row in paged.page() track by $index" ng-click="rowClick(row, $event)" ng-class="assignRowClass(row)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(row[header.property], row, $index))"></td>
</tr>
The problem is that $index is always 0 when passed to the header.formatter function.

try this
<tr ng-if="isComplete()" ng-repeat="(index,val) in paged.page() track by index" ng-click="rowClick(val, $event)" ng-class="assignRowClass(val)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(val[header.property], val, index))"></td>

As saw in my comment this works
$parent.$index
This is because of the new scope created by ng-if and the limit of inheritance between scope in angular (because of javascript limits).
You can either go for $parent.$index of move the ng-if to the upper DOM Element if possible (<thead> / <tbody).

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.

ng-repeat or ng-options How can I automatically select the last row in a table ?

How I can I automatically select the last row in a table
ng-repeat="unit in selectedOrder.products" using something like select by track by $index == desc or alternatively ng-options
<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>
<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products" ng-if="$last">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>
will give you only the last row selected
In ng-repeat you can use the $last special variable to apply something only if it's the last element. see: https://docs.angularjs.org/api/ng/directive/ngRepeat
you can use it as a condition for anything you want to do in the tag. like
<img class="{{$last ? 'selected'}}" ng-class="{'selected': $last}" ng-if="$last" ....>
or however you like (these are just examples)
Always keep in mind though that using angular means that you have to edit your model to apply changes to your view, so if you want to have an element selected you have to do something to your model so that the element contains a value that makes it selected and then your view should reflect this.
For example in your controller you can check which element is the last in your ng-repeat array and add a selected variable, then in your view do something to make it look like your element is selected (for example: ng-class="{'selected': element.selected}") otherwise, by working on the view only you can make it look like the element is selected using $last but it won't be really selected in your model
In fact In ng-options (so we are talking about a select) you have to change your model in order to reflect your choice. So for example if your select has an attribute like this: ng-model="selected" then in your controller you set the $scope.selected variable to the last element of the array containing the values for your ng-options
You could use something like ng-if="$index == $last"

How to pass $index as a object key in ng-repeat?

I am facing a problem with angular where i have a dynamic generated object in the form below
object:{
0: [],
1: []
}
This is set in the angular controller so in the html side i want to do this
<tr ng-repeat="comapny in companies">
<td ng-repeat="option in object.$index">{{option.name}}</td>
</tr>
$index comes from the tr ng-repeat that wraps the ng-repeat with $index variable.
Is this even possible?
If you really have an object like this you can simply access the array by
option in object[$parent.$index]
You need to use $parent.$index because you want to access the $index of the first ng-repeat.
Objects don't have an index... the correct syntax for ngRepeat with objects is (k, v) in obj - so you can do:
<tr ng-repeat="(id, options) in companies">
<td ng-repeat="option in options">{{option.name}}</td>
</tr>

How to get rowspan into td element of table in AngularJS

In AngularJS 1.3, I'm creating a table from an array I've defined in my controller. Basically, I have the array:
sessionOverviewTrs = [{rowspan: 1},{rowspan: 2},..]
I've got code like this:
<tr ng-repeat="trs in list.sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index">
{{ tds.rowspan}}
The problem is I really want to put the rowspan on the td ng-repeat="tds... but I can't figure out to do that. I feel like I want to put my repeater for the td one level up in a div or something, then have the td executed with the
Why not to simply add the rowspan attribute?
<table>
<tr ng-repeat="trs in sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index" colspan="{{tds.colspan}}" rowspan="{{tds.rowspan}}">
{{tds.value}}
</td></tr></table>
Jsfiddle
<tr ng-repeat="trs in list.sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index" rowspan="{{tds.rowspan}}">

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.

Resources