How to iterate an object with a specific key in angularjs? - javascript

I want to list an item inside a specific key using a filter. Now listing like this.
Sanal
Jin
John
Tim
Jeff
Sam
John
Tim
I want like this using a filterJeffSam
Here is the Fiddle
function testCtrl($scope) {
$scope.items = {"id":"B716","day":8,"di":{"type":"normal","one":[{"name":"Sanal","age":"18"},{"name":"Jin","age":"25"}],"two":[{"name":"Jeff","age":"55"},{"name":"Sam","age":"32"}],"three":[{"name":"John","age":"34"},{"name":"Tim","age":"39"}]}};
}
<div ng-app="" ng-controller="testCtrl">
<ul>
<li ng-repeat="val in items.di">
<ul>
<li ng-repeat="value in val">{{value.name}}</li>
</ul>
</li>
</ul>
</div>

in your ng repeat change it as
<li ng-repeat="value in val | filter: val.name='jeff'">{{value.name}}</li>
I have used name you can use the value that you want ot test

Related

ng-repeat on array based on length of second array

I am trying to iterate over an array using ng-repeat to display in a list. The number of records to display should be equal to the length of a second array.
<ul>
<li ng-repeat="item in firstArray"></li>
</ul>
var firstArray = ["a","b","c","d","e","f"]
var secondArray = ["x","y","z"]
The expected result for the above example :
var output = ["a","b","c"]
Since the length of secondArray is 3, the number of li elements would be 3 with the first three values from firstArray.
Should i use filter? I am using angularjs.
Thanks
The simplest solution is to use limitTo
<ul>
<li ng-repeat="item in firstArray | limitTo:secondArray.length">{{item}}</li>
</ul>
http://plnkr.co/edit/LWh1uqNPxTy09u3MP677?p=preview
<ul>
<li ng-repeat="item in firstArray" ng-if=" $index < secondArray.length "></li>
</ul>
Use the above code, it will work
You can use AngularJs filter limitTo in ng-repeat. Refer to the below example:
At angular application side:
var app = angular.module('sampleapp', [])
app.controller('samplecontrol', function ($scope) {
$scope.firstArray = ["a","b","c","d","e","f"]
$scope.secondArray = ["x","y","z"]
});
In your view:
<ul>
<li ng-repeat="item in firstArray | limitTo:secondArray.length">{{item}}</li>
</ul>
Maybe you should use $index to test if it has to be displayed :
<ul >
<li ng-repeat="item in firstArray" ng-if="$index < secondArray.length()" > </li>
</ul>
Just loop over your second array and access the items of the first array using firstArray[$index].
angular.module('myApp', [])
.controller('myCtrl', function ($scope) {
$scope.firstArray = ["a","b","c","d","e","f"];
$scope.secondArray = ["x","y","z"];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="i in secondArray">
{{firstArray[$index]}}
</li>
</ul>
</div>
</div>

Filter matched elements by class name in Angular js.

Problem:
I have an unordered list of items which are returned from a json call and are output using ng-repeat. Each one of these items has a class name (there are about 9 categories).
I have a second unordered list which is simply a list of available categories.
Aim:
I want to be able to select one of the categories in the right hand list, which will apply a filter to the actual list of returned elements. This should be activated via a toggle (so click once: filtered, click again: filter removed). So it is simply looking to match the classname in the clicked element, to the elements that share the same classname in the list of json data.
I cannot use ng-model (as this is reserved for certain form elements).
For my jsfiddle I am simply using static html.
Here is my angular code:
/* angular custom filter on returned ajax api data */
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.chFilters = {};
$scope.links = [
{name: 'atm'},
{name: 'internet'},
{name: 'mobile'},
{name: 'sms'},
{name: 'postal'}
];
$scope.channels = ["ATM", "INTERNET", "SMS", "POSTAL","MOBILE"];
});
(this is based on another question I found on SO). Unfortunately the fiddle is a bit messy and has some extraneous code in it.
HTML:
<div ng-app="app">
<div ng-controller="main">
<ul>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="sms">Some stuff ATM</li>
<li class="atm">Some stuff ATM</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="postal">Some stuff POSTAL</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="sms">Some stuff SMS</li>
<li class="mobile">Some stuff MOBILE</li>
<li class="internet">Some stuff INTERNET</li>
<li class="mobile">Some stuff MOBILE</li>
</ul>
<ul class="channel-filters">
<li ng-repeat="link in links | filter:chFilters" class="{{link.name | lowercase}}"><a ng-click="chFilters.name = link.name">{{link.name | uppercase}}</a></li>
<li class="last" ng-click="chFilters.name = ''">CLEAR FILTER</li>
</ul>
<ul>
<li ng-repeat="channel in channels | filter:chFilters">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
</div>
</div>
This is the actual HTML from the application (with the call to the api).
<ul class="accordion">
<li class="search-text-channel">
<input type="textarea" ng-model="searchTextChannel.$" placeholder="Search"/>
</li>
<li ng-repeat="day in interactions.model.byDay | filter:searchTextChannel" ng-click="hidden = !hidden" ng-init="hidden = false" class="{{day.channel | removeSpace | lowercase}}" ng-class="{'closed': !hidden, 'open': hidden}">
<span class="date">{{day.date}}</span>
<span class="subheading">{{day.channel}}</span>
<ul ng-show="hidden">
<li ng-repeat="interaction in day.interactions">
{{interaction.time}} {{interaction.description | removeUnderscore}}
</li>
</ul>
</li>
<li class="load-more">
<i class="fa fa-plus"></i>LOAD MORE
</li>
</ul>
I have managed to recreate this functionality in jquery, but I think it would be better to implement an angular solution in an angular application.
I've tried researching and also attempted to implement show/hide as well as a custom filter, but so far no joy.
Here is my (messy) jsfiddle
<ul>
<li ng-repeat="channel in channels | filter:chFilters.name">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters.name">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
Update Plunker
Let me know if you have any question on this.
Here is part of the solution:
Suppose your items look like this:
$scope.items = [
{ class: "atm", label: "Some stuff ATM" },
{ class: "internet", label: "Some stuff INTERNET" },
{ class: "sms", label: "Some stuff SMS" },
{ class: "postal", label: "Some stuff POSTAL" },
...
];
To show a filtered list (only filtering by a single channel for now): create a separate list in the scope, with the filters applied:
$scope.click = function(name) {
$scope.chFilters.name = name;
$scope.filteredItems = $scope.items.filter(function(item) {
return item.class === $scope.chFilters.name;
});
};
Call this click handler from the bottom list:
...<a ng-click="click(link.name)">{{link.name | uppercase}}</a>....
And show filteredItems in the top list:
<ul>
<li ng-repeat="item in filteredItems" ng-class="item.class">{{item.label}}</li>
</ul>
So this is really just a starting point, it should be extended to handle multiple filters, etc...

