Can I set `ng-repeat` object as `model` to share the details? - angularjs

I am using ng-repeat to display a property of an array. and i need further details to share with other elements to from this array. but the element not nested inside of the ng-repeat.
In this case is it possible to set the array object as a model to share the details to other elements?
here is my code :
<ul>
<li ng-click="activate(item)" ng-model="item" ng-repeat="item in items" ng-class="{active : active == item}">
<span ng-if="item == active">
<span>{{item.name}}</span>
<!-- when active nested under span -->
</span>
<!-- else without nesting the span -->
<span ng-if="item !== active">{{item.name}}</span>
</li>
</ul>
<h1>{{item.age}}</h1> //i am trying to fetch model info here

You can make ng-click set the item to a scope variable:
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.items = [{
name: 'a',
age: 12
}, {
name: 'b',
age: 15
}];
$scope.activate = function(item) {
$scope.active = item;
};
});
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app='app' ng-controller='myController'>
<ul>
<li ng-click="activate(item)" ng-repeat="item in items" ng-class="{active : active == item}">
<span ng-if="item == active">
<span>{{item.name}}</span>
<!-- when active nested under span -->
</span>
<!-- else without nesting the span -->
<span ng-if="item !== active">{{item.name}}</span>
</li>
</ul>
<h1>{{active.age}}</h1>
</div>

Related

how to implement show more in <li> with angularjs ng-repeat directive?

