Distinguish between $index in angularJS - angularjs

I have two ng-repeats, one inside the other.
<table ng-repeat="all in values track by $index">
<tr ng-repeat = "errors in all track by $index">
// I want to use the $index of both ng-repeats
</tr>
</table>
I have to use the $index of both the ng-repeats. How can I distinguish one $index from the other?

When using $parent.$index for getting the parents index:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="data in parent track by $index">
<div ng-repeat="data1 in data track by $index">
{{$parent.$index}}:{{$index}}
</div>
</div>
</div>
</div>
Where myApp is:
angular
.module('myApp',[])
.controller('myCtrl',function($scope){
$scope.parent = [
['a','e','i','o','u'],
['a1','e1','i1','o1','u1'],
['a2','e2','i2','o2','u2'],
];
});
You can have a look at more details in this jsbin.

Related

Nested Loops (ng-repeat) in AngularJS with $index

Lets say we have two ng-repeat (nested) in angularJS:
<div ng-repeat="animal of animals track by $index">
<div ng-repeat="name in names">
<p>{{$index}}</p>
</div>
</div>
In this example the $index would be the index of the child loop in names, but i want to have the index of the parent loop animals where i have the track by.
Why is this not working?
Try this.
<div ng-repeat="animal of animals track by $index">
<div ng-repeat="name in names">
<p>{{$parent.$index}}</p>
</div>
</div>

How to avoid ng-init in angular?

I want to show message when ng-repeat collection is empty i.e.:
<div ng-init="filteredArray=(array|filter:{...})">
<h1 ng-if="!filteredArray.length">Empty array</h1>
<table ng-if="filteredArray.length">
<tr ng-repeat="element in filteredArray">
<td>{{element}}</td>
</tr>
</table>
</div>
The problem is that ng-init will not watch for modification of the source array. Any hint how to do it properly?
You can just create the filtered variable in the ng-repeat, and use that one:
<div>
<h1 ng-if="!filteredArray.length">Empty array</h1>
<table ng-if="filteredArray.length">
<!-- here angular assigns the filtered array to the 'filteredArray' variable,
which then can be used -->
<tr ng-repeat="element in filteredArray=(array|filter:{...})">
<td>{{element}}</td>
</tr>
</table>
</div>
See also this jsfiddle
EDIT
If you don't like the ugly expression, you can also do something like this:
function myController ($scope, $filter) {
$scope.$watch("theFilter", function (val) {
$scope.filteredArray = $filter("filter")($scope.array, val);
});
}
And in your html:
<tr ng-repeat="element in filteredArray">
..
</tr>
Check in this jsfiddle
Check ng-repeats $last to show your message like below
<div ng-repeat="n in data track by $index">
<h1 ng-if="$last">Empty array</h1>
</div>
In your case you can have a variable at the table level and then set it to $last,when it'll be true your message will show like below
<body ng-app="app" ng-controller="ctrl">
<div ng-init='counter=false'>
<h1 ng-if='counter'>Empty array</h1>
<table ng-if="myData.length">
<tbody>
<tr ng-repeat="element in myData track by $index" ng-init="counter=$last">
<td>{{element}}
<ng-if ng-init='sync($last)'/>
</td>
</tr>
</tbody>
</table>
</div>
</body>
Your controller should look like below
var app=angular.module('app',[])
app.controller('ctrl',function($scope){
$scope.myData=['a','b','c']
$scope.sync=function(val)
{
alert(val)
$scope.counter=val
}
})
Since you have stored (array|filter:{...}) value into filteredArray, you cannot modify it in the template.
You should repeat (array|filter:{...}) code in the template.
<h1 ng-if="!(array|filter:{...}).length">Empty array</h1>
<table ng-if="(array|filter:{...}).length">
<tr ng-repeat="element in (array|filter:{...})">
<td>{{element}}</td>
</tr>
</table>

Display data from ng-repeat in multiple columns

