Reputation: 2084
I want my li elements to be hidden and when my state loads I want to display only the first two elements and when I click on a button o show the next two elements and so on.
This is how it should work :
http://jsfiddle.net/zuyvgwx3/2/
In my angular application I display my li elements as following :
<ul id="myList">
<li ng-repeat="offre in offres |orderBy:'-dateCreation'|filter:{etat:'true'}">
<div class="box">
<!-- HTML Code -->
</div>
</li>
</ul>
I have li elements set to display:none;
and a javascript code that shows the first two elements as following :
<script>
size_li = $("#myList li").size();
x=2;
$('#myList li:lt('+x+')').show();
$('#loadMore').click(function () {
x= x+2;
$('#myList li:lt('+x+')').show();
});
</script>
The problem is when my state loads all the li elements are shown and not only the first two elements, as you can see in the fiddle I attached it works but it doesn't work when I use it with ng-repeat.
How can I solve this?
Upvotes: 2
Views: 4606
Reputation: 16609
As you are using Angular, you should try to avoid directly manipulating the DOM in this way where possible. Instead you should take advantage of Angular directives to control how elements are displayed, in this case ng-show
.
You are already storing the list in the $scope.offres
. You just need to keep track of how many items to show and only show it if the $index
available in ng-repeat
is lower than that value:
angular.module('myapp', []).controller('ctrl1', function($scope) {
// set up the list with dummy data
$scope.offres = [];
for (var i = 0; i < 11; i++) {
$scope.offres.push(i + 1);
}
// set initial index
// we will use this variable to control the display - see ng-show="" in HTML
$scope.loadIndex = 2;
// function to increase visible items
$scope.showMore = function() {
// don't increment if at the end of the list
if ($scope.loadIndex < $scope.offres.length) {
$scope.loadIndex += 2;
}
};
// function to decrease visible items
$scope.showLess = function() {
// don't decrement if at the start of the list
if ($scope.loadIndex > 2) {
$scope.loadIndex -= 2;
}
};
});
#loadMore {
color: green;
cursor: pointer;
}
#loadMore:hover {
color: black;
}
#showLess {
color: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp" ng-controller="ctrl1">
<ul id="myList">
<li ng-repeat="offre in offres" ng-show="$index < loadIndex">{{offre}}</li>
</ul>
<div id="loadMore" ng-click="showMore()">Load more</div>
<div id="showLess" ng-click="showLess()">Show less</div>
</div>
As you can see, it is then trivial to implement showing less items, as you are just changing a number in your controller.
Upvotes: 1
Reputation: 456
As said by Rhumborl, you should use ng-show to handle this. When you click on the button, just increment a variable and show items only if variable > index.
<li ng-show="variable > index"></li>
$('#loadMore').click(function () {
$scope.variable += 2;
});
Upvotes: 1
Reputation: 2979
When using AngularJS I personally try to avoid writing custom JQuery code for DOM manipulation. To implement the functionality that you have described, I would have taken following approach.
offersHidden
.shift()
the 2 items from offersHidden
and push()
to offres
offres.push(offersHidden.shift())
That way you let AngularJS take care of UI manipulation and avoid any conflicts.
Upvotes: 1
Reputation: 25797
You can directly use Angular's ng-show
/ng-hide
and view binding to achieve this. You don't need to use jQuery for this. Here is a sample example:
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
$scope.offers = [];
// Generating dummy data
for (var i = 0; i < 100; i++) {
var number = i + 1;
$scope.offers.push({
number: number,
name: 'Offer ' + number
});
}
$scope.showFirstTwo = function() {
var shown = 0;
angular.forEach($scope.offers, function(offer) {
if (!offer.isVisible && shown < 2) {
offer.isVisible = true;
shown++;
}
});
};
// At load, display first two by default
$scope.showFirstTwo();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sa" ng-controller="FooController">
<ul>
<li ng-repeat="offer in offers" ng-show="offer.isVisible">
Offer ID: <strong>{{offer.number}}</strong>
<br>Offer name: <strong>{{offer.name}}</strong>
</li>
</ul>
<a href="" ng-click="showFirstTwo()">Load more</a>
</div>
Upvotes: 1