I am using a *ngFor loop but I only want the loop to run on particular indexes defined in an array (i.e. indexArray = [454,640]).
If I try this, and the indexArray has two or more elements, it does not work. But If the array has only one element (i.e. indexArray=[565]) it works.
<div *ngFor="let item of items; index as i">
<table *ngIf="i == indexArray">
You can use .indexOf(i) and check whether it is in your indexArray variable.
<div *ngFor="let item of items; index as i">
<table *ngIf="indexArray.indexOf(i)> -1">
<!-- REST OF THE CODE -->
You can do the following:
<div *ngFor="let item of items; index as i">
<table *ngIf="indexArray.includes(i)">
enter code here...
</table>
</div>
Here is a working example
create index array like this
public indexArray: array = [454,640];
do like below.
<div *ngFor="let item of items; index as i">
<table *ngIf="indexArray.indexOf(i)> -1">
enter code here...
</table>
</div>
let me know if you have any doubt.
Related
Here is my element
<div *ngFor="let item of items |xxxx ; let l = count "> <div>
<!--use {{l}} in other element-->
How can I get the value of {{ l }} to use it outside this div or to use it in component.ts after filter directly?
Wrap your template in <ng-container>. Like this:
<ng-container *ngFor="let item of items |xxxx ; let l = count ">
<div ><div>
<!--use {{l}} in other element-->
</ng-container>
I'm dynamically loading templates which is working fine. Now my concern is I need to add a JavaScript logic to template
I need to use something like this in my template.
{{ var entries = 0; }}
{{ for(var r = 0; r < d; r++) }}
Suppose my template returns this HTML
<div ng-repeat="x in names" ><span>{{x.name}}</span>{{some logic here which is plain js. var a=[] if(a=b){}}}</div>
My question is how to achieve this.
<div ng-repeat="entry in entries track by $index">
{{entry}},{{$index}}
</div>
Use ng-repeat.
<div ng-repeat="entry in entries">
{{entry}}
</div>
If you need the index:
<div ng-repeat="entry in entries">
{{entry}},{{$index}}
</div>
Docs: https://docs.angularjs.org/api/ng/directive/ngRepeat
<div ng-init="entries[0,1,2,3,4]">//Use ng-int to initialize data
<div ng-repeat="data in entries">// use ng-repeat to loop over
{{data}}
</div>
</div>
I'm trying to show an alert in case a filtered and limited list has elements not being shown. I'm looking for a good performing solution, as these lists will be really long.
Here is what I have from now:
<div class="list_item" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter | limitTo: 6 as results track by $index">
<label ng-click="$ctrl.handle_list_click()">
<input type="checkbox" ng-model="item.checked">
<div class="fake_label" >
{{item.name}}
</div>
</label>
</div>
<div class="list_item too_many"
ng-repeat-end
ng-if="results.length > 6">
<div class="fake_label">
{{results.length}} matches... Please, filter out.
</div>
</div>
But the results contains the elements after being filtered and also limited. If I move the as results just before the limitTo, it just breaks.
The condition I want to detect show the alert would be: if the limited list's length and the filtered list's length are different, then show the alert.
I don't mind using something else, instead of the as results, just wonder if there is a way to detect that condition.
Edit: the problem right now is that results.length gives me the amount of elements after applying the limit, while what I need is the amount just after the filter, but before the limit. I know how to do this by deleting the limitTo sentence, but then there are too many results on the list...
var newapp = angular.module('someapp',[]);
newapp.service('limitcheck', [function(){
return {
checkLimit : function (arr) {
if (arr.length > 6) {
alert('The array has more than 6 entries');
}
}
};
}]);
newapp.filter('dummyfilter',['limitcheck',function(limitcheck){
return function (input) {
//do your filtering here
limitcheck.checkLimit(input);
return input;
}
}]);
newapp.controller('something', ['$scope',function(scope){
//This will trigger alert since it contains more than 6 entries
scope.alist = ['me','you','someone','anyone', 'noone','everyone','villain'];
//this will not
//scope.alist = ['me','you','someone','anyone', 'noone','everyone'];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='someapp'>
<div ng-controller='something'>
<div ng-repeat='person in alist | dummyfilter | limitTo :6'>
{{person}}
</div>
</div>
</div>
I have tried and achieved the result by using a service and a filter combination
I hope this helps
The easiest way is to duplicate the repeat and use it to count the filtered elements. At first, I expected this to be quite slow but I'm really surprised of how fast it runs, probably because there is not really much DOM manipulation.
<div class="list_item" ng-if="false" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter as count track by $index">
</div>
<div class="list_item" ng-repeat="item in $ctrl.list | filter: $ctrl.responsiveFilter | limitTo: 6 as results track by $index">
<label ng-click="$ctrl.handle_list_click()">
<input type="checkbox" ng-model="item.checked">
<div class="fake_label" >
{{item.name}}
</div>
</label>
</div>
<div class="list_item too_many"
ng-repeat-end
ng-if="count.length > results.length">
<div class="fake_label">
{{count.length}} matches... Please, filter out.
</div>
</div>
This way you have an ng-if hidden loop to count the filtered elements and another one to count and paint the limited list. All you have to do is to use these data to create the condition.
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...
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