Loop to visible items in ng-repeat - javascript

It is possible to loop to the visible items in a ng-repeat?
I have a ng-repeat with multiple filters and I want to create a 'select all' function to select all the visible items in the repeat.
How can I get the visible items? The selection may be come undone when the filter is changing, so there are no 'old' selections possible, but that can be easily done to loop all items with no conditional.
<div class="item" ng-repeat='item in collection | product_sex:filter_sex | product_stock: stockKind | filter:productFilter'>
{{item.name}}
{{item.price}}
</div>

you can add a filter like this;
<div ng-repeat="item in items | filter:{visible: true} ">
<p>{{item.id}}</p>
</div>

You could define a variable that represents all visible items by using as expression with a ng-repeat directive:
<div class="item"
ng-repeat='item in (collection | product_sex:filter_sex | product_stock: stockKind | filter:productFilter) as allVisibleItems'>
{{item.name}}
{{item.price}}
</div>
You could access this variable easily, right underneath ng-repeat for example:
<div ng-click="selectAll(allVisibleItems)">Select all Items</div>
More can be read here: https://docs.angularjs.org/api/ng/directive/ngRepeat

Related

If all array items are hidden show another div in AngularJS

I'm using ng-repeat on my page. ng-class working very well.
<div class="card news" ng-repeat="item in news track by $index" id="{{news.nid}}" ng-init="parentIndex = $index" ng-class="{hidden: '{{getCheck($index)}}' == 'true'}">
...
</div>
Now I need, if all items are hidden, show this div:
<h3 class="news-empty">No news</h3>
Whats the rules? How can I do it? Thanks.
You need another method that checks if all elements are hidden:
$scope.everythingIsHidden = function() {
return $scope.news.every((new, index) => $scope.getCheck(index));
}
$scope.getCheck = function(index) { // Your getChek function that I suppose it checks if an element is hidden based on index
//...
}
<h3 class="news-empty" ng-if="everythingIsHidden()">No news</h3>
TheCog's answer will work. If you want to do this in a more 'Angular' way you're going to need to refactor what you have.
You shouldn't be trying to hide them with a CSS class. ngRepeats have a built in filter syntax. So, you should be filtering them out.
<div class="card news"
ng-repeat="item in news | filterMethod as results track by $index"
id="{{news.nid}}"
ng-init="parentIndex = $index"
>
<h3 class="news-empty" ng-if="results.length === 0" >No news</h3>
The as results statement in the repeat will store the filtered array in results. filterMethodneeds to be an angular filter and it will probably work similarly to your getCheck($index) method.
You want to add an ngShow to the h3 tag, and aim it at a function you write in your controller that checks if the array is empty, probably by iterating over the same array that's hidden and running getCheck($index) on each.

Add a counter to Angular ng-repeat?

I am trying to find some documentation for being able to append a counted number to each item returned by an ng-repeat. Is this not an out of a box thing for Angular? Not quite like an Id, but more like, if 4 items returned, each item JSON object could add a number in front of data returned. My code looks like:
<div class="swipeBoxes" ng-repeat="swipe in swipes">
<a href="#">
<div class="swipeBox">
<span class="swipeNum"></span>
<p><span>swipe date:</span><span>{{ swipe.date | date: 'MM/dd/yyyy'}}</span></p>
<p><span>provider:</span><span>{{ swipe.merchant }}</span></p>
<p><span>amount:</span><span>{{ swipe.amount | currency }}</span></p>
</div>
</a>
</div>
You can use $index for your counter.
<div class="swipeBoxes" ng-repeat="swipe in swipes">
{{$index + 1}}
</div>
Using $index from ngRepeat should be able to solve your problems.

using ngIf with ngRepeat

Hi i am trying to use two types of ng-repeat statements based on the codition using ng-if. Somehow it is not working.
Code:
<div ng-if="orderby === '0'">
<div ng-repeat="user in users | filter:search"></div>
</div>
<div ng-if="orderby === '1'">
<div ng-repeat="user in users | filter:search| orderBy:'-timestamp'"></div>
</div>
I have two controller, they are using the same template. In one template i set the value of $scope.orderby = '0' . In this template i want to use ng-repeat without orderBy and vice versa.
This isn't working out. Is there other way of doing this type of functionality?
Create object : someObjectName.orderby instead of primitive variable orderby.
And your binding will be:
<div ng-if="someObjectName.orderby === '0'">
<div ng-repeat="user in users | filter:search"></div>
</div>
<div ng-if="someObjectName.orderby === '1'">
<div ng-repeat="user in users | filter:search| orderBy:'-timestamp'"></div>
</div>
ng-repeat have another scope and your orderby variable out of ng-repeat is not same in orderby inside ng-repeat scope.
Read this article for more information about scopes: https://github.com/angular/angular.js/wiki/Understanding-Scopes

