How to obtain index in nested ng-repeats - angularjs

I have an ng-repeat within a ng-repeat. I am tyring to obtain the index at both levels but am not able to :
<tbody>
<tr ng-repeat="element in body">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{$parent.$parent.$index}}" row="{{$parent.$index}}">{{element[h.column]}}</div>
<td>
</tr>
</tbody>
here is a plnkr too.
http://plnkr.co/edit/dGoN43HzQefVpCsp2R3j
The ISSUE is that value of "col" never gets populated. It does not capture the index.
Can anyone assist

You do not have to use $parent, just use $index to get index of inner loop and use indexOf() function of array to get index of outer loop...
HTML
<tr ng-repeat="element in body">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{body.indexOf(element)}}" row="{{$index}}">{{element[h.column]}}</div>
<td>
</tr>
UPDATE
Actually using ng-init would much better to get index of outer loop... here you can easily set rowIndex to current index at every turn and use it in inner loop...
<tbody>
<tr ng-repeat="element in body" ng-init="rowIndex = $index">
<td ng-repeat="h in header" style="width:{{h.width}}px">
<div col="{{$index}}" row="{{rowIndex}}">{{element[h.column]}}</div>
<td>
</tr>
</tbody>
here is updated PLUNKER

Related

Ng-if to show and hide td data

Attached is my code, tried showing td data when the condtion of ng-if is true
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report"
ng-if="(fellow.F_Id==value.fellowship_id)? (show_row = true) : (show_row=false)">
<td ng-show="show_row">{{value.Completed}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Not_Updated}}</td>
<td ng-hide="show_row">0</td>
<td ng-show="show_row">{{value.Total_schedule}}</td>
<td ng-hide="show_row">0</td>
</div>
</tr>
</tbody>
Its just giving 0 as result. Though data_report is having values
Tried adding span in td with conditions in td and result in span.
still the result is zero
May I know where the logic is going wrong and how it can be achieved?
Changed the code to
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<td>
<span ng-repeat="value in data_report" ng-show ="fellow.F_Id==value.fellowship_id">{{value.Completed}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Not_Updated}}</span>
</td>
<td>
<span ng-repeat="value in data_report" ng-show="fellow.F_Id==value.fellowship_id">{{value.Total_schedule}}</span>
</td>
</tr>
</tbody>
Here i am getting values but how can i set default value to zero if there are no values present?
In your case ng-if returns no boolean
The usage is (DOCs):
<ANY
ng-if="expression">
...
</ANY>
I think you dont need ng-if at all. You can write something like:
<tbody>
<tr ng-repeat="fellow in fellowships">
<td>{{$index}}</td>
<td>{{fellow.Fellowship_Name}}</td>
<div ng-repeat="value in data_report">
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Completed: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Not_Updated: 0}}</td>
<td>{{(fellow.F_Id==value.fellowship_id) ? value.Total_schedule: 0}}</td>
</div>
</tr>
</tbody>
Its not best solution, in Javascript you can set for example value.Completed to be by default 0. It will help you to simplify your HTML

Nested ng-repeat failing on inner loop