select one item in one time in angularjs

I am trying to select one item on one time in angularJS.
Here is my code
<div ng-repeat="list in listgroups" >
<ul ng-init="selected = -1">
<li ng-repeat="item in list" ng-class="{active:(selected == $index)}" ng-click="selected = $index;">{{item}} </li>
</ul>
</div>
Regards
Nauman
ng-repeat creates new scope from current scope, so If you are using selected inside a inner ng-repeat will cause to create new scope variable for inner ng-repeat.
If you want to refer the parent scope from ng-repeat then use $parent.selected that will refer the outer scope variable of ng-repeat.
HTML
<div ng-repeat="list in listgroups" ng-init="selected = -1">
<b>List {{$index + 1}}</b>
<ul>
<li ng-repeat="item in list" ng-class="{active:($parent.selected == $index)}"
ng-click="$parent.selected = $index;">
{{item}}
</li>
</ul>
</div>
Working Fiddle
For more information here is link

AngularJS - ngRepeat with multiple object types

I have a list of items. An item can be a number of things, let's say the list is something like so :
[userObject , vehicleObject , userObject , animalObject , animalObject]
Now I want to render the list with ngRepeat directive that will use a template according to the type of the object (Polymorphic rendering). can this be done?
maybe something like (ng-use is an hypothetically directive):
<ul>
<li ng-repeat="item in items">
<img ng-use="item.type == 'user'" ng-src="item.src">
<a ng-use="item.type == 'vehicle'">{{item.link}}</a>
<span ng-use="item.type == 'animal'">{{item.name}}</span>
</li>
</ul>
<ul>
<li ng-repeat="item in items" ng-switch="item.type">
<img ng-switch-when="user" ng-src="item.src">
<a ng-switch-when="vehicle">{{item.link}}</a>
<span ng-switch-when="animal">{{item.name}}</span>
</li>
</ul>
API reference:
http://docs.angularjs.org/api/ng.directive:ngSwitch
Although this doesn't use ng-switch, it does get round the problem of not having a type field, which #DotNetHaggis pointed out.
<div ng-repeat="field in fields">
<div ng-if="field.user !== undefined">user info</div>
<div ng-if="field.vehicle !== undefined">vehicle info</div>
<div ng-if="field.animal !== undefined">animal info</div>
</div>

