Reputation: 3514
I have a list of items like:
<ul>
<li ng-repeat="show in data_shows">
<span class="program_shows_show_day">{{show[2]*1000 | amDateFormat:'ddd D MMM'}}</span>
<span class="program_shows_show_time">{{show[2]*1000 | amDateFormat:'H:mm'}} - {{show[3]*1000 | amDateFormat:'H:mm'}}</span>
</li>
</ul>
When there are more than 4 items I would like to show only the first 4 items and hide the rest with a button ('Show all').
With jQuery I would just count the items and if they're over 4 items apply a class to the <ul>
. In Angular it's a bit more difficult- I know ng-repeat produces a $index variable, but I can only use that within the <li>
items right? So what's the best way to apply a class on the <ul>
element?
Upvotes: 0
Views: 5625
Reputation: 48212
You can use Angular's limitTo
filter to originally limit the number of displayed items to 4.
Additonally, you can have 2 buttons (one for showing all items, one for limiting the displayed items to 4) and show/hide them (or disable/enable them) according to the currently displayed items and the total number of items.
E.g.:
// VIEW
<ul>
<li ng-repeat="item in items | limitTo:limit">{{item}}</li>
</ul>
<button ng-click="setLimit(4)" ng-disabled="(limit===4)||(items.length<=4)">
Show few
</button>
<button ng-click="setLimit(0)" ng-disabled="items.length<=limit">
Show all
</button>
// CONTROLLER
$scope.items = [...];
$scope.limit = 4;
$scope.setLimit = function (lim) {
$scope.limit = (lim <= 0) ? $scope.items.length : lim;
};
See, also, this short demo.
Upvotes: 1
Reputation: 2882
ngClass
is your best bet:
<ul ng-class="{'my-hiding-class': data_shows.length > 4}">
...
This just says add the class 'my-hiding-class' to the ul when your collection size is greater than 4. Documentation here
EDIT:
For the button you'd need to do something like this:
<button ng-click="toggleList()"></button>
Then in your directive:
scope.toggleList = function() {
scope.showList = !scope.showList;
};
Then change your ngClass
declaration slightly:
<ul ng-class="{'my-hiding-class': data_shows.length > 4 && showList}">
Edit 2:
Using the limitTo filter seems nice, but you might want to wrap it with custom functionality if you decide to go the filter route:
angular.module('myApp').filter('limitlessFilter', function($filter){
return function(objects, limit, showAll) {
if(showAll){
return objects;
} else {
return $filter('limitTo')(objects, limit);
}
}
});
In your HTML:
<li ng-repeat="show in data_shows | limitlessFilter:4:showAll">
...
<button ng-bind="showAll && 'Show Less' || 'Show More'" ng-click="toggleShowAll()"></button>
In your controller/directive
scope.toggleShowAll = function() {
scope.showAll = !scope.showAll;
};
On a side note, if you want to limit the number of renders your li go through, be sure to use track by
on your ng-repeat. Documentation here
Upvotes: 4
Reputation: 46
This should do the trick
<ul>
<li ng-repeat="show in data_shows | limitTo:4">
<span class="program_shows_show_day">{{show[2]*1000 | amDateFormat:'ddd D MMM'}}</span>
<span class="program_shows_show_time">{{show[2]*1000 | amDateFormat:'H:mm'}} - {{show[3]*1000 | amDateFormat:'H:mm'}}</span>
</li>
</ul>
<button ng-hide="data_shows.length < 4">Show more</button>
You could replace the first "4" with a variable in your scope and modify this value when clicking the button.
But yeah, BenCr's answer sounds better in some ways.
Upvotes: 0
Reputation: 6042
Only add 4 items to your data_shows collection in your controller. That way you can test the logic, testing the view would be more tricky.
Upvotes: 0