I'm getting list of data from Db to a view using ng-repeat. In order to select multiple values at once I'm using checklist-model. My code is as follows,
<div ng-repeat="item in items">
<input type=checkbox checklist-model="user.role" checklist-value="item"/>{{item}}
</div>
This will return a long list one below another. What I need is to get these data in the list to be displayed in 4 columns. Any help please!
This was my previous question. For the answer for this I got this
<table>
<tr>
<td ng-repeat="item in items">
<input type=checkbox checklist-model="user.role" checklist-value="item"/>{{item}}
</td>
</tr>
</table>
and this
<div ng-repeat="item in items" style="display:inline-block;">
<input type=checkbox checklist-model="user.role" checklist-value="item"/>{{item}}
</div>
These codes make sure that the data are in a same row. But what I want is to add values into 4 separate columns. If there are 1000 data I need 200 data to be in one column, 200 in the second and so on. Please not that I'm using checklist-model
Hi Please try this and use logic
var app = angular.module("app",[]);
app.controller("MyCtrl" , function($scope){
$scope.index = 0;
$scope.items =["str1", "str2", "str3","str4","str5","str6","str7","str8","str9","str10"];
$scope.array = [];
for(var i=0; i<$scope.items.length/5;i++)
$scope.array.push(i);
});
<html>
<head>
<title>My Angular App!</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="MyCtrl">
<table>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
<td>Col4</td>
<td>Col5</td>
</tr>
<tr ng-repeat="i in array" ng-init="index = i*5">
<td ng-repeat="one in items.slice(index,index+5)">{{one}}</td>
</tr>
</table>
</div>
</body>
</html>
<div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index]}}</div>
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index+1]}}</div>
<div class="col-xs-4"> <input type="checkbox" checklist-model="user.role" checklist-value="{{products[$index]}}"/>{{products[$index+2]}}</div>
</div>
This did the trick. Thanks to #KhalidHussain

ng-repeat not showing any value

This is my controller
mode.controller("array_l",['$scope',function($scope){
$scope.items=[1,2,3,4,5];
//console.log( $scope.items);
}]);
This is my HTML
<div ng-controller="array_l" ng-repeat="item in items">
{{item}}
</div>
ng-repeat not showing any value
given controller and html
Move your ng-controller directive before your ng-repeat block.
Use track by $index in your ng-repeat to avoid problems with duplicate elements.
angular.module('mode',[])
.controller("array_l",['$scope',function($scope){
$scope.items=[1,2,3,1];
}]);
HTML:
<div ng-app="mode" ng-controller="array_l">
<div ng-repeat="item in items track by $index">
{{item}}
</div>
</div>
<div ng-repeat="item in items">
{{item}}
</div>
Defiantly worth reading through the Angular docs.

Angular Display NG-Repeat Display

I have the following code to display 3 different types on the page:
Production
Development
Maintenance
And I want the entire section (Production h4 and table/tbody) to disappear if there is no content in filteredResults. (Only appear if there is content)
<span ng-repeat="type in types">
<table class="max-width">
<tbody>
<div class="row" ng-repeat="result in filteredResults = (results | filter:search) | filter: status('status', type)">
<div class="left-header-padding" ng-if="$index==0">
<tr class="pull-left">
<h4 class="title">{{type.charAt(0).toUpperCase() + type.substring(1)}}</h4>
</tr>
</div>
</div>
</tbody>
</table>
</span>
I am currently trying ng-if for content inside the table, checking if ng-repeat occurs and only rendering the if there is content in ng-repeat, but I want the entire section (table included) to disappear when there is no content. Does anyone know how to accomplish this?
if you want hide table put ng-show into table tag ie:
<table class="max-width" ng-show="filteredResults.length >0">
<tbody>
<div class="row" ng-repeat="result in filteredResults = (results | filter:search) | filter: status('status', type)">
<div class="left-header-padding">
<tr class="pull-left">
<h4 class="title">{{type}}</h4>
</tr>
</div>
</div>
</tbody>
add ng-show="filteredResults.length" to your table element
<table ... ng-show="filteredResults.length">
example: http://plnkr.co/edit/WFQzRtXFe3UnvuzA8psa?p=preview
also, iv'e used tr inside tbody instead of div
Try using ng-init to create a local filtered collection and use the ng-if statement to hide the table if there is no items in the filtered collection.
<div ng-repeat="type in types">
<div ng-init="filteredResults = (results | filter:search) | filter: status('status', type)">
<table class="max-width" ng-if="filteredResults.lenght > 0">
<tbody>
<div class="row" ng-repeat="result in >
<div class="left-header-padding" ng-if="$index==0">
<tr class="pull-left">
<h4 class="title">{{type.charAt(0).toUpperCase() + type.substring(1)}}</h4>
</tr>
</div>
</div>
</tbody>
</table>
</div>
</div>
Let me know if you have any questions.

Resources