Adding active class in ng-repeat - angularjs

I have two iterations, one list and its wrapper. I want to add a class when I click on the item. But now the class added all wrapper list item. Please see the below link.
$scope.select= function(index) {
$scope.selected = index;
};
https://jsfiddle.net/9me2L1ev/
Please anyone help me. Thanks
Vimal

You need to do something like this you have logical error.
<div ng-app='app' class="filters_ct" ng-controller="selectFilter">
<div ng-repeat="filter1 in filters">
<ul>
<li ng-repeat="filter in filters" ng-click="filter1[selected] = $index " ng-class="{active: $index == filter1[selected]}">
<span class="filters_ct_status"></span>
{{filter.time}}
</li>
</ul>
</div></div>
check out updated fiddle link

You need to combo two $index value. Reference to parent $index using $parent.$index
ng-click="select($parent.$index, $index)" ng-class="{active: $parent.$index + '.' + $index == selected}"
and
$scope.select= function(parentIndex, index) {
$scope.selected = parentIndex + '.' + index;
};
Check this https://jsfiddle.net/56dc8dej/

I have updated code in his link
<div ng-app='app' class="filters_ct" ng-controller="selectFilter">
<div>
<ul>
<li ng-repeat="filter in filters" ng-click="select($index)" ng-class="{active: $index == selected}">
<span class="filters_ct_status"></span>
{{filter.time}}
</li>
</ul>
</div></div>

you need to consider the parent index...
<div ng-app='app' class="filters_ct" ng-controller="selectFilter">
<div ng-repeat="filter1 in filters">
<ul>
<li ng-repeat="filter in filters" ng-click="select($parent.$index, $index)" ng-class="{active: $parent.$index+','+$index == selected }">
<span class="filters_ct_status"></span>
{{filter.time}}
</li>
</ul>
</div>
</div>
And in you controller:
...
$scope.select= function(pindex, index) {
$scope.selected = pindex+','+index;
};
...

Related

First item of a ng-repeat with a if condition

I have the following:
<li ng-repeat="category in categories" ng-if="category.id== '3'">
<div ng-repeat="item in items" ng-if="item.no == category.no" ng-style="{'margin-left': ($first ? '20px': '0px')}">
...
</div>
</li>
it can only work on the very first item, but not every first item in each li. How can I update this?
You need to try it like this. The way you were doing it $first refers to the first ng-repeat.
<li ng-repeat="category in categories" ng-if="category.id== '3'">
<div ng-repeat="item in items" ng-if="item.no == category.no">
// use $parent.$first to check for the first item of categories
// using $first here refers to first item in items array
<div ng-style="{'margin-left': ($first ? '20px': '0px')}">...</div>
</div>
</li>

First element of a ng-repeat imbrication

AngularJS
How can i get first element and add class 'active' automatically .
There is 2 ng-repeat , I want get first group --> first item --> first element and add class.
<div class="first" ng-repeat="group in group ">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': selectedGame.id === prematchGame.id}"></div>
</div>
</div>
You can do like this:
<div ng-class='{active:$first}' > {{item.data}}</div>
If you want to make active only the first element of the first ng-repeat, then try:
<div class="first" ng-repeat="group in groups">
<div class="second" ng-repeat="item in items">
<div ng-class='{active: $first && $parent.$first}'>{{item.data}}</div>
</div>
</div>
Demo on JSFiddle
simple way if all you want is first element
<div class="first" ng-repeat="group in group">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': $index == 1}" ></div>
</div>
</div>
you can do same for other ng-repeat all will have different $index
Use $first to do check for the first element of ng-repeat : Fiddle
<div class="first" ng-repeat="group in group" ng-init="firstGroup = $first">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': selectedGame.id === prematchGame.id}" ng-class='{active: $first && firstGroup}'></div>
</div>
</div>

AngularJS: Hide li element when it's clicked

I have a html code:
<div class="col-xs-6">
<ul class="list-group itemList">
<li class="list-group-item" ng-repeat="(id, product) in drinks" ng-click="addToShoppingList(id)">
<strong>{{ product.name }}</strong> - {{ product.price | currency }}
</li>
</ul>
</div>
And the Angular code:
$scope.addToShoppingList = function(id){
};
I just want the id element to disappear (hide, fadeOut etc), when it's clicked. I bet it's something about the ng-hide but for now I'm too dumby for that.
Thanks for any answers.
Edit: It should be inside the addToShoppingList function.
Edit2: This is the whole function:
$scope.addToShoppingList = function(id){
$scope.itemsToBuy.push($scope.drinks[id]);
};
When the li element is clicked, it pushes that element to the new array. And then it should be hidden.
Edit3: If I want to cancel it and make the items come back to the array, the result is strange.
You could do something like this:
<div ng-controller="MyCtrl2">
<h2>Hide each LI:</h2>
<ul>
<li ng-click="pushItem(suggestion)" ng-repeat="suggestion in results" ng-click="visible = false">
{{suggestion}}
</li>
</ul>
</div>
Below is the angular code:
var myApp = angular.module('myApp',[]);
function MyCtrl2($scope) {
$scope.results = [1, 2, 3, 4];
$scope.itemsToBuy = [];
$scope.pushItem = function(item){
$scope.itemsToBuy.push(item);
$scope.results.splice($scope.results.indexOf(item),1);
}
}
JS Fiddle on the same:
http://jsfiddle.net/59gdo817/
On the vice-versa, just add the item back to results array to show the li back.
You can add a new status to the $scope.drinks array called isHidden which will track whether or not the item is hidden. When the user clicks on that li, the function will set isHidden to true and the ng-hide will immediately cause it to hide from the DOM.
<div class="col-xs-6">
<ul class="list-group itemList">
<li class="list-group-item" ng-repeat="(id, product) in drinks" ng-click="addToShoppingList(id)" ng-hide="product.isHidden===true">
<strong>{{ product.name }}</strong> - {{ product.price | currency }}
</li>
</ul>
</div>
$scope.addToShoppingList = function(id){
$scope.itemsToBuy.push($scope.drinks[id]);
$scope.drinks[id].isHidden = true;
};
How about this:
<div class="col-xs-6">
<ul class="list-group itemList">
<li class="list-group-item" ng-repeat="(id, product) in drinks" ng-click="addToShoppingList(id);" ng-hide='product.hidden'>
<strong>{{ product.name }}</strong> - {{ product.price | currency }}
</li>
</ul>
</div>
And in your addToShoppingList, you can set the product to hidden:
$scope.addToShoppingList = function(id){
$scope.itemsToBuy.push($scope.drinks[id]);
$scope.drinks[id].hidden = true;
};

