get $index of item within ngrepeat - javascript

<ul ng-repeat="item in items">
<li>{{item.name}}</li>
</ul>
js
$scope.item = [
{
"itemId": 1,
"name":"laptop"
}
];
I want to the $index of item to be my itemId so in the future I can store in db or use it in somewhere else. I can do <li>{{$index}}</li> but how to bind it with my object of item in js?

You can bind with
<li ng-bind="$inndex" ></li>
Or store in id or other tags by
<li custom_tag="{{$index}}"></li>

One trick for selection of individual items of ng-repeat, is the inclusion of an controller in the same element as the ng-repeat.
The ng-repeat dedicated controller will contain all the new items generated by the iteration, ng-click calling a function in that controller will do the item selection.
Check Demo here.
<tbody ng-repeat="i in invoices"
ng-controller="RowCtrl"
ng-click="toggleRow()"
ng-switch on="isSelected()">
<tr>
<td>{{i.name}}</td>
<td>{{i.company}}</td>
</tr>
<tr ng-switch-when="true">
<td>{{i.invoice}}</td>
<td>{{i.units}}</td>
</tr>

Related

ng-if and ng-class-even/odd doesn't work well together and won't get expected outout

Here,I am loading a json file and using ng-repeat I display json data into table form.I am adding following features to code.
checkboxes to add the two CSS:
Bubble CSS
text-danger [In built class]
when you click on those check boxes, the CSS is applied only to the even rows in the table.
Using the ng-if or ngHide/Show to display the User-info which have the gender : Male.
I use ng-if to fulfill condition because ng-if will remove elements from DOM. This means that all your handlers or anything else attached to those elements will be lost.
ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles to hide/show elements.
I created Codepen demo for my problem.Here ng-if and ng-class-even doesn't give expected o/p.
HTML:
<body ng-app="module1" ng-controller="module1Ctrl as flight">
<div class="page-header">
<h1>Angular app</h1>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="danger">
Something's Wrong
</label>
<label>
<input type="checkbox" ng-model="bubble">
Zoom In/Out
</label>
</div>
<table class="table table-striped table-bordered">
<tr>
<th>name</th>
<th>Birthdate</th>
<th>gender</th>
<th>father</th>
<th>mother</th>
</tr>
<tr ng-repeat="x in flightData"
ng-class-even ="{'text-danger':danger,'bubble': bubble}"
ng-if="x.sex=='f'">
<td>{{x.name}}</td>
<td>{{ x.born |date:'yyyy-MM-dd THH:mm:ss'}}</td>
<td>{{x.sex }}</td>
<td>{{x.father}}</td>
<td>{{x.mother}}</td>
</tr>
</table>
</div>
</body>
JS
var app=angular.module('module1',[]);
app.controller('module1Ctrl', function ($scope,$http) {
$scope.getDataFromServer = function () {
$http.get('http://codepen.io/timivey/pen/emQZYY.js').then(
function(res){
console.log(res.data);
$scope.flightData = res.data;
}
,function (err) {
console.log(err.message);
})
};
$scope.getDataFromServer();
$scope.showList='table';
});
Just a small change to Joel's answer. You no need to create a separate filter method.
<tr ng-repeat="x in flightData | filter:{sex:'f'}"
ng-class-even ="{'text-danger':danger,'bubble': bubble}">
There is nothing wrong with your code, but there is a small error with your understanding:
<tr ng-repeat="x in flightData"
ng-class-even ="{'text-danger':danger,'bubble': bubble}"
ng-if="x.sex=='f'">
The ng-if="x.sex == 'f' statement is omitting each <td> from display, but it does not remove them from the flightData array. ng-repeat is run for each item in the array, not for each item that is displayed.
If you add {{$index}} to each row of the table you will see that the order is not 0,1,2,3... it is 1,2,7,11,14...
If you remove the ng-if statement, you will see that every even row has correct class applied.
Instead of using ng-if to remove the males from the list, use a filter instead:
<tr ng-repeat="x in flightData | females"
ng-class-even ="{'text-danger':danger,'bubble': bubble}">
Append this filter to your controller statement in the JS code:
.filter('females', function() {
return function(input) {
var out = [];
angular.forEach(input, function(x) {
if(x.sex == 'f') {
out.push(x);
}
});
return out;
};
})
http://codepen.io/anon/pen/mABJyo
What this does is remove the males from the list before it runs the ng-repeat and will correctly output in the order 0,1,2,3...

ng-repeat through object with value as an array angular

I have an object with key value pairs that looks like this. You will see that the key has an array as its value.
$scope.testObj = {
"London":[
{"id":1,"city":"London","country":"GB","name":"Test1"},
{"id":4,"city":"London","country":"GB","name":"Test2"}
],
"Los Angeles":[
{"id":8,"city":"LA","country":"US","name":"Test3"}
]
}
I want to display the name next to the city in the front end using angular. To do this I have tried many approaches, and used track by $index, but cannot figure out how to get this working.
<div ng-repeat="(key, val) in jobsByCity track by $index">
{{key}}:{{val[$index].name}}
</div>
I have looked at this approach too, nesting ng-repeat
<div ng-repeat="(key, val) in testCity">
{{key}}
<div ng-repeat="test in val[$index].name">
{{test}}
</div>
</div>
Just use another ng-repeat to iterate over the value:
<div ng-repeat="(key, val) in jobsByCity">
<div ng-repeat="subValue in val track by $index">
{{key}}:{{subValue.name}}
</div>
</div>
Also note that your Los Angeles property needs to be in quotes, otherwise it isn't valid javascript.
See this jsfiddle

Ng-click changing key,value pair

