Ng-repeat: show item on click and hide the rest

I have ng-repeat that displays a list of divs , and when I click on it, it shows an aditionnal div for the clicked item.

Works

 <div ng-repeat="item in items"> <div ng-click="showfull = !showfull"> <div> <h1>{{item.title}}</h1> <p>{{item.content}}</p> </div> </div> <div ng-show="showfull"> <p>{{item.info}}</p> </div> <hr/> </div> 

My objects are loaded from json containing a list of elements, and each element has a showfull default showfull set to false in this json. This works, but now I want to hide all other items in the list when I click an item. I tried something like this:

This does not work

 <div ng-repeat="item in items"> <div ng-click="expand(item)"> <div> <h1>{{item.title}}</h1> <p>{{item.content}}</p> </div> </div> <div ng-show="showfull"> <p>{{item.info}}</p> </div> <hr/> </div> 

and in the controller I added a function:

 $scope.expand = function(e) { e.showfull = !e.showfull; //TODO: put here a foreach logic to hide all other items } 

But even without foreach logic, this does not work, the element does not show an additional div when pressed. I have two questions:

  • I suppose this is due to the fact that the item "passed in as a copy" in the expand function or some kind of area isolation problem, but can you explain to me why? solvable

  • How can I hide all additional divs of other elements when I click on an element and show additional content for that element? Do I need to make a directive? NOT SOLVED

thanks

+5
source share
3 answers

I think you're on the right track. You need to set showfull to the element, and then use ng-show or ng-if to hide it, or, as Gavin said, use the class.

In ng-click you can call your expand function, where you pass the element, switch it and set all the others to hidden ones.

Template:

 <div ng-repeat="item in items> <div ng-click="expand(item)"> <div> <h1>{{item.title}}</h1> <p>{{item.content}}</p> </div> </div> <div ng-show="item.showfull"> <p>{{item.info}}</p> </div> <hr/> </div> 

Controller:

 $scope.expand = function (item) { angular.forEach($scope.items, function (currentItem) { currentItem.showfull = currentItem === item && !currentItem.showfull; }); }; 
+4
source

Your extension method modifies the element, so your ng-show should reference the element:

 <div ng-show="item.showfull"> <p>{{item.info}}</p> </div> 

To hide all your items you need to do something like

 $scope.expand = function(item) { angular.forEach(items, function(i) { if (i === item) { i.showfull = !i.showfull; } else { i.showfull = false; } }); }; 
+2
source

Shouldn't the second div you want to show refer to the element?

 <div ng-repeat="item in items> <div ng-click="expand(item)"> <div> <h1>{{item.title}}</h1> <p>{{item.content}}</p> </div> </div> <!-- Added item to ng-show --> <div ng-show="item.showfull"> <p>{{item.info}}</p> </div> <hr/> </div> 
0
source

Source: https://habr.com/ru/post/1204843/


All Articles