How Do I hide the list data if the list is greater than 3? and a show more button that will show the whole list when it's clicked?
Here is my current code, i do not know how to implement the show more when the ng-repeat directive is inside the li tag.
<ul>
<li ng-repeat="data in datas">
<div>data</div>
</li>
</ul>
How about this?
var app = angular.module("App", []);
app.controller("Ctrl", [function () {
var ctrl = this;
ctrl.items = ["Item1", "Item2", "Item3", "Item4", "Item5", "item6"]
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="App" ng-controller="Ctrl as ctrl">
<ul ng-init="limit = 3">
<li ng-repeat="item in ctrl.items | limitTo: limit as results">{{item}}</li>
</ul>
<button ng-hide="results.length === ctrl.items.length"
ng-click="limit = limit +2">show more...</button>
</div>

Angular show hide toggle on ng-repeat

I have this ngRepeat. I want to create some sort of toggle, so that when the user clicks on the button, the input shows, however, I want all other shown inputs to hide (if they are already visible).
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!showMe">text here</span>
<input ng-show="showMe">
<button ng-click="showMe = true"></button>
</li>
</ul>
Hope this makes sense.
ng-repeat has isolated scope, that is why to influence all other inputs you need to track their visibility via variable from parent scope. I've prepeared a fiddle with example: http://jsfiddle.net/ancvgc1b/
angular
.module('myApp', ['ui.bootstrap'])
.controller('ExampleController', function($scope){
$scope.jewel = {
key1: 'Foo',
key2: 'Bar'
};
$scope.visible = { key: 'key1' };
$scope.setVisible = function(key) {
$scope.visible.key = key;
}
});
<body ng-app="myApp">
<div ng-controller='ExampleController'>
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!(visible.key == key)">Text value</span>
<input ng-show="visible.key == key">
<button ng-click="setVisible(key)">show input</button>
</li>
</ul>
</div>
</body>
Quick fix:
<ul ng-init="active={}">
<li ng-repeat="(key, value) in jewel">
<span ng-show="!($index==active.index)">text here</span>
<input ng-show="$index==active.index">
<button ng-click="active.index = $index"></button>
</li>
</ul>
If you are using controllerAs, it leads to much cleaner code as follows:
(vm is your alias to controller)
<ul>
<li ng-repeat="(key, value) in jewel">
<span ng-show="!($index==vm.activeIndex)">text here</span>
<input ng-show="$index==vm.activeIndex">
<button ng-click="vm.activeIndex = $index"></button>
</li>
</ul>
Try this :
var app = angular.module('myApp', []);
app.controller('MyCtrl',function($scope) {
$scope.people = [
{
id: 1,
name: "Alpha",
age: "24",
clicked : false
},
{
id: 2,
name: "Beta",
age: "25",
clicked : false
}
];
$scope.showInput = function(person,index) {
person.input = true;
$scope.index = index;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul>
<li ng-repeat="person in people">
<span ng-show="(!person.input && (index != $index))">text here</span>
<input ng-show="(person.input && (index == $index))">
<button ng-click="showInput(person,$index)">Show Input</button>
</li>
</ul>
</div>

How to change clicked item glyphicon

am binding list of products from database in my page with icon,
initially am showing glyphicon off for all items , when i click list item am changing clicked item glyphicon to ok,
but if i select any other item in list first item glyphicon changing to ok , i want to change icon of clicked item
my code is
view
<div class="collapse navbar-collapse " id="myNavbar">
<ul class="nav navbar-nav">
<li ng-repeat="prod in products">
{{prod.PRODCTNAME}}<span id="iProduct" class="glyphicon glyphicon-off ChangeButtonColorOrangeRed"></span>
</li>
</ul>
</div>
js
$scope.getModules = function (event) {
var prodID = event.target.id;
var productElement = angular.element(document.querySelector('#iProduct'));
productElement.toggleClass('glyphicon glyphicon-off ChangeButtonColorOrangeRed').toggleClass('glyphicon glyphicon-ok ChangeButtonColorGreen');
var moduleDiv = angular.element(document.querySelector('#divModule'));
moduleDiv.toggleClass('divProductsHide').toggleClass('divProductsShow');
productService.getModules(prodID).then(function (d) {
$scope.modules = d.data;
}, function (error) {
alert('Error!');
});
};
css
<style>
.ChangeButtonColorOrangeRed {
color: orangered;
}
.ChangeButtonColorGreen {
color: green;
}
You can also get selected Item by using this example below.Plunker here
HTML
<body data-ng-controller="myController">
<div class="collapse navbar-collapse " id="myNavbar">
<ul class="nav navbar-nav">
<li ng-repeat="prod in products">
<a href="#" class="productClass" ng-click="selectProduct(prod.id)">{{prod.name}}
<span data-ng-hide="selectedProducts.indexOf(prod.id) > -1" class="glyphicon glyphicon-off ChangeButtonColorOrangeRed"></span>
<span data-ng-show="selectedProducts.indexOf(prod.id) > -1" class="glyphicon glyphicon-ok ChangeButtonColorGreen"></span>
</a>
</li>
</ul>
</div>
</body>
JS
angular.module("myApp",[]);
angular.module("myApp").controller("myController",function($scope){
$scope.products = [
{id:1,name:'A'},
{id:2,name:'B'},
{id:3,name:'C'}
];
$scope.selectedProducts = [];
$scope.selectProduct = function(id){
var index = $scope.selectedProducts.indexOf(id);
if(index > -1){
$scope.selectedProducts.splice(index,1);
}else{
$scope.selectedProducts.push(id);
}
}
})
Update
Change this function for selecting only one product
$scope.selectProduct = function(id){
$scope.selectedProducts= [id];
}
You can use ng-class to solve this problem.
<div class="collapse navbar-collapse " id="myNavbar">
<ul class="nav navbar-nav">
<li ng-repeat="prod in products" ng-init="off=false">
{{prod.PRODCTNAME}}<span id="iProduct" ng-class="off?'change-button-to-green':'change-button-to-red'"></span>
</li>
</ul>
</div>
CSS:
.change-button-to-red {
color: orangered;
}
.change-button-to-green {
color: green;
}
This will solve problem.
Issue is in selection:
var productElement = angular.element(document.querySelector('#iProduct'));
You are selecting value with id '#iProduct'. So query selector pick the first match and change the class of the first span.
So, provide dynamic id to span also.
I added a fiddle for this:
https://jsfiddle.net/ranageneration/s5ua3fed/

$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>

NgRepeat on switch case

I'm using angular include to insert the html's in the page and below is the code for it.
RightNav.html
<div ng-switch on="page">
<div ng-switch-when="Games">
<div ng-include="'Games.html'"></div>
</div>
<div ng-switch-when="Music">
<div ng-include="'Music.html'"></div>
</div>
<div ng-switch-when="Videos">
<div ng-include="'Videos.html'"></div>
</div>
</div>
LeftNav.html
<ul>
<li ng-repeat="item in items">
{{item.name}}
</li>
</ul>
JS
app.controller('Nav', function($scope) {
$scope.items = [
{
name : 'Music'
},
{
name : 'Videos'
},
{
name : 'Games'
}
];
$scope.page = $scope.items[0].name;
$scope.selectedItem = function(item) {
$scope.page = item.name;
}
})
I tried using ng-repeat in RightNav.html and it doesn't work what am i doing wrong here?
<div ng-switch on="page">
<div ng-repeat="item in items">
<div class="item.name" ng-switch-when="{{item.name}}">
<div ng-include="'{{item.name}}.html'"></div>
</div>
</div>
</div>
Demo : http://plnkr.co/edit/D1tMRpxVzn51g18Adnp8?p=preview
In your case you do not need ng-repeat. You can directly bind the expression to ng-include. Also when i tried ng-switch when part does not take expression. Also using the . notation for selected page as the ng-switch and ng-include creates new scope.
See my fiddle
http://plnkr.co/edit/dPILzsyFoWHfL3Urlso2?p=preview

Resources