AngularJS- how to change value of dynamic model

I want to change {{order.status}} to def when someone click updatestatus button.
<ul>
<li ng-repeat="order in orders">
<!--
<div ng-model="row[order.id]" >abc</div>
-->
<div ng-model="row[order.id]" >{{order.status}}</div>
updatestatus
</li>
</ul>
Controller
$scope.row = {};
$scope.changestatus = function(id) {
//console.log(id);
$scope.row[id] = 'def';
}
It does not work. Please help.
You don't need ng-model here. ng-model is used for inputs, textarea, select or custom form elements https://docs.angularjs.org/api/ng/directive/ngModel
<ul>
<li ng-repeat="order in orders">
<div>{{ row[order.id] }}</div>
updatestatus
</li>
</ul>
Here, you just need to update the view. For this ng-bind is used https://docs.angularjs.org/api/ng/directive/ngBind
<div> ng-bind="row[order.id]"></div> and <div>{{ row[order.id] }}</div> are similar
UPDATE
<ul>
<li ng-repeat="order in orders">
<div>{{ order.status }}</div>
Update Status
</li>
</ul>
Controller:
$scope.changestatus = function(order) {
//console.log(order.id);
order.status = 'the update status'; // status changed
}
Use {{row[order.id]}} instead of abc in your view and remove ng-model within your div.
<ul>
<li ng-repeat="order in orders">
<div>{{ row[order.id] }}</div>
updatestatus
</li>
</ul>
Or
<ul>
<li ng-repeat="order in orders">
<div ng-bind="row[order.id]"></div>
updatestatus
</li>
</ul>

$index restart each row in ng-repeat

I want to repeat this code for each element in my array:
<div class="container" ng-init="parentIndex = $index" ng-repeat="urn in apsocket.mensajes | filter:searchTextURN">
<button style="width:100%" type="button" class="btn btn-info" data-toggle="collapse" data-target="{{'#urn_'+$index}}">{{urn.urn }}</button>
<div id="{{'urn_'+$index}}" class="collapse">
{{urn.timestamp}}
<br>
<p>
<div align="right" ng-repeat="meas in urn.measurements track by $index">
<button style="width:90%;background-color: #68ec6a;border-color:#8bf48c;" type="button" class="btn btn-success" data-toggle="collapse" data-target="{{'#meas_'+parentIndex + '_' +$index}}">{{meas.phenomenon}} </button>
<div style="width:90%" id="{{'meas_'+parentIndex + '_' +$index}}" class="collapse">
{{meas.value + ' ' + meas.uom}}
</div>
</div>
</p>
</div>
</div>
But, while first button in each row works fine and creates a working collapsible, the inner ng-repeats seem not.
Each inner element in each outter row, have the same id. So, for each "container", parentIndex is the same and starts in 0.
What should I do in this case? This is not a fixed array which I load at the beggining. This array recevies data from socket and it get bigger each time a message is received.
If you need any more code or so, just ask.
I would recommend just using the pure angular way. In a repeat, each item has it's own scope so you can do an ng-click="collapse = ! collapse" (something like that), I made you an example here
http://jsfiddle.net/X8era/82/
I just made a fake data structure for examples sake
<ul>
<li ng-repeat="item in objs" ng-click="collapse = ! collapse">
{{item.id}}
<ul ng-show="item.more.length > 0 && collapse">
<li ng-repeat="child in item.more" ng-click="collapse = ! collapse; $event.stopPropagation();" >
{{child.id}}
<ul ng-show="child.more.length > 0 && collapse">
<li ng-repeat="baby in child.more">
{{baby.id}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
If you would like to use the collapse class for an animation or whatever, you can change the part of the ng-show that is collapse to
ng-class="{ 'collapse' : collapse }"
The first 'collapse' being whatever class you want to be toggled.
You don't have to use ng-init="parentIndex = $index". You can access to parent $index like this $parent.$index.
Each ng-repeat creates new scope, that's why you can access to parent by using $parent keyword.
Demo:
var app = angular.module('app',[]);
app.controller('ctrl', function($scope) {
$scope.items = [0, 1, 2, 3, 4];
});
<div ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="item in items track by $index">
<ul>
<li ng-repeat="item in items track by $index">
parent: {{$parent.$index}}
current: {{$index}}
</li>
</ul>
</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Resources