I have a ng-repeat like this:
<div ng-app="myApp" ng-controller="Ctrl">
{{ctrlTest}}<hr/>
<div ng-repeat="elements in filter">
<div>
<li ng-repeat="(key,value) in filter.producers" ng-show="value">
{{key}}<a ng-click="filter.producers.key=false"> X</a>
</li>
</div>
{{filter.producers}}
</div>
angular.module('myApp', [])
.controller('Ctrl', function($scope) {
$scope.ctrlTest = "Filters";
$scope.filter = {"producers": {"Ford":true,"Honda":true,"Ferrari":true}}
});
I am trying to make a ng-click that would set each label to false when clicking in a link, but I haven't achieved to do it properly as the key values are not fixed (they should be treated as variables).
So far I have tried it his way.
http://jsfiddle.net/Joe82/wjz8270z/5/
Thanks in advance!
Ps: I cannot change the json structure.
You just need to access the element of object by its key, to ensure that there references would not get lost & binding will work
<li ng-repeat="(key,value) in filter.producers" ng-show="value">
{{key}}<a ng-click="filter.producers[key]=false"> X</a>
</li>
Forked Fiddle
You also call a function and set value false
HTML
<li ng-repeat="(key,value) in filter.producers" ng-show="value">{{key}} {{value}}<a ng-click="setValue(key)"> X</a>
JS
$scope.setValue = function(key){
$scope.filter.producers[key.toString()] = false;
}
see this link http://jsfiddle.net/wjz8270z/8/

angularjs ng-repeat hide element with a click event

There is a list of items which is displayed using ng-repeat. Each item is associated with a hide link. The intent is to hide an item if its corresponding hide link is clicked.
view:
<div ng-repeat="item in products">
<div>{{ item }}</div>
<a href"javascript:void(0)" ng-click="hideMe(item)">[delete]</label>
</div>
How could I implement the function hideMe(item) such a way that it could hide item div element, something like following, ng-if could identify when to hide based on the click event -
<div ng-if="...">{{ item }}</div>
For every list-item, you want to hide it if it's clicked. The best way we can do this is by adding the ng-hide directive.
Using the ng-click directive on a button, we can set the hidden property of an item to true, meaning it should be hidden.
<ul>
<li ng-repeat="fruit in fruits" ng-hide="fruit.hidden">
<p>{{fruit.name}}</p>
<button ng-click="hideMe(fruit)">hide li</button>
</li>
</ul>
$scope.hideMe = function (fruit) {
fruit.hidden=true;
alert('hide this li');
};
Here is a fiddle
http://jsfiddle.net/5yh8bxay/1/
You could use an array of objects like this: $scope.products = [{name: 'hello', status: true}]
And then you can hide them changing the status property:
<div ng-repeat="item in products">
<div ng-show="item.status">
{{ item.name }} <a href"javascript:void(0)" ng-click="item.status = false">[delete]</label>
</div>
</div>
JSFiddle
You can use $index to do that.
Something like this.
<div ng-repeat="item in products">
<div ng-hide="selected.index === $index">{{ item }}</div>
<a href"javascript:void(0)" ng-click="selected.index = $index">[delete]</label>
</div>
Just store the selected value when clicked and use-hide you can use ng-class to hide the item, comparing them to the selected index.

Angular show/hide with nested repeats

I have a double repeat going on here, an initial repeat list, and then a second one (for expanding details). What is the best way to show/hide the second repeat ONLY at that index in which clicked at. I have them separated by class name however Angular's Jquery Lite doesn't support the "nextUntil" feature. I'm thinking a ng-class conditional but I don't want based on the Scope (needs to be temp for each expand).
<tr ng-repeat-start="x in calls track by $index" class="{{x.status}}" class="{{x.status}}" ng-click="getCallDetails(x,$index)" my-draggable >
<td><small><i class="fa fa-plus"></i></small></td>
<td style="text-align:center;"><span class="label label-default stat-context {{x.status}}">{{x.statusdesc}}</span></td>
<td>{{x.cust_no}}</td>
<td>{{x.company}}</td>
<td>{{x.name}}</td>
<td>{{x.emp_id}}</td>
<td>{{x.enterdate}}</td>
</tr>
<tr class="callDetails" ng-class="callDetails" ng-repeat-end ng-repeat="y in x.callDetails" >
<td></td>
<td colspan="2">{{y.emp_name}}</td>
<td>{{y.attempt_date}}</td>
<td colspan="2">{{y.note}}</td>
<td class="allAtt-stat">{{y.callstatus}}</td>
</tr>
</tbody>
my simple angular functions
$scope.getCalls = function() {
$http.get("callView.php")
.success(function(response) {
$scope.calls = response;
});
};
$scope.getCallDetails = function(attempt,ind) {
$http.get("callDetails.php?a=" + attempt.action_id)
.success(function (response) {
attempt.callDetails = response;
});
};
With nested ng-repeats, $index would refer to the innermost scope.
If you want to differentiate between parentindex and childindex, child elements can be accessed using $index while parent elements can be accessed either using $parent.$index or using ng-init, parentindex can be initialised to some value.
First approach:
<div ng-repeat="item in items">
<div>{{item.key}}</div>
<ul ng-repeat="val in item.value track by $index">
<li >child index {{$index}} -- parentIndex {{$parent.$index}}</li>
</ul>
</div>
Second approach:
<div ng-repeat="item in items" ng-init="parentIndex=$index">
<div>{{item.key}}</div>
<ul ng-repeat="val in item.value track by $index">
<li >child index {{$index}} -- parentIndex {{parentIndex}}</li>
</ul>
</div>
see the demo for reference

Categories

Resources