javascripthtmlangularjsangularjs-ng-repeatangularjs-ng-show

set all ng-if to false on click except clicked item


I have an ng-repeat which has a button that has a function that toggles an ng-show element inside that ng-repeat.

The inside the class movie_option span has an ng-click=toggleInfo($index):

And the div additional_info has an ng-show that shows or hides an element.

    <ul ng-cloak="showResult">
        <li class="search_results" ng-repeat="movie in movies | orderBy: '-release_date'  track by $index">
            <div class="movie_info">
                <div class="movie_options">
                    <div class="slide">
                        <span class="movie_option">
                            <span><i class="fa fa-question-circle" aria-hidden="true" ng-click="toggleInfo($index)"></i></span>
                        </span>
                    </div>
                </div>
            </div>
            <div class="additional_info" ng-show="hiddenDiv[$index]">
                {{movie.overview}}
            </div>
        </li>
    </ul>

When a user clicks on the icon it calls this function:

    $scope.toggleInfo = function (index) {
         $scope.hiddenDiv[index] = !$scope.hiddenDiv[index];
    }

This toggles the ng-show state from the hiddenDiv ng-show. This works fine.

What I wanted to do is put all hiddenDiv states on false except the one that is clicked so only one ng-show would be true.


Solution

  • That's a pure algorithm problem, not related to Angular.

    Instead of having a boolean per item, it would be much simpler to just remember the element (index) that should be displayed:

    <ul ng-cloak="showResult">
        <li class="search_results" ng-repeat="movie in movies | orderBy: '-release_date'  track by $index">
            <div class="movie_info">
                <div class="movie_options">
                    <div class="slide">
                        <span class="movie_option">
                            <span><i class="fa fa-question-circle" aria-hidden="true" ng-click="model.displayedIndex = $index"></i></span>
                        </span>
                    </div>
                </div>
            </div>
            <div class="additional_info" ng-show="$index === model.displayedIndex">
                {{movie.overview}}
            </div>
        </li>
    </ul>
    

    And in your controller $scope.model = {}

    Fiddle: http://jsfiddle.net/6dkLqgfL/