Filter inner ng-repeat based on index of outer ng-repeat

I am trying to get the index of parent ng-repeat and in inner ng-repeat filter the data based of that.
Trying to use the below code but it is not working.
<div class="boxStyle" ng-repeat="priorityItem in priorityBox" data-tasktype= '{{$index+1}}' ui-drop-listener='dropListener' data-model='someArrays' > {{priorityItem.name}}
<div ui-draggable ng-repeat="item in someArrays | filter: {tasktype: "+ '{{$parent.$index}}' +" | orderBy: 'priority'" data-index='{{$index}}' data-taskid='{{item.taskid}}' data-priority='{{item.priority}}' class='btn btn-info btn-block'>{{item.name}}
</div>
</div>
Here is a plunker that does the job. It is not pretty because it duplicates the $index in order to make it easily accessible from the inner ng-repeat.
I would introduce a new custom filter to do the job.
This is the line that introduces a new variable which stores the parent index:
<div ng-init="parentIndex = $index"></div>
Good luck.

AngularJS - how to get an ngRepeat filtered result reference

I am using an ng-repeat directive with filter like so:
ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4"
and I can see the rendered results fine; now I want to run some logic on that result in my controller. The question is how can I grab the result items reference?
Update:
Just to clarify: I'm trying to create an auto complete, I have this input:
<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query">
and then the filtered results:
<ul>
<li ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li>
</ul>
now I want to navigate the result and select one of the items.
UPDATE: Here's an easier way than what was there before.
<input ng-model="query">
<div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
{{item}}
</div>
Then $scope.filteredItems is accessible.
Here's the filter version of Andy Joslin's solution.
Update: BREAKING CHANGE. As of version 1.3.0-beta.19 (this commit) filters do not have a context and this will be bound to the global scope. You can either pass the context as an argument or use the new aliasing syntax in ngRepeat, 1.3.0-beta.17+.
// pre 1.3.0-beta.19
yourModule.filter("as", function($parse) {
return function(value, path) {
return $parse(path).assign(this, value);
};
});
// 1.3.0-beta.19+
yourModule.filter("as", function($parse) {
return function(value, context, path) {
return $parse(path).assign(context, value);
};
});
Then in your view
<!-- pre 1.3.0-beta.19 -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:'filteredItems'">
{{item}}
</div>
<!-- 1.3.0-beta.19+ -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:this:'filteredItems'">
{{item}}
</div>
<!-- 1.3.0-beta.17+ ngRepeat aliasing -->
<input ng-model="query">
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 as filteredItems">
{{item}}
</div>
Which gives you access to $scope.filteredItems.
Try something like this, the problem with the ng-repeat is that it creates child scope because of that you can't access
filteritems
from the controller
<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li>
Update:
Even after 1.3.0. if you want to put it on the scope of the controller or the parent you cannot do that with as syntax.
For example if I have the following code:
<div>{{labelResults}}</div>
<li ng-repeat="label in (labels | filter:query | as labelResults)">
</div>
the above will not work.
The way to go around it is using the $parent as so:
<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))">
I came up with a somewhat better version of Andy's solution. In his solution ng-repeat places a watch on the expression that contains the assignment. Each digest loop will evaluate that expression and assign the result to the scope variable.
The problem with this solution is that you might run into assignment issues if you are in a child scope. This is the same reason why you should have a dot in ng-model.
The other thing I don't like about this solution is that it buries the definition of the filtered array somewhere in the view markup. If it is used in multiple places in your view or your controller it can get confusing.
A simpler solution is to just place a watch in your controller on a function that makes the assignment:
$scope.$watch(function () {
$scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4");
});
This function will be evaluated during each digest cycle so performance should be comparable with Andy's solution. You can also add any number of assignments in the function to keep them all in one place rather than scattered about the view.
In the view, you would just use the filtered list directly:
<ul>
<li ng-repeat="item in filteredItems">{{item.name}}</li>
</ul>
Here's a fiddle where this is shown in a more complicated scenario.
Check this answer:
Selecting and accessing items in ng-repeat
<li ng-repeat="item in ..." ng-click="select_item(item)">

Categories

Resources