I am having trouble trying to present data from an api. The data comes in a json response organized like this API from Guild Wars for character data
I made an angularJS request and used a series of nested ng-repeats to present the data, but the innermost loop , the inventory data , isn't being present properly. Only some of it is being iterated.
This is my code :
<table>
<tr ng-repeat="char in $ctrl.chars | orderBy:'-age'">
<td>
<table id="charTotal">
<ng-include src="'charBasic.html'"></ng-include>
<ng-include src="'charBags.html'"></ng-include>
</table>
</td>
</tr>
</table>
Forgot to include charBasic.html :
<tr>
<td>
<table id="charBasic" class="charBasic">
<tr>
<td>{{char.name}}</td>
<td>{{char.race}}</td>
<td>{{char.profession}}</td>
<td>{{char.level}}</td>
<td>{{char.deaths}}</td>
<td>
<table>
<tr ng-repeat="craft in char.crafting">
<td>{{craft.discipline}}</td>
<td>{{craft.rating}}</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
charBags.html :
<tr>
<td>
<table id="charBags" class="charBags" border="1">
<tr ng-repeat="bag in char.bags">
<td>{{bag.id}}</td>
<td>{{bag.size}}</td>
<td ng-repeat="inv in bag.inventory"><ng-if "{{inv}}">{{inv.id}}</ng-if></td>
</tr>
</table>
</td>
</tr>
As it is, not all inventory arrays are iterated, and the results vary each time
What would be the correct way to iterate this data ?
I found out the problem, it was a duplicate item issue :(
I "solved" it by using track-by $index option inside ng-repeat, which will bypass the problem of duplicate ids.

Conditionally add row in ng-repeat

I've got a simple repeating table-row in AngularJS
<tr ng-repeat="item in items">
<td>{{ item.prop1 }}</td>
<td>{{ item.prop2 }}</td>
</tr>
My item object has a comment property on it, and if that comment contains a value, I want to display that in a row all by itself on the line right after the rest of the elements and have it span the entire row. Is that type of thing possible? I looked at ng-repeat-end but that doesn't seem to be what I want, and I can't just add and extra <tr> element inside the ng-repeat as that'd be invalid HTML.
You can use ng-repeat's special repeat start and end points via ng-repeat-start and ng-repeat-end.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-repeat="comment in post.comments">
<td>{{comment.content}}</td>
</tr>
</table>
UPDATE: If the comment is a string, then simply remove the ng-repeat at the ng-repeat-end end point and add an ng-if expression that validates the existence of post.comment.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-if="post.comment">
<td>{{post.comment}}</td>
</tr>
</table>

angularjs: ng-repeat-start and ng-repeat-end with inner ng-repeat

Hi I have a simple use case for ng-repeat-start and end and is working just fine, the problem appears when I want to add an inner ng-repeat.
Here is the my code
<tr ng-repeat-start="obj in rows" >
<td ng-repeat="e in obj.row">{{e}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="4">{{obj.description}}</td>
<tr>
The inner ng-repeat into td element is not working, I'm seeing the ngRepeat comment when I inspect the html source code, but the td elements are not being created.
<!-- ngRepeat: e in obj.row -->
My ugly workaround (given that I know the size of that vector) is:
<tr ng-repeat-start="obj in rows" >
<td>{{obj.row[0]}}</td>
<td>{{obj.row[1]}}</td>
<td>{{obj.row[2]}}</td>
<td>{{obj.row[3]}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="4">{{obj.description}}</td>
<tr>
I am not sure whether you are using angular 1.1.6 or not since ng-repeat-start and ng-repeat-end are not available in 1.1.5 or 1.0.7 yet.
However, you don't actually have to use the new directives to achieve that. You can simply implement it like this for right now:
<table>
<tbody ng-repeat="obj in rows">
<tr ng-repeat="e in obj.row">
<td>{{e}}</td>
</tr>
<tr>
<td colspan="4">{{obj.description}}</td>
<tr>
</tbody>
</table>
You may use ng-repeat-start and ng-repeat-end to reimplement it when AngularJS 1.1.6 version is officially released.
Demo
I think it might be something wrong with your data structure. Using Angular 1.2.1 this works for me
<div ng-app="myApp" ng-controller="myCtrl">
<div class="h" ng-repeat-start="val in data">{{val.title}}</div>
<div ng-repeat="con in val.content">
{{con}}
</div>
<div class="b" ng-repeat-end>footer</div>
</div>
See jsFiddle
You should be able to use index-based iterations to bypass that:
<tr ng-repeat-start="obj in rows" >
<td ng-repeat="e in obj.row">{{obj.row[$index]}}</td>
</tr>
<tr ng-repeat-end>
<!-- ... -->

AngularJS: ng-repeat for 2 x <tr> - can't use a DIV

I am having an issue i need to repeat the following.. as a group
<tr></tr>
<tr></tr>
I can't surround them with a DIV on put the ng-repeat on there as its invalid for TR i.e.
<div ng-repeat="item in items">
<tr></tr>
<tr></tr>
</div>
so i currently have the following implemented
<tr ng-repeat.....></tr>
<tr ng-repeat.....></tr>
but the problem is with this there is a collection of 6 items so the first TR renders 6 times and then 6 times for next ...
I am scratching my head trying to get around this but I just can't figure it out.
It would be nice if there was some sort of Div tag that was used for ng-repeat but didn't render an element to the DOM ??
It looks like the angularjs guys have implemented something along these lines. https://github.com/angular/angular.js/commit/e46100f7097d9a8f174bdb9e15d4c6098395c3f2
So the syntax would be
<tr ng-repeat-start="item in items"></tr>
<tr ng-repeat-end></tr>
You can put the ng-repeat on a tbody element :
<tbody ng-repeat="item in items">
<tr>
<td>{{item.row_one_stuff}}</td>
<td>{{item.more_row_one_stuff}}</td>
</tr>
<tr>
<td>{{item.row_two_stuff}}</td>
<td>{{item.more_row_two_stuff}}</td>
</tr>
</tbody>
<tr ng-repeat-start="item in items">
<td>{{item.data1}}</td>
</tr>
<tr ng-repeat-end>
<td>{{item.data2}}</td>
</tr>

Resources