AngularJS ng-repeat handle empty list case

I thought this would be a very common thing, but I couldn't find how to handle it in AngularJS. Let's say I have a list of events and want to output them with AngularJS, then that's pretty easy:
<ul>
<li ng-repeat="event in events">{{event.title}}</li>
</ul>
But how do I handle the case when the list is empty? I want to have a message box in place where the list is with something like "No events" or similar. The only thing that would come close is the ng-switch with events.length (how do I check if empty when an object and not an array?), but is that really the only option I have?
You can use ngShow.
<li ng-show="!events.length">No events</li>
See example.
Or you can use ngHide
<li ng-hide="events.length">No events</li>
See example.
For object you can test Object.keys.
And if you want to use this with a filtered list here's a neat trick:
<ul>
<li ng-repeat="item in filteredItems = (items | filter:keyword)">
...
</li>
</ul>
<div ng-hide="filteredItems.length">No items found</div>
You might want to check out the angular-ui directive ui-if if you just want to remove the ul from the DOM when the list is empty:
<ul ui-if="!!events.length">
<li ng-repeat="event in events">{{event.title}}</li>
</ul>
With the newer versions of angularjs the correct answer to this question is to use ng-if:
<ul>
<li ng-if="list.length === 0">( No items in this list yet! )</li>
<li ng-repeat="item in list">{{ item }}</li>
</ul>
This solution will not flicker when the list is about to download either because the list has to be defined and with a length of 0 for the message to display.
Here is a plunker to show it in use: http://plnkr.co/edit/in7ha1wTlpuVgamiOblS?p=preview
Tip: You can also show a loading text or spinner:
<li ng-if="!list">( Loading... )</li>
<ul>
<li ng-repeat="item in items | filter:keyword as filteredItems">
...
</li>
<li ng-if="filteredItems.length===0">
No items found
</li>
</ul>
This is similar to #Konrad 'ktoso' Malawski but slightly easier to remember.
Tested with Angular 1.4
Here's a different approach using CSS instead of JavaScript/AngularJS.
CSS:
.emptymsg {
display: list-item;
}
li + .emptymsg {
display: none;
}
Markup:
<ul>
<li ng-repeat="item in filteredItems"> ... </li>
<li class="emptymsg">No items found</li>
</ul>
If the list is empty, <li ng-repeat="item in filteredItems">, etc. will get commented out and will become a comment instead of a li element.
You can use this ng-switch:
<div ng-app ng-controller="friendsCtrl">
<label>Search: </label><input ng-model="searchText" type="text">
<div ng-init="filtered = (friends | filter:searchText)">
<h3>'Found '{{(friends | filter:searchText).length}} friends</h3>
<div ng-switch="(friends | filter:searchText).length">
<span class="ng-empty" ng-switch-when="0">No friends</span>
<table ng-switch-default>
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="friend in friends | filter:searchText">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
</tr>
</tbody>
</table>
</div>
You can use as keyword to refer a collection under a ng-repeat element:
<table>
<tr ng-repeat="task in tasks | filter:category | filter:query as res">
<td>{{task.id}}</td>
<td>{{task.description}}</td>
</tr>
<tr ng-if="res.length === 0">
<td colspan="2">no results</td>
</tr>
</table>
i usually use ng-show
<li ng-show="variable.length"></li>
where variable you define for example
<div class="list-group-item" ng-repeat="product in store.products">
<li ng-show="product.length">show something</li>
</div>
you can use ng-if because this is not render in html page and you dont see your html tag in inspect...
<ul ng-repeat="item in items" ng-if="items.length > 0">
<li>{{item}}<li>
</ul>
<div class="alert alert-info">there is no items!